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); |
