diff options
Diffstat (limited to 'openssl.c')
-rw-r--r-- | openssl.c | 204 |
1 files changed, 183 insertions, 21 deletions
@@ -32,6 +32,9 @@ | |||
32 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ | 32 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ |
33 | #include <time.h> /* struct tm time_t strptime(3) */ | 33 | #include <time.h> /* struct tm time_t strptime(3) */ |
34 | 34 | ||
35 | #include <sys/types.h> | ||
36 | #include <sys/stat.h> /* struct stat stat(2) */ | ||
37 | |||
35 | #include <netinet/in.h> /* struct in_addr struct in6_addr */ | 38 | #include <netinet/in.h> /* struct in_addr struct in6_addr */ |
36 | #include <arpa/inet.h> /* AF_INET6 AF_INET inet_pton(3) */ | 39 | #include <arpa/inet.h> /* AF_INET6 AF_INET inet_pton(3) */ |
37 | 40 | ||
@@ -42,6 +45,7 @@ | |||
42 | #include <openssl/x509v3.h> | 45 | #include <openssl/x509v3.h> |
43 | #include <openssl/evp.h> | 46 | #include <openssl/evp.h> |
44 | #include <openssl/pem.h> | 47 | #include <openssl/pem.h> |
48 | #include <openssl/ssl.h> | ||
45 | 49 | ||
46 | #include <lua.h> | 50 | #include <lua.h> |
47 | #include <lualib.h> | 51 | #include <lualib.h> |
@@ -58,6 +62,7 @@ | |||
58 | #define X509_CHAIN_CLASS "OpenSSL X.509 Chain" | 62 | #define X509_CHAIN_CLASS "OpenSSL X.509 Chain" |
59 | #define X509_STORE_CLASS "OpenSSL X.509 Store" | 63 | #define X509_STORE_CLASS "OpenSSL X.509 Store" |
60 | #define X509_STCTX_CLASS "OpenSSL X.509 Store Context" | 64 | #define X509_STCTX_CLASS "OpenSSL X.509 Store Context" |
65 | #define SSL_CTX_CLASS "OpenSSL SSL Context" | ||
61 | 66 | ||
62 | 67 | ||
63 | #define countof(a) (sizeof (a) / sizeof *(a)) | 68 | #define countof(a) (sizeof (a) / sizeof *(a)) |
@@ -2708,15 +2713,36 @@ static int xs_interpose(lua_State *L) { | |||
2708 | 2713 | ||
2709 | static int xs_add(lua_State *L) { | 2714 | static int xs_add(lua_State *L) { |
2710 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); | 2715 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); |
2711 | X509 *crt = checksimple(L, 2, X509_CERT_CLASS); | 2716 | int i, top = lua_gettop(L); |
2712 | X509 *dup; | ||
2713 | 2717 | ||
2714 | if (!(dup = X509_dup(crt))) | 2718 | for (i = 2; i <= top; i++) { |
2715 | return throwssl(L, "x509.store:add"); | 2719 | if (lua_isuserdata(L, i)) { |
2720 | X509 *crt = checksimple(L, i, X509_CERT_CLASS); | ||
2721 | X509 *dup; | ||
2716 | 2722 | ||
2717 | if (!X509_STORE_add_cert(store, dup)) { | 2723 | if (!(dup = X509_dup(crt))) |
2718 | X509_free(dup); | 2724 | return throwssl(L, "x509.store:add"); |
2719 | return throwssl(L, "x509.store:add"); | 2725 | |
2726 | if (!X509_STORE_add_cert(store, dup)) { | ||
2727 | X509_free(dup); | ||
2728 | return throwssl(L, "x509.store:add"); | ||
2729 | } | ||
2730 | } else { | ||
2731 | const char *path = luaL_checkstring(L, i); | ||
2732 | struct stat st; | ||
2733 | int ok; | ||
2734 | |||
2735 | if (0 != stat(path, &st)) | ||
2736 | return luaL_error(L, "%s: %s", path, strerror(errno)); | ||
2737 | |||
2738 | if (S_ISDIR(st.st_mode)) | ||
2739 | ok = X509_STORE_load_locations(store, NULL, path); | ||
2740 | else | ||
2741 | ok = X509_STORE_load_locations(store, path, NULL); | ||
2742 | |||
2743 | if (!ok) | ||
2744 | return throwssl(L, "x509.store:add"); | ||
2745 | } | ||
2720 | } | 2746 | } |
2721 | 2747 | ||
2722 | lua_pushboolean(L, 1); | 2748 | lua_pushboolean(L, 1); |
@@ -2835,8 +2861,8 @@ int luaopen__openssl_x509_store(lua_State *L) { | |||
2835 | * held externally for the life of the X509_STORE_CTX object. | 2861 | * held externally for the life of the X509_STORE_CTX object. |
2836 | * | 2862 | * |
2837 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 2863 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
2838 | 2864 | #if 0 | |
2839 | static int sx_new(lua_State *L) { | 2865 | static int stx_new(lua_State *L) { |
2840 | X509_STORE_CTX **ud = prepsimple(L, X509_STCTX_CLASS); | 2866 | X509_STORE_CTX **ud = prepsimple(L, X509_STCTX_CLASS); |
2841 | STACK_OF(X509) *chain; | 2867 | STACK_OF(X509) *chain; |
2842 | 2868 | ||
@@ -2844,36 +2870,159 @@ static int sx_new(lua_State *L) { | |||
2844 | return throwssl(L, "x509.store.context"); | 2870 | return throwssl(L, "x509.store.context"); |
2845 | 2871 | ||
2846 | return 1; | 2872 | return 1; |
2847 | } /* sx_new() */ | 2873 | } /* stx_new() */ |
2848 | 2874 | ||
2849 | 2875 | ||
2850 | static int sx_interpose(lua_State *L) { | 2876 | static int stx_interpose(lua_State *L) { |
2851 | return interpose(L, X509_STCTX_CLASS); | 2877 | return interpose(L, X509_STCTX_CLASS); |
2852 | } /* sx_interpose() */ | 2878 | } /* stx_interpose() */ |
2853 | 2879 | ||
2854 | 2880 | ||
2855 | static int sx_add(lua_State *L) { | 2881 | static int stx_add(lua_State *L) { |
2856 | X509_STORE_CTX *ctx = checksimple(L, 1, X509_STCTX_CLASS); | 2882 | X509_STORE_CTX *ctx = checksimple(L, 1, X509_STCTX_CLASS); |
2857 | 2883 | ||
2858 | |||
2859 | |||
2860 | return 0; | 2884 | return 0; |
2861 | } /* sx_add() */ | 2885 | } /* stx_add() */ |
2862 | 2886 | ||
2863 | 2887 | ||
2864 | static int sx__gc(lua_State *L) { | 2888 | static int stx__gc(lua_State *L) { |
2865 | X509_STORE **ud = luaL_checkudata(L, 1, X509_STORE_CLASS); | 2889 | X509_STORE **ud = luaL_checkudata(L, 1, X509_STORE_CLASS); |
2866 | 2890 | ||
2867 | X509_STORE_free(*ud); | 2891 | X509_STORE_free(*ud); |
2868 | *ud = NULL; | 2892 | *ud = NULL; |
2869 | 2893 | ||
2870 | return 0; | 2894 | return 0; |
2895 | } /* stx__gc() */ | ||
2896 | |||
2897 | |||
2898 | static const luaL_Reg stx_methods[] = { | ||
2899 | { "add", &stx_add }, | ||
2900 | { NULL, NULL }, | ||
2901 | }; | ||
2902 | |||
2903 | static const luaL_Reg stx_metatable[] = { | ||
2904 | { "__gc", &stx__gc }, | ||
2905 | { NULL, NULL }, | ||
2906 | }; | ||
2907 | |||
2908 | static const luaL_Reg stx_globals[] = { | ||
2909 | { "new", &stx_new }, | ||
2910 | { "interpose", &stx_interpose }, | ||
2911 | { NULL, NULL }, | ||
2912 | }; | ||
2913 | |||
2914 | int luaopen__openssl_x509_store_context(lua_State *L) { | ||
2915 | initall(L); | ||
2916 | |||
2917 | luaL_newlib(L, stx_globals); | ||
2918 | |||
2919 | return 1; | ||
2920 | } /* luaopen__openssl_x509_store_context() */ | ||
2921 | #endif | ||
2922 | |||
2923 | |||
2924 | /* | ||
2925 | * SSL_CTX - openssl.ssl.context | ||
2926 | * | ||
2927 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
2928 | |||
2929 | static int sx_new(lua_State *L) { | ||
2930 | static const char *opts[] = { | ||
2931 | "SSLv2", "SSLv3", "SSLv23", "SSL", "TLSv1", "TLS", NULL | ||
2932 | }; | ||
2933 | SSL_CTX **ud = prepsimple(L, SSL_CTX_CLASS); | ||
2934 | SSL_METHOD *(*method)() = &TLSv1_client_method; | ||
2935 | _Bool srv; | ||
2936 | |||
2937 | lua_settop(L, 2); | ||
2938 | srv = lua_toboolean(L, 2); | ||
2939 | |||
2940 | switch (checkoption(L, 1, "TLS", opts)) { | ||
2941 | case 0: /* SSLv2 */ | ||
2942 | method = (srv)? &SSLv2_server_method : &SSLv2_client_method; | ||
2943 | break; | ||
2944 | case 1: /* SSLv3 */ | ||
2945 | method = (srv)? &SSLv3_server_method : &SSLv3_client_method; | ||
2946 | break; | ||
2947 | case 2: /* SSLv23 */ | ||
2948 | /* FALL THROUGH */ | ||
2949 | case 3: /* SSL */ | ||
2950 | method = (srv)? &SSLv23_server_method : &SSLv23_client_method; | ||
2951 | break; | ||
2952 | case 4: /* TLSv1 */ | ||
2953 | /* FALL THROUGH */ | ||
2954 | case 5: /* TLS */ | ||
2955 | method = (srv)? &TLSv1_server_method : &TLSv1_client_method; | ||
2956 | break; | ||
2957 | } | ||
2958 | |||
2959 | if (!(*ud = SSL_CTX_new(method()))) | ||
2960 | return throwssl(L, "ssl.context.new"); | ||
2961 | |||
2962 | return 1; | ||
2963 | } /* sx_new() */ | ||
2964 | |||
2965 | |||
2966 | static int sx_interpose(lua_State *L) { | ||
2967 | return interpose(L, SSL_CTX_CLASS); | ||
2968 | } /* sx_interpose() */ | ||
2969 | |||
2970 | |||
2971 | static int sx_setStore(lua_State *L) { | ||
2972 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
2973 | X509_STORE *store = checksimple(L, 2, X509_STORE_CLASS); | ||
2974 | |||
2975 | SSL_CTX_set_cert_store(ctx, store); | ||
2976 | CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); | ||
2977 | |||
2978 | lua_pushboolean(L, 1); | ||
2979 | |||
2980 | return 1; | ||
2981 | } /* sx_setStore() */ | ||
2982 | |||
2983 | |||
2984 | static int sx_setVerify(lua_State *L) { | ||
2985 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
2986 | int mode = luaL_optint(L, 2, -1); | ||
2987 | int depth = luaL_optint(L, 3, -1); | ||
2988 | |||
2989 | if (mode != -1) | ||
2990 | SSL_CTX_set_verify(ctx, mode, 0); | ||
2991 | |||
2992 | if (depth != -1) | ||
2993 | SSL_CTX_set_verify_depth(ctx, depth); | ||
2994 | |||
2995 | lua_pushboolean(L, 1); | ||
2996 | |||
2997 | return 1; | ||
2998 | } /* sx_setVerify() */ | ||
2999 | |||
3000 | |||
3001 | static int sx_getVerify(lua_State *L) { | ||
3002 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3003 | |||
3004 | lua_pushinteger(L, SSL_CTX_get_verify_mode(ctx)); | ||
3005 | lua_pushinteger(L, SSL_CTX_get_verify_depth(ctx)); | ||
3006 | |||
3007 | return 2; | ||
3008 | } /* sx_getVerify() */ | ||
3009 | |||
3010 | |||
3011 | static int sx__gc(lua_State *L) { | ||
3012 | SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS); | ||
3013 | |||
3014 | SSL_CTX_free(*ud); | ||
3015 | *ud = NULL; | ||
3016 | |||
3017 | return 0; | ||
2871 | } /* sx__gc() */ | 3018 | } /* sx__gc() */ |
2872 | 3019 | ||
2873 | 3020 | ||
2874 | static const luaL_Reg sx_methods[] = { | 3021 | static const luaL_Reg sx_methods[] = { |
2875 | { "add", &sx_add }, | 3022 | { "setStore", &sx_setStore }, |
2876 | { NULL, NULL }, | 3023 | { "setVerify", &sx_setVerify }, |
3024 | { "getVerify", &sx_getVerify }, | ||
3025 | { NULL, NULL }, | ||
2877 | }; | 3026 | }; |
2878 | 3027 | ||
2879 | static const luaL_Reg sx_metatable[] = { | 3028 | static const luaL_Reg sx_metatable[] = { |
@@ -2887,13 +3036,25 @@ static const luaL_Reg sx_globals[] = { | |||
2887 | { NULL, NULL }, | 3036 | { NULL, NULL }, |
2888 | }; | 3037 | }; |
2889 | 3038 | ||
2890 | int luaopen__openssl_x509_store_context(lua_State *L) { | 3039 | int luaopen__openssl_ssl_context(lua_State *L) { |
2891 | initall(L); | 3040 | initall(L); |
2892 | 3041 | ||
2893 | luaL_newlib(L, sx_globals); | 3042 | luaL_newlib(L, sx_globals); |
2894 | 3043 | ||
3044 | lua_pushinteger(L, SSL_VERIFY_NONE); | ||
3045 | lua_setfield(L, -2, "VERIFY_NONE"); | ||
3046 | |||
3047 | lua_pushinteger(L, SSL_VERIFY_PEER); | ||
3048 | lua_setfield(L, -2, "VERIFY_PEER"); | ||
3049 | |||
3050 | lua_pushinteger(L, SSL_VERIFY_FAIL_IF_NO_PEER_CERT); | ||
3051 | lua_setfield(L, -2, "VERIFY_FAIL_IF_NO_PEER_CERT"); | ||
3052 | |||
3053 | lua_pushinteger(L, SSL_VERIFY_CLIENT_ONCE); | ||
3054 | lua_setfield(L, -2, "VERIFY_CLIENT_ONCE"); | ||
3055 | |||
2895 | return 1; | 3056 | return 1; |
2896 | } /* luaopen__openssl_x509_store_context() */ | 3057 | } /* luaopen__openssl_ssl_context() */ |
2897 | 3058 | ||
2898 | 3059 | ||
2899 | 3060 | ||
@@ -2909,6 +3070,7 @@ static void initall(lua_State *L) { | |||
2909 | addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable); | 3070 | addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable); |
2910 | addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable); | 3071 | addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable); |
2911 | addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable); | 3072 | addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable); |
3073 | addclass(L, SSL_CTX_CLASS, sx_methods, sx_metatable); | ||
2912 | } /* initall() */ | 3074 | } /* initall() */ |
2913 | 3075 | ||
2914 | 3076 | ||