diff options
author | William Ahern <william@25thandClement.com> | 2016-01-07 00:40:54 +0800 |
---|---|---|
committer | William Ahern <william@25thandClement.com> | 2016-01-07 00:40:54 +0800 |
commit | 3c5d110bec0801bd7d25200e68fd28c30ef8dc6a (patch) | |
tree | e8b5e18e400e346042afca9ededc5cb3bbcf3157 | |
parent | a4bb486b51bf6dd74d942ce112703b746bb8173a (diff) | |
download | luaossl-3c5d110bec0801bd7d25200e68fd28c30ef8dc6a.tar.gz luaossl-3c5d110bec0801bd7d25200e68fd28c30ef8dc6a.tar.bz2 luaossl-3c5d110bec0801bd7d25200e68fd28c30ef8dc6a.zip |
preliminary support for pkey:setParameters
-rw-r--r-- | src/openssl.c | 501 |
1 files changed, 470 insertions, 31 deletions
diff --git a/src/openssl.c b/src/openssl.c index 71aaed4..ed1fecb 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -148,6 +148,7 @@ | |||
148 | 148 | ||
149 | #define BIGNUM_CLASS "BIGNUM*" | 149 | #define BIGNUM_CLASS "BIGNUM*" |
150 | #define PKEY_CLASS "EVP_PKEY*" | 150 | #define PKEY_CLASS "EVP_PKEY*" |
151 | #define EC_GROUP_CLASS "EVP_GROUP*" | ||
151 | #define X509_NAME_CLASS "X509_NAME*" | 152 | #define X509_NAME_CLASS "X509_NAME*" |
152 | #define X509_GENS_CLASS "GENERAL_NAMES*" | 153 | #define X509_GENS_CLASS "GENERAL_NAMES*" |
153 | #define X509_EXT_CLASS "X509_EXTENSION*" | 154 | #define X509_EXT_CLASS "X509_EXTENSION*" |
@@ -336,10 +337,11 @@ static int checkoption(lua_State *L, int index, const char *def, const char *con | |||
336 | #define X509_ANY 0x01 | 337 | #define X509_ANY 0x01 |
337 | #define X509_PEM 0x02 | 338 | #define X509_PEM 0x02 |
338 | #define X509_DER 0x04 | 339 | #define X509_DER 0x04 |
340 | #define X509_TXT 0x08 /* "pretty" */ | ||
339 | #define X509_ALL (X509_PEM|X509_DER) | 341 | #define X509_ALL (X509_PEM|X509_DER) |
340 | 342 | ||
341 | static int optencoding(lua_State *L, int index, const char *def, int allow) { | 343 | static int optencoding(lua_State *L, int index, const char *def, int allow) { |
342 | static const char *const opts[] = { "*", "pem", "der", NULL }; | 344 | static const char *const opts[] = { "*", "pem", "der", "pretty", NULL }; |
343 | int type = 0; | 345 | int type = 0; |
344 | 346 | ||
345 | switch (checkoption(L, index, def, opts)) { | 347 | switch (checkoption(L, index, def, opts)) { |
@@ -352,6 +354,9 @@ static int optencoding(lua_State *L, int index, const char *def, int allow) { | |||
352 | case 2: | 354 | case 2: |
353 | type = X509_DER; | 355 | type = X509_DER; |
354 | break; | 356 | break; |
357 | case 3: | ||
358 | type = X509_TXT; | ||
359 | break; | ||
355 | } | 360 | } |
356 | 361 | ||
357 | if (!(type & allow)) | 362 | if (!(type & allow)) |
@@ -608,6 +613,21 @@ static _Bool auxS_txt2obj(ASN1_OBJECT **obj, const char *txt) { | |||
608 | } | 613 | } |
609 | } /* auxS_txt2obj() */ | 614 | } /* auxS_txt2obj() */ |
610 | 615 | ||
616 | static _Bool auxS_txt2nid(int *nid, const char *txt) { | ||
617 | /* try builtins first */ | ||
618 | if ((*nid = OBJ_sn2nid(txt)) != NID_undef | ||
619 | || (*nid = OBJ_ln2nid(txt)) != NID_undef) { | ||
620 | return 1; | ||
621 | } | ||
622 | |||
623 | /* OBJ_txt2nid creates a temporary ASN1_OBJECT; call sparingly */ | ||
624 | if (auxS_isoid(txt) && (*nid = OBJ_txt2nid(txt)) != NID_undef) { | ||
625 | return 1; | ||
626 | } | ||
627 | |||
628 | return 0; | ||
629 | } /* auxS_txt2nid() */ | ||
630 | |||
611 | 631 | ||
612 | /* | 632 | /* |
613 | * Auxiliary Lua API routines | 633 | * Auxiliary Lua API routines |
@@ -1577,6 +1597,11 @@ static BIGNUM *bn_dup(lua_State *L, const BIGNUM *src) { | |||
1577 | } /* bn_dup() */ | 1597 | } /* bn_dup() */ |
1578 | 1598 | ||
1579 | 1599 | ||
1600 | static BIGNUM *bn_dup_nil(lua_State *L, const BIGNUM *src) { | ||
1601 | return (src)? bn_dup(L, src) : (lua_pushnil(L), (BIGNUM *)0); | ||
1602 | } /* bn_dup_nil() */ | ||
1603 | |||
1604 | |||
1580 | #define checkbig_(a, b, c, ...) checkbig((a), (b), (c)) | 1605 | #define checkbig_(a, b, c, ...) checkbig((a), (b), (c)) |
1581 | #define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }, 0) | 1606 | #define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }, 0) |
1582 | 1607 | ||
@@ -1976,7 +2001,7 @@ static int bn__gc(lua_State *L) { | |||
1976 | BIGNUM **ud = luaL_checkudata(L, 1, BIGNUM_CLASS); | 2001 | BIGNUM **ud = luaL_checkudata(L, 1, BIGNUM_CLASS); |
1977 | 2002 | ||
1978 | if (*ud) { | 2003 | if (*ud) { |
1979 | BN_free(*ud); | 2004 | BN_clear_free(*ud); |
1980 | *ud = NULL; | 2005 | *ud = NULL; |
1981 | } | 2006 | } |
1982 | 2007 | ||
@@ -2222,8 +2247,8 @@ static int pk_new(lua_State *L) { | |||
2222 | } | 2247 | } |
2223 | 2248 | ||
2224 | if (loadfield(L, 1, "curve", LUA_TSTRING, &id)) { | 2249 | if (loadfield(L, 1, "curve", LUA_TSTRING, &id)) { |
2225 | curve = OBJ_sn2nid(id); | 2250 | if (!auxS_txt2nid(&curve, id)) |
2226 | luaL_argcheck(L, curve != NID_undef, 1, lua_pushfstring(L, "%s: invalid curve", id)); | 2251 | luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id)); |
2227 | } | 2252 | } |
2228 | 2253 | ||
2229 | creat: | 2254 | creat: |
@@ -2686,8 +2711,14 @@ enum pk_param { | |||
2686 | PK_DH_PUB_KEY, | 2711 | PK_DH_PUB_KEY, |
2687 | PK_DH_PRIV_KEY, | 2712 | PK_DH_PRIV_KEY, |
2688 | 2713 | ||
2689 | #define PK_EC_OPTLIST { "pub_key", "priv_key", NULL } | 2714 | /* |
2690 | #define PK_EC_OPTOFFSET PK_EC_PUB_KEY | 2715 | * NB: group MUST come before pub_key as setting pub_key requires the group |
2716 | * to be defined. :setParameters will do the requested assignments in the | ||
2717 | * order defined by by this array. | ||
2718 | */ | ||
2719 | #define PK_EC_OPTLIST { "group", "pub_key", "priv_key", NULL } | ||
2720 | #define PK_EC_OPTOFFSET PK_EC_GROUP | ||
2721 | PK_EC_GROUP, | ||
2691 | PK_EC_PUB_KEY, | 2722 | PK_EC_PUB_KEY, |
2692 | PK_EC_PRIV_KEY, | 2723 | PK_EC_PRIV_KEY, |
2693 | }; /* enum pk_param */ | 2724 | }; /* enum pk_param */ |
@@ -2712,6 +2743,10 @@ static int pk_checkparam(lua_State *L, int type, int index) { | |||
2712 | } | 2743 | } |
2713 | } /* pk_checkparam() */ | 2744 | } /* pk_checkparam() */ |
2714 | 2745 | ||
2746 | #ifndef OPENSSL_NO_EC | ||
2747 | static EC_GROUP *ecg_dup_nil(lua_State *, const EC_GROUP *); | ||
2748 | #endif | ||
2749 | |||
2715 | static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { | 2750 | static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { |
2716 | union { | 2751 | union { |
2717 | RSA *rsa; | 2752 | RSA *rsa; |
@@ -2725,95 +2760,246 @@ static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { | |||
2725 | switch (which) { | 2760 | switch (which) { |
2726 | case PK_RSA_N: | 2761 | case PK_RSA_N: |
2727 | /* RSA public modulus n */ | 2762 | /* RSA public modulus n */ |
2728 | bn_dup(L, key.rsa->n); | 2763 | bn_dup_nil(L, key.rsa->n); |
2729 | 2764 | ||
2730 | break; | 2765 | break; |
2731 | case PK_RSA_E: | 2766 | case PK_RSA_E: |
2732 | /* RSA public exponent e */ | 2767 | /* RSA public exponent e */ |
2733 | bn_dup(L, key.rsa->e); | 2768 | bn_dup_nil(L, key.rsa->e); |
2734 | 2769 | ||
2735 | break; | 2770 | break; |
2736 | case PK_RSA_D: | 2771 | case PK_RSA_D: |
2737 | /* RSA secret exponent d */ | 2772 | /* RSA secret exponent d */ |
2738 | bn_dup(L, key.rsa->d); | 2773 | bn_dup_nil(L, key.rsa->d); |
2739 | 2774 | ||
2740 | break; | 2775 | break; |
2741 | case PK_RSA_P: | 2776 | case PK_RSA_P: |
2742 | /* RSA secret prime p */ | 2777 | /* RSA secret prime p */ |
2743 | bn_dup(L, key.rsa->p); | 2778 | bn_dup_nil(L, key.rsa->p); |
2744 | 2779 | ||
2745 | break; | 2780 | break; |
2746 | case PK_RSA_Q: | 2781 | case PK_RSA_Q: |
2747 | /* RSA secret prime q with p < q */ | 2782 | /* RSA secret prime q with p < q */ |
2748 | bn_dup(L, key.rsa->q); | 2783 | bn_dup_nil(L, key.rsa->q); |
2749 | 2784 | ||
2750 | break; | 2785 | break; |
2751 | case PK_RSA_DMP1: | 2786 | case PK_RSA_DMP1: |
2752 | /* exponent1 */ | 2787 | /* exponent1 */ |
2753 | bn_dup(L, key.rsa->dmp1); | 2788 | bn_dup_nil(L, key.rsa->dmp1); |
2754 | 2789 | ||
2755 | break; | 2790 | break; |
2756 | case PK_RSA_DMQ1: | 2791 | case PK_RSA_DMQ1: |
2757 | /* exponent2 */ | 2792 | /* exponent2 */ |
2758 | bn_dup(L, key.rsa->dmq1); | 2793 | bn_dup_nil(L, key.rsa->dmq1); |
2759 | 2794 | ||
2760 | break; | 2795 | break; |
2761 | case PK_RSA_IQMP: | 2796 | case PK_RSA_IQMP: |
2762 | /* coefficient */ | 2797 | /* coefficient */ |
2763 | bn_dup(L, key.rsa->iqmp); | 2798 | bn_dup_nil(L, key.rsa->iqmp); |
2764 | 2799 | ||
2765 | break; | 2800 | break; |
2766 | case PK_DSA_P: | 2801 | case PK_DSA_P: |
2767 | bn_dup(L, key.dsa->p); | 2802 | bn_dup_nil(L, key.dsa->p); |
2768 | 2803 | ||
2769 | break; | 2804 | break; |
2770 | case PK_DSA_Q: | 2805 | case PK_DSA_Q: |
2771 | bn_dup(L, key.dsa->q); | 2806 | bn_dup_nil(L, key.dsa->q); |
2772 | 2807 | ||
2773 | break; | 2808 | break; |
2774 | case PK_DSA_G: | 2809 | case PK_DSA_G: |
2775 | bn_dup(L, key.dsa->g); | 2810 | bn_dup_nil(L, key.dsa->g); |
2776 | 2811 | ||
2777 | break; | 2812 | break; |
2778 | case PK_DSA_PUB_KEY: | 2813 | case PK_DSA_PUB_KEY: |
2779 | bn_dup(L, key.dsa->pub_key); | 2814 | bn_dup_nil(L, key.dsa->pub_key); |
2780 | 2815 | ||
2781 | break; | 2816 | break; |
2782 | case PK_DSA_PRIV_KEY: | 2817 | case PK_DSA_PRIV_KEY: |
2783 | bn_dup(L, key.dsa->priv_key); | 2818 | bn_dup_nil(L, key.dsa->priv_key); |
2784 | 2819 | ||
2785 | break; | 2820 | break; |
2786 | case PK_DH_P: | 2821 | case PK_DH_P: |
2787 | bn_dup(L, key.dh->p); | 2822 | bn_dup_nil(L, key.dh->p); |
2788 | 2823 | ||
2789 | break; | 2824 | break; |
2790 | case PK_DH_G: | 2825 | case PK_DH_G: |
2791 | bn_dup(L, key.dh->g); | 2826 | bn_dup_nil(L, key.dh->g); |
2792 | 2827 | ||
2793 | break; | 2828 | break; |
2794 | case PK_DH_PUB_KEY: | 2829 | case PK_DH_PUB_KEY: |
2795 | bn_dup(L, key.dh->pub_key); | 2830 | bn_dup_nil(L, key.dh->pub_key); |
2796 | 2831 | ||
2797 | break; | 2832 | break; |
2798 | case PK_DH_PRIV_KEY: | 2833 | case PK_DH_PRIV_KEY: |
2799 | bn_dup(L, key.dh->priv_key); | 2834 | bn_dup_nil(L, key.dh->priv_key); |
2800 | 2835 | ||
2801 | break; | 2836 | break; |
2802 | #ifndef OPENSSL_NO_EC | 2837 | #ifndef OPENSSL_NO_EC |
2838 | case PK_EC_GROUP: | ||
2839 | ecg_dup_nil(L, EC_KEY_get0_group(key.ec)); | ||
2840 | |||
2841 | break; | ||
2803 | case PK_EC_PUB_KEY: { | 2842 | case PK_EC_PUB_KEY: { |
2804 | const EC_GROUP *group; | 2843 | const EC_GROUP *group; |
2805 | const EC_POINT *public_key; | 2844 | const EC_POINT *pub_key; |
2806 | 2845 | ||
2807 | if (!(group = EC_KEY_get0_group(key.ec)) || !(public_key = EC_KEY_get0_public_key(key.ec))) | 2846 | if ((group = EC_KEY_get0_group(key.ec)) && (pub_key = EC_KEY_get0_public_key(key.ec))) { |
2808 | goto sslerr; | 2847 | bn_dup_nil(L, EC_POINT_point2bn(group, pub_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L))); |
2809 | bn_dup(L, EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L))); | 2848 | } else { |
2849 | lua_pushnil(L); | ||
2850 | } | ||
2810 | 2851 | ||
2811 | break; | 2852 | break; |
2812 | } | 2853 | } |
2813 | case PK_EC_PRIV_KEY: | 2854 | case PK_EC_PRIV_KEY: |
2814 | bn_dup(L, EC_KEY_get0_private_key(key.ec)); | 2855 | bn_dup_nil(L, EC_KEY_get0_private_key(key.ec)); |
2856 | |||
2857 | break; | ||
2858 | #endif | ||
2859 | default: | ||
2860 | luaL_error(L, "%d: invalid EVP_PKEY parameter", which); | ||
2861 | } | ||
2862 | |||
2863 | return; | ||
2864 | } /* pk_pushparam() */ | ||
2865 | |||
2866 | |||
2867 | static _Bool pk_bn_set_nothrow(BIGNUM **dst, BIGNUM *src) { | ||
2868 | BIGNUM *tmp; | ||
2869 | |||
2870 | if (!(tmp = BN_dup(src))) | ||
2871 | return 0; | ||
2872 | |||
2873 | if (*dst) | ||
2874 | BN_clear_free(*dst); | ||
2875 | *dst = tmp; | ||
2876 | |||
2877 | return 1; | ||
2878 | } /* pk_bn_set_nothrow() */ | ||
2879 | |||
2880 | #define pk_bn_set(L, dst, index) do { \ | ||
2881 | BIGNUM *n = checkbig((L), (index)); \ | ||
2882 | if (!pk_bn_set_nothrow((dst), n)) \ | ||
2883 | goto sslerr; \ | ||
2884 | } while (0) | ||
2885 | |||
2886 | static void pk_setparam(lua_State *L, void *_key, enum pk_param which, int index) { | ||
2887 | union { | ||
2888 | RSA *rsa; | ||
2889 | DH *dh; | ||
2890 | DSA *dsa; | ||
2891 | #ifndef OPENSSL_NO_EC | ||
2892 | EC_KEY *ec; | ||
2893 | #endif | ||
2894 | } key = { _key }; | ||
2895 | |||
2896 | switch (which) { | ||
2897 | case PK_RSA_N: | ||
2898 | pk_bn_set(L, &key.rsa->n, index); | ||
2899 | |||
2900 | break; | ||
2901 | case PK_RSA_E: | ||
2902 | pk_bn_set(L, &key.rsa->e, index); | ||
2903 | |||
2904 | break; | ||
2905 | case PK_RSA_D: | ||
2906 | pk_bn_set(L, &key.rsa->d, index); | ||
2907 | |||
2908 | break; | ||
2909 | case PK_RSA_P: | ||
2910 | pk_bn_set(L, &key.rsa->p, index); | ||
2911 | |||
2912 | break; | ||
2913 | case PK_RSA_Q: | ||
2914 | pk_bn_set(L, &key.rsa->q, index); | ||
2815 | 2915 | ||
2816 | break; | 2916 | break; |
2917 | case PK_RSA_DMP1: | ||
2918 | pk_bn_set(L, &key.rsa->dmp1, index); | ||
2919 | |||
2920 | break; | ||
2921 | case PK_RSA_DMQ1: | ||
2922 | pk_bn_set(L, &key.rsa->dmq1, index); | ||
2923 | |||
2924 | break; | ||
2925 | case PK_RSA_IQMP: | ||
2926 | pk_bn_set(L, &key.rsa->iqmp, index); | ||
2927 | |||
2928 | break; | ||
2929 | case PK_DSA_P: | ||
2930 | pk_bn_set(L, &key.dsa->p, index); | ||
2931 | |||
2932 | break; | ||
2933 | case PK_DSA_Q: | ||
2934 | pk_bn_set(L, &key.dsa->q, index); | ||
2935 | |||
2936 | break; | ||
2937 | case PK_DSA_G: | ||
2938 | pk_bn_set(L, &key.dsa->g, index); | ||
2939 | |||
2940 | break; | ||
2941 | case PK_DSA_PUB_KEY: | ||
2942 | pk_bn_set(L, &key.dsa->pub_key, index); | ||
2943 | |||
2944 | break; | ||
2945 | case PK_DSA_PRIV_KEY: | ||
2946 | pk_bn_set(L, &key.dsa->priv_key, index); | ||
2947 | |||
2948 | break; | ||
2949 | case PK_DH_P: | ||
2950 | pk_bn_set(L, &key.dh->p, index); | ||
2951 | |||
2952 | break; | ||
2953 | case PK_DH_G: | ||
2954 | pk_bn_set(L, &key.dh->g, index); | ||
2955 | |||
2956 | break; | ||
2957 | case PK_DH_PUB_KEY: | ||
2958 | pk_bn_set(L, &key.dh->pub_key, index); | ||
2959 | |||
2960 | break; | ||
2961 | case PK_DH_PRIV_KEY: | ||
2962 | pk_bn_set(L, &key.dh->priv_key, index); | ||
2963 | |||
2964 | break; | ||
2965 | #ifndef OPENSSL_NO_EC | ||
2966 | case PK_EC_GROUP: { | ||
2967 | const EC_GROUP *group = checksimple(L, index, EC_GROUP_CLASS); | ||
2968 | |||
2969 | if (!EC_KEY_set_group(key.ec, group)) | ||
2970 | goto sslerr; | ||
2971 | |||
2972 | break; | ||
2973 | } | ||
2974 | case PK_EC_PUB_KEY: { | ||
2975 | const BIGNUM *n = checkbig(L, index); | ||
2976 | const EC_GROUP *group; | ||
2977 | EC_POINT *pub_key; | ||
2978 | _Bool okay; | ||
2979 | |||
2980 | if (!(group = EC_KEY_get0_group(key.ec))) | ||
2981 | luaL_error(L, "unable to set EC pub_key (no group defined)"); | ||
2982 | |||
2983 | if (!(pub_key = EC_POINT_bn2point(group, n, NULL, getctx(L)))) | ||
2984 | goto sslerr; | ||
2985 | |||
2986 | /* NB: copies key, doesn't share or take ownership */ | ||
2987 | okay = EC_KEY_set_public_key(key.ec, pub_key); | ||
2988 | EC_POINT_free(pub_key); | ||
2989 | if (!okay) | ||
2990 | goto sslerr; | ||
2991 | |||
2992 | break; | ||
2993 | } | ||
2994 | case PK_EC_PRIV_KEY: { | ||
2995 | const BIGNUM *n = checkbig(L, index); | ||
2996 | |||
2997 | /* NB: copies key, doesn't share or take ownership */ | ||
2998 | if (!EC_KEY_set_private_key(key.ec, n)) | ||
2999 | goto sslerr; | ||
3000 | |||
3001 | break; | ||
3002 | } | ||
2817 | #endif | 3003 | #endif |
2818 | default: | 3004 | default: |
2819 | luaL_error(L, "%d: invalid EVP_PKEY parameter", which); | 3005 | luaL_error(L, "%d: invalid EVP_PKEY parameter", which); |
@@ -2821,10 +3007,10 @@ static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { | |||
2821 | 3007 | ||
2822 | return; | 3008 | return; |
2823 | sslerr: | 3009 | sslerr: |
2824 | auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); | 3010 | auxL_error(L, auxL_EOPENSSL, "pkey:setParameters"); |
2825 | 3011 | ||
2826 | return; | 3012 | return; |
2827 | } /* pk_pushparam() */ | 3013 | } /* pk_setparam() */ |
2828 | 3014 | ||
2829 | 3015 | ||
2830 | static int pk_getParameters(lua_State *L) { | 3016 | static int pk_getParameters(lua_State *L) { |
@@ -2862,7 +3048,7 @@ static int pk_getParameters(lua_State *L) { | |||
2862 | 3048 | ||
2863 | break; | 3049 | break; |
2864 | default: | 3050 | default: |
2865 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_base_id(key)); | 3051 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", type); |
2866 | } | 3052 | } |
2867 | 3053 | ||
2868 | /* | 3054 | /* |
@@ -2908,6 +3094,56 @@ sslerr: | |||
2908 | } /* pk_getParameters() */ | 3094 | } /* pk_getParameters() */ |
2909 | 3095 | ||
2910 | 3096 | ||
3097 | static int pk_setParameters(lua_State *L) { | ||
3098 | EVP_PKEY *_key = checksimple(L, 1, PKEY_CLASS); | ||
3099 | int type = EVP_PKEY_base_id(_key); | ||
3100 | void *key; | ||
3101 | const char *const *optlist; | ||
3102 | int optindex, optoffset; | ||
3103 | |||
3104 | luaL_checktype(L, 2, LUA_TTABLE); | ||
3105 | |||
3106 | if (!(key = EVP_PKEY_get0(_key))) | ||
3107 | goto sslerr; | ||
3108 | |||
3109 | switch (type) { | ||
3110 | case EVP_PKEY_RSA: | ||
3111 | optlist = pk_rsa_optlist; | ||
3112 | optoffset = PK_RSA_OPTOFFSET; | ||
3113 | |||
3114 | break; | ||
3115 | case EVP_PKEY_DSA: | ||
3116 | optlist = pk_dsa_optlist; | ||
3117 | optoffset = PK_DSA_OPTOFFSET; | ||
3118 | |||
3119 | break; | ||
3120 | case EVP_PKEY_DH: | ||
3121 | optlist = pk_dh_optlist; | ||
3122 | optoffset = PK_DH_OPTOFFSET; | ||
3123 | |||
3124 | break; | ||
3125 | case EVP_PKEY_EC: | ||
3126 | optlist = pk_ec_optlist; | ||
3127 | optoffset = PK_EC_OPTOFFSET; | ||
3128 | |||
3129 | break; | ||
3130 | default: | ||
3131 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", type); | ||
3132 | } | ||
3133 | |||
3134 | for (optindex = 0; optlist[optindex]; optindex++) { | ||
3135 | if (getfield(L, 2, optlist[optindex])) { | ||
3136 | pk_setparam(L, key, optindex + optoffset, -1); | ||
3137 | lua_pop(L, 1); | ||
3138 | } | ||
3139 | } | ||
3140 | |||
3141 | return 0; | ||
3142 | sslerr: | ||
3143 | return auxL_error(L, auxL_EOPENSSL, "pkey:setParameters"); | ||
3144 | } /* pk_setParameters() */ | ||
3145 | |||
3146 | |||
2911 | static int pk__tostring(lua_State *L) { | 3147 | static int pk__tostring(lua_State *L) { |
2912 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | 3148 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); |
2913 | int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); | 3149 | int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); |
@@ -2954,6 +3190,7 @@ static const luaL_Reg pk_methods[] = { | |||
2954 | { "verify", &pk_verify }, | 3190 | { "verify", &pk_verify }, |
2955 | { "toPEM", &pk_toPEM }, | 3191 | { "toPEM", &pk_toPEM }, |
2956 | { "getParameters", &pk_getParameters }, | 3192 | { "getParameters", &pk_getParameters }, |
3193 | { "setParameters", &pk_setParameters }, | ||
2957 | { NULL, NULL }, | 3194 | { NULL, NULL }, |
2958 | }; | 3195 | }; |
2959 | 3196 | ||
@@ -2988,6 +3225,205 @@ int luaopen__openssl_pubkey(lua_State *L) { | |||
2988 | 3225 | ||
2989 | 3226 | ||
2990 | /* | 3227 | /* |
3228 | * EC_GROUP - openssl.ec.group | ||
3229 | * | ||
3230 | * NOTE: Ensure copy-by-value semantics when passing EC_GROUP objects as it | ||
3231 | * doesn't support reference counting. The only persistent reference should | ||
3232 | * be the Lua userdata value. | ||
3233 | * | ||
3234 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3235 | |||
3236 | #ifndef OPENSSL_NO_EC | ||
3237 | |||
3238 | static EC_GROUP *ecg_dup(lua_State *L, const EC_GROUP *src) { | ||
3239 | EC_GROUP **ud = prepsimple(L, EC_GROUP_CLASS); | ||
3240 | |||
3241 | if (!(*ud = EC_GROUP_dup(src))) | ||
3242 | auxL_error(L, auxL_EOPENSSL, "group"); | ||
3243 | |||
3244 | return *ud; | ||
3245 | } /* ecg_dup() */ | ||
3246 | |||
3247 | static EC_GROUP *ecg_dup_nil(lua_State *L, const EC_GROUP *src) { | ||
3248 | return (src)? ecg_dup(L, src) : (lua_pushnil(L), (EC_GROUP *)0); | ||
3249 | } /* ecg_dup_nil() */ | ||
3250 | |||
3251 | static EC_GROUP *ecg_new_by_nid(int nid) { | ||
3252 | EC_GROUP *group; | ||
3253 | |||
3254 | if (!(group = EC_GROUP_new_by_curve_name(nid))) | ||
3255 | return NULL; | ||
3256 | |||
3257 | /* flag as named for benefit of __tostring */ | ||
3258 | EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); | ||
3259 | |||
3260 | /* compressed points may be patented */ | ||
3261 | EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED); | ||
3262 | |||
3263 | return group; | ||
3264 | } /* ecg_new_by_nid() */ | ||
3265 | |||
3266 | static EC_GROUP *ecg_push_by_nid(lua_State *L, int nid) { | ||
3267 | EC_GROUP **group = prepsimple(L, EC_GROUP_CLASS); | ||
3268 | |||
3269 | if (!(*group = EC_GROUP_new_by_curve_name(nid))) | ||
3270 | goto oops; | ||
3271 | |||
3272 | EC_GROUP_set_asn1_flag(*group, OPENSSL_EC_NAMED_CURVE); | ||
3273 | |||
3274 | /* compressed points may be patented */ | ||
3275 | EC_GROUP_set_point_conversion_form(*group, POINT_CONVERSION_UNCOMPRESSED); | ||
3276 | |||
3277 | return *group; | ||
3278 | oops: | ||
3279 | lua_pop(L, 1); | ||
3280 | |||
3281 | return NULL; | ||
3282 | } /* ecg_push_by_nid() */ | ||
3283 | |||
3284 | static int ecg_new(lua_State *L) { | ||
3285 | switch (lua_type(L, 1)) { | ||
3286 | case LUA_TSTRING: { | ||
3287 | const char *data; | ||
3288 | size_t datalen; | ||
3289 | int nid, type, goterr; | ||
3290 | BIO *bio; | ||
3291 | EC_GROUP **group; | ||
3292 | |||
3293 | data = luaL_checklstring(L, 1, &datalen); | ||
3294 | |||
3295 | if (auxS_txt2nid(&nid, data)) { | ||
3296 | if (!ecg_push_by_nid(L, nid)) | ||
3297 | goto sslerr; | ||
3298 | } else { | ||
3299 | type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); | ||
3300 | group = prepsimple(L, EC_GROUP_CLASS); | ||
3301 | |||
3302 | luaL_argcheck(L, datalen < INT_MAX, 1, "string too long"); | ||
3303 | if (!(bio = BIO_new_mem_buf((void *)data, datalen))) | ||
3304 | return auxL_error(L, auxL_EOPENSSL, "group.new"); | ||
3305 | |||
3306 | goterr = 0; | ||
3307 | |||
3308 | if (type == X509_PEM || type == X509_ANY) { | ||
3309 | goterr |= !(*group = PEM_read_bio_ECPKParameters(bio, NULL, 0, "")); | ||
3310 | } | ||
3311 | |||
3312 | if (!*group && (type == X509_DER || type == X509_ANY)) { | ||
3313 | BIO_reset(bio); | ||
3314 | goterr |= !(*group = d2i_ECPKParameters_bio(bio, NULL)); | ||
3315 | } | ||
3316 | |||
3317 | BIO_free(bio); | ||
3318 | |||
3319 | if (!*group) | ||
3320 | return auxL_error(L, auxL_EOPENSSL, "group.new"); | ||
3321 | if (goterr) | ||
3322 | ERR_clear_error(); | ||
3323 | } | ||
3324 | |||
3325 | return 1; | ||
3326 | } | ||
3327 | case LUA_TNUMBER: { | ||
3328 | int nid = luaL_checkint(L, 2); | ||
3329 | |||
3330 | if (!ecg_push_by_nid(L, nid)) | ||
3331 | goto sslerr; | ||
3332 | |||
3333 | return 1; | ||
3334 | } | ||
3335 | default: | ||
3336 | return luaL_error(L, "%s: unknown group initializer", lua_typename(L, lua_type(L, 1))); | ||
3337 | } /* switch() */ | ||
3338 | |||
3339 | return 0; | ||
3340 | sslerr: | ||
3341 | return auxL_error(L, auxL_EOPENSSL, "group.new"); | ||
3342 | } /* ecg_new() */ | ||
3343 | |||
3344 | static int ecg_interpose(lua_State *L) { | ||
3345 | return interpose(L, EC_GROUP_CLASS); | ||
3346 | } /* ecg_interpose() */ | ||
3347 | |||
3348 | static int ecg_tostring(lua_State *L) { | ||
3349 | EC_GROUP *group = checksimple(L, 1, EC_GROUP_CLASS); | ||
3350 | int how = optencoding(L, 2, "pem", X509_PEM|X509_DER|X509_TXT); | ||
3351 | BIO *bio = getbio(L); | ||
3352 | char *bytes; | ||
3353 | int len, indent; | ||
3354 | |||
3355 | switch (how) { | ||
3356 | case X509_PEM: | ||
3357 | if (!PEM_write_bio_ECPKParameters(bio, group)) | ||
3358 | goto sslerr; | ||
3359 | break; | ||
3360 | case X509_DER: | ||
3361 | if (!i2d_ECPKParameters_bio(bio, group)) | ||
3362 | goto sslerr; | ||
3363 | break; | ||
3364 | case X509_TXT: | ||
3365 | indent = auxL_optinteger(L, 3, 0, 0, INT_MAX); | ||
3366 | if (!ECPKParameters_print(bio, group, indent)) | ||
3367 | goto sslerr; | ||
3368 | break; | ||
3369 | } | ||
3370 | |||
3371 | len = BIO_get_mem_data(bio, &bytes); | ||
3372 | lua_pushlstring(L, bytes, len); | ||
3373 | |||
3374 | return 1; | ||
3375 | sslerr: | ||
3376 | return auxL_error(L, auxL_EOPENSSL, "group:__tostring"); | ||
3377 | } /* ecg_tostring() */ | ||
3378 | |||
3379 | static int ecg__tostring(lua_State *L) { | ||
3380 | return ecg_tostring(L); | ||
3381 | } /* ecg__tostring() */ | ||
3382 | |||
3383 | static int ecg__gc(lua_State *L) { | ||
3384 | EC_GROUP **ud = luaL_checkudata(L, 1, EC_GROUP_CLASS); | ||
3385 | |||
3386 | if (*ud) { | ||
3387 | EC_GROUP_clear_free(*ud); | ||
3388 | *ud = NULL; | ||
3389 | } | ||
3390 | |||
3391 | return 0; | ||
3392 | } /* ecg__gc() */ | ||
3393 | |||
3394 | static const luaL_Reg ecg_methods[] = { | ||
3395 | { "tostring", &ecg_tostring }, | ||
3396 | { NULL, NULL }, | ||
3397 | }; | ||
3398 | |||
3399 | static const luaL_Reg ecg_metatable[] = { | ||
3400 | { "__tostring", &ecg__tostring }, | ||
3401 | { "__gc", &ecg__gc }, | ||
3402 | { NULL, NULL }, | ||
3403 | }; | ||
3404 | |||
3405 | static const luaL_Reg ecg_globals[] = { | ||
3406 | { "new", &ecg_new }, | ||
3407 | { "interpose", &ecg_interpose }, | ||
3408 | { NULL, NULL }, | ||
3409 | }; | ||
3410 | |||
3411 | #endif /* OPENSSL_NO_EC */ | ||
3412 | |||
3413 | int luaopen__openssl_ec_group(lua_State *L) { | ||
3414 | #ifndef OPENSSL_NO_EC | ||
3415 | initall(L); | ||
3416 | |||
3417 | luaL_newlib(L, ecg_globals); | ||
3418 | |||
3419 | return 1; | ||
3420 | #else | ||
3421 | return 0; | ||
3422 | #endif | ||
3423 | } /* luaopen__openssl_ec_group() */ | ||
3424 | |||
3425 | |||
3426 | /* | ||
2991 | * X509_NAME - openssl.x509.name | 3427 | * X509_NAME - openssl.x509.name |
2992 | * | 3428 | * |
2993 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 3429 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
@@ -7575,6 +8011,9 @@ static void initall(lua_State *L) { | |||
7575 | 8011 | ||
7576 | addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); | 8012 | addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); |
7577 | addclass(L, PKEY_CLASS, pk_methods, pk_metatable); | 8013 | addclass(L, PKEY_CLASS, pk_methods, pk_metatable); |
8014 | #ifndef OPENSSL_NO_EC | ||
8015 | addclass(L, EC_GROUP_CLASS, ecg_methods, ecg_metatable); | ||
8016 | #endif | ||
7578 | addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); | 8017 | addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); |
7579 | addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable); | 8018 | addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable); |
7580 | addclass(L, X509_EXT_CLASS, xe_methods, xe_metatable); | 8019 | addclass(L, X509_EXT_CLASS, xe_methods, xe_metatable); |