diff options
author | William Ahern <william@server.local> | 2012-10-08 22:41:26 -0700 |
---|---|---|
committer | William Ahern <william@server.local> | 2012-10-08 22:41:26 -0700 |
commit | 175b7db5f19623158f74f068f1a6d67f59bbc533 (patch) | |
tree | cbfb1da3688ac998f947a593bad8b30895e26198 | |
parent | ee4377fd20153de610f77bc2a355bba4834c1097 (diff) | |
download | luaossl-175b7db5f19623158f74f068f1a6d67f59bbc533.tar.gz luaossl-175b7db5f19623158f74f068f1a6d67f59bbc533.tar.bz2 luaossl-175b7db5f19623158f74f068f1a6d67f59bbc533.zip |
-n
add some key bindings
-rw-r--r-- | openssl.c | 744 |
1 files changed, 723 insertions, 21 deletions
@@ -48,10 +48,12 @@ | |||
48 | #include <lauxlib.h> | 48 | #include <lauxlib.h> |
49 | 49 | ||
50 | 50 | ||
51 | #define BIGNUM_CLASS "OpenSSL BN" | ||
52 | #define PUBKEY_CLASS "OpenSSL PK" | ||
51 | #define X509_NAME_CLASS "OpenSSL X.509 Name" | 53 | #define X509_NAME_CLASS "OpenSSL X.509 Name" |
52 | #define X509_GENS_CLASS "OpenSSL X.509 AltName" | 54 | #define X509_GENS_CLASS "OpenSSL X.509 AltName" |
53 | #define X509_CERT_CLASS "OpenSSL X.509 Cert" | 55 | #define X509_CERT_CLASS "OpenSSL X.509 Cert" |
54 | #define BIGNUM_CLASS "OpenSSL BN" | 56 | #define X509_CSR_CLASS "OpenSSL X.509 Request" |
55 | 57 | ||
56 | 58 | ||
57 | #define countof(a) (sizeof (a) / sizeof *(a)) | 59 | #define countof(a) (sizeof (a) / sizeof *(a)) |
@@ -109,13 +111,32 @@ static void *checksimple(lua_State *L, int index, const char *tname) { | |||
109 | } /* checksimple() */ | 111 | } /* checksimple() */ |
110 | 112 | ||
111 | 113 | ||
114 | static void *testsimple(lua_State *L, int index, const char *tname) { | ||
115 | void **p; | ||
116 | |||
117 | if (tname) { | ||
118 | p = luaL_testudata(L, index, tname); | ||
119 | } else { | ||
120 | luaL_checktype(L, index, LUA_TUSERDATA); | ||
121 | p = lua_touserdata(L, index); | ||
122 | } | ||
123 | |||
124 | return *p; | ||
125 | } /* testsimple() */ | ||
126 | |||
127 | |||
112 | static int throwssl(lua_State *L, const char *fun) { | 128 | static int throwssl(lua_State *L, const char *fun) { |
113 | unsigned long code; | 129 | unsigned long code; |
114 | const char *file; | 130 | const char *path, *file; |
115 | int line; | 131 | int line; |
116 | char txt[256]; | 132 | char txt[256]; |
117 | 133 | ||
118 | code = ERR_get_error_line(&file, &line); | 134 | code = ERR_get_error_line(&path, &line); |
135 | if ((file = strrchr(path, '/'))) | ||
136 | ++file; | ||
137 | else | ||
138 | file = path; | ||
139 | |||
119 | ERR_clear_error(); | 140 | ERR_clear_error(); |
120 | 141 | ||
121 | ERR_error_string_n(code, txt, sizeof txt); | 142 | ERR_error_string_n(code, txt, sizeof txt); |
@@ -167,6 +188,63 @@ static int checkoption(struct lua_State *L, int index, const char *def, const ch | |||
167 | } /* checkoption() */ | 188 | } /* checkoption() */ |
168 | 189 | ||
169 | 190 | ||
191 | static _Bool getfield(lua_State *L, int index, const char *k) { | ||
192 | lua_getfield(L, index, k); | ||
193 | |||
194 | if (lua_isnil(L, -1)) { | ||
195 | lua_pop(L, 1); | ||
196 | |||
197 | return 0; | ||
198 | } else { | ||
199 | return 1; | ||
200 | } | ||
201 | } /* getfield() */ | ||
202 | |||
203 | |||
204 | static _Bool loadfield(lua_State *L, int index, const char *k, int type, void *p) { | ||
205 | if (!getfield(L, index, k)) | ||
206 | return 0; | ||
207 | |||
208 | switch (type) { | ||
209 | case LUA_TSTRING: | ||
210 | *(const char **)p = luaL_checkstring(L, -1); | ||
211 | break; | ||
212 | case LUA_TNUMBER: | ||
213 | *(lua_Number *)p = luaL_checknumber(L, -1); | ||
214 | break; | ||
215 | default: | ||
216 | luaL_error(L, "loadfield(type=%d): invalid type", type); | ||
217 | break; | ||
218 | } /* switch() */ | ||
219 | |||
220 | lua_pop(L, 1); /* table keeps reference */ | ||
221 | |||
222 | return 1; | ||
223 | } /* loadfield() */ | ||
224 | |||
225 | |||
226 | const char *pushnid(lua_State *L, int nid) { | ||
227 | const char *txt; | ||
228 | ASN1_OBJECT *obj; | ||
229 | char buf[256]; | ||
230 | int len; | ||
231 | |||
232 | if ((txt = OBJ_nid2sn(nid)) || (txt = OBJ_nid2ln(nid))) { | ||
233 | lua_pushstring(L, txt); | ||
234 | } else { | ||
235 | if (!(obj = OBJ_nid2obj(nid))) | ||
236 | luaL_error(L, "%d: unknown ASN.1 NID", nid); | ||
237 | |||
238 | if (-1 == (len = OBJ_obj2txt(buf, sizeof buf, obj, 1))) | ||
239 | luaL_error(L, "%d: invalid ASN.1 NID", nid); | ||
240 | |||
241 | lua_pushlstring(L, buf, len); | ||
242 | } | ||
243 | |||
244 | return lua_tostring(L, -1); | ||
245 | } /* pushnid() */ | ||
246 | |||
247 | |||
170 | static void initall(lua_State *L); | 248 | static void initall(lua_State *L); |
171 | 249 | ||
172 | 250 | ||
@@ -369,7 +447,6 @@ static BN_CTX *getctx(lua_State *L) { | |||
369 | lua_pushcfunction(L, &ctx__gc); | 447 | lua_pushcfunction(L, &ctx__gc); |
370 | lua_pushvalue(L, -2); | 448 | lua_pushvalue(L, -2); |
371 | lua_settable(L, LUA_REGISTRYINDEX); | 449 | lua_settable(L, LUA_REGISTRYINDEX); |
372 | |||
373 | } | 450 | } |
374 | 451 | ||
375 | ctx = lua_touserdata(L, -1); | 452 | ctx = lua_touserdata(L, -1); |
@@ -555,6 +632,454 @@ int luaopen__openssl_bignum(lua_State *L) { | |||
555 | 632 | ||
556 | 633 | ||
557 | /* | 634 | /* |
635 | * EVP_PKEY - openssl.pubkey | ||
636 | * | ||
637 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
638 | |||
639 | static int bio__gc(lua_State *L) { | ||
640 | BIO **bio = lua_touserdata(L, 1); | ||
641 | |||
642 | BIO_free(*bio); | ||
643 | *bio = NULL; | ||
644 | |||
645 | return 0; | ||
646 | } /* bio__gc() */ | ||
647 | |||
648 | static BIO *getbio(lua_State *L) { | ||
649 | BIO **bio; | ||
650 | |||
651 | lua_pushcfunction(L, &bio__gc); | ||
652 | lua_gettable(L, LUA_REGISTRYINDEX); | ||
653 | |||
654 | if (lua_isnil(L, -1)) { | ||
655 | lua_pop(L, 1); | ||
656 | |||
657 | bio = prepsimple(L, NULL, &bio__gc); | ||
658 | |||
659 | if (!(*bio = BIO_new(BIO_s_mem()))) | ||
660 | throwssl(L, "BIO_new"); | ||
661 | |||
662 | lua_pushcfunction(L, &bio__gc); | ||
663 | lua_pushvalue(L, -2); | ||
664 | lua_settable(L, LUA_REGISTRYINDEX); | ||
665 | } | ||
666 | |||
667 | bio = lua_touserdata(L, -1); | ||
668 | lua_pop(L, 1); | ||
669 | |||
670 | BIO_reset(*bio); | ||
671 | |||
672 | return *bio; | ||
673 | } /* getbio() */ | ||
674 | |||
675 | |||
676 | static int pk_new(lua_State *L) { | ||
677 | EVP_PKEY **ud; | ||
678 | |||
679 | lua_settop(L, 1); | ||
680 | |||
681 | ud = prepsimple(L, PUBKEY_CLASS); | ||
682 | |||
683 | if (lua_istable(L, 1)) { | ||
684 | int type = EVP_PKEY_RSA; | ||
685 | unsigned bits = 1024; | ||
686 | unsigned exp = 65537; | ||
687 | int curve = NID_X9_62_prime192v1; | ||
688 | const char *id; | ||
689 | lua_Number n; | ||
690 | |||
691 | if (!lua_istable(L, 1)) | ||
692 | goto creat; | ||
693 | |||
694 | if (loadfield(L, 1, "type", LUA_TSTRING, &id)) { | ||
695 | static const struct { int nid; const char *sn; } types[] = { | ||
696 | { EVP_PKEY_RSA, "RSA" }, | ||
697 | { EVP_PKEY_DSA, "DSA" }, | ||
698 | { EVP_PKEY_DH, "DH" }, | ||
699 | { EVP_PKEY_EC, "EC" }, | ||
700 | }; | ||
701 | unsigned i; | ||
702 | |||
703 | type = OBJ_sn2nid(id); | ||
704 | |||
705 | if (NID_undef == (type = EVP_PKEY_type(OBJ_sn2nid(id)))) { | ||
706 | for (i = 0; i < countof(types); i++) { | ||
707 | if (strieq(id, types[i].sn)) { | ||
708 | type = types[i].nid; | ||
709 | break; | ||
710 | } | ||
711 | } | ||
712 | } | ||
713 | |||
714 | luaL_argcheck(L, type != NID_undef, 1, lua_pushfstring(L, "%s: invalid key type", id)); | ||
715 | } | ||
716 | |||
717 | if (loadfield(L, 1, "bits", LUA_TNUMBER, &n)) { | ||
718 | luaL_argcheck(L, n > 0 && n < UINT_MAX, 1, lua_pushfstring(L, "%f: `bits' invalid", n)); | ||
719 | bits = (unsigned)n; | ||
720 | } | ||
721 | |||
722 | if (loadfield(L, 1, "exp", LUA_TNUMBER, &n)) { | ||
723 | luaL_argcheck(L, n > 0 && n < UINT_MAX, 1, lua_pushfstring(L, "%f: `exp' invalid", n)); | ||
724 | exp = (unsigned)n; | ||
725 | } | ||
726 | |||
727 | if (loadfield(L, 1, "curve", LUA_TSTRING, &id)) { | ||
728 | curve = OBJ_sn2nid(id); | ||
729 | luaL_argcheck(L, curve != NID_undef, 1, lua_pushfstring(L, "%s: invalid curve", id)); | ||
730 | } | ||
731 | |||
732 | creat: | ||
733 | if (!(*ud = EVP_PKEY_new())) | ||
734 | return throwssl(L, "pubkey.new"); | ||
735 | |||
736 | switch (EVP_PKEY_type(type)) { | ||
737 | case EVP_PKEY_RSA: { | ||
738 | RSA *rsa; | ||
739 | |||
740 | if (!(rsa = RSA_generate_key(bits, exp, 0, 0))) | ||
741 | return throwssl(L, "pubkey.new"); | ||
742 | |||
743 | EVP_PKEY_set1_RSA(*ud, rsa); | ||
744 | |||
745 | RSA_free(rsa); | ||
746 | |||
747 | break; | ||
748 | } | ||
749 | case EVP_PKEY_DSA: { | ||
750 | DSA *dsa; | ||
751 | |||
752 | if (!(dsa = DSA_generate_parameters(bits, 0, 0, 0, 0, 0, 0))) | ||
753 | return throwssl(L, "pubkey.new"); | ||
754 | |||
755 | if (!DSA_generate_key(dsa)) { | ||
756 | DSA_free(dsa); | ||
757 | return throwssl(L, "pubkey.new"); | ||
758 | } | ||
759 | |||
760 | EVP_PKEY_set1_DSA(*ud, dsa); | ||
761 | |||
762 | DSA_free(dsa); | ||
763 | |||
764 | break; | ||
765 | } | ||
766 | case EVP_PKEY_DH: { | ||
767 | DH *dh; | ||
768 | |||
769 | if (!(dh = DH_generate_parameters(bits, exp, 0, 0))) | ||
770 | return throwssl(L, "pubkey.new"); | ||
771 | |||
772 | if (!DH_generate_key(dh)) { | ||
773 | DH_free(dh); | ||
774 | return throwssl(L, "pubkey.new"); | ||
775 | } | ||
776 | |||
777 | EVP_PKEY_set1_DH(*ud, dh); | ||
778 | |||
779 | DH_free(dh); | ||
780 | |||
781 | break; | ||
782 | } | ||
783 | case EVP_PKEY_EC: { | ||
784 | EC_GROUP *grp; | ||
785 | EC_KEY *key; | ||
786 | |||
787 | if (!(grp = EC_GROUP_new_by_curve_name(curve))) | ||
788 | return throwssl(L, "pubkey.new"); | ||
789 | |||
790 | EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_NAMED_CURVE); | ||
791 | |||
792 | /* compressed points patented */ | ||
793 | EC_GROUP_set_point_conversion_form(grp, POINT_CONVERSION_UNCOMPRESSED); | ||
794 | |||
795 | if (!(key = EC_KEY_new())) { | ||
796 | EC_GROUP_free(grp); | ||
797 | return throwssl(L, "pubkey.new"); | ||
798 | } | ||
799 | |||
800 | EC_KEY_set_group(key, grp); | ||
801 | |||
802 | EC_GROUP_free(grp); | ||
803 | |||
804 | if (!EC_KEY_generate_key(key)) { | ||
805 | EC_KEY_free(key); | ||
806 | return throwssl(L, "pubkey.new"); | ||
807 | } | ||
808 | |||
809 | EVP_PKEY_set1_EC_KEY(*ud, key); | ||
810 | |||
811 | EC_KEY_free(key); | ||
812 | |||
813 | break; | ||
814 | } | ||
815 | default: | ||
816 | return luaL_error(L, "%d: unknown EVP base type (%d)", EVP_PKEY_type(type), type); | ||
817 | } /* switch() */ | ||
818 | } else { | ||
819 | const char *pem; | ||
820 | size_t len; | ||
821 | BIO *bio; | ||
822 | int ok; | ||
823 | |||
824 | if (!(*ud = EVP_PKEY_new())) | ||
825 | return throwssl(L, "pubkey.new"); | ||
826 | |||
827 | switch (lua_type(L, 1)) { | ||
828 | case LUA_TSTRING: | ||
829 | pem = luaL_checklstring(L, 1, &len); | ||
830 | |||
831 | if (!(bio = BIO_new_mem_buf((void *)pem, len))) | ||
832 | return throwssl(L, "pubkey.new"); | ||
833 | |||
834 | if (strstr(pem, "PUBLIC KEY")) { | ||
835 | ok = !!PEM_read_bio_PUBKEY(bio, ud, 0, 0); | ||
836 | } else { | ||
837 | ok = !!PEM_read_bio_PrivateKey(bio, ud, 0, 0); | ||
838 | } | ||
839 | |||
840 | BIO_free(bio); | ||
841 | |||
842 | if (!ok) | ||
843 | return throwssl(L, "pubkey.new"); | ||
844 | |||
845 | break; | ||
846 | default: | ||
847 | return luaL_error(L, "%s: unknown key initializer", lua_typename(L, lua_type(L, 1))); | ||
848 | } /* switch() */ | ||
849 | } | ||
850 | |||
851 | return 1; | ||
852 | } /* pk_new() */ | ||
853 | |||
854 | |||
855 | static int pk_interpose(lua_State *L) { | ||
856 | return interpose(L, X509_NAME_CLASS); | ||
857 | } /* pk_interpose() */ | ||
858 | |||
859 | |||
860 | static int pk_type(lua_State *L) { | ||
861 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
862 | int nid = key->type; | ||
863 | |||
864 | pushnid(L, nid); | ||
865 | |||
866 | return 1; | ||
867 | } /* pk_type() */ | ||
868 | |||
869 | |||
870 | static int pk_setPublicKey(lua_State *L) { | ||
871 | EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS); | ||
872 | const char *pem; | ||
873 | size_t len; | ||
874 | BIO *bio; | ||
875 | int ok; | ||
876 | |||
877 | lua_settop(L, 2); | ||
878 | |||
879 | pem = luaL_checklstring(L, 2, &len); | ||
880 | |||
881 | if (!(bio = BIO_new_mem_buf((void *)pem, len))) | ||
882 | return throwssl(L, "pubkey.new"); | ||
883 | |||
884 | ok = !!PEM_read_bio_PUBKEY(bio, key, 0, 0); | ||
885 | |||
886 | BIO_free(bio); | ||
887 | |||
888 | if (!ok) | ||
889 | return throwssl(L, "pubkey.new"); | ||
890 | |||
891 | lua_pushboolean(L, 1); | ||
892 | |||
893 | return 1; | ||
894 | } /* pk_setPublicKey() */ | ||
895 | |||
896 | |||
897 | static int pk_setPrivateKey(lua_State *L) { | ||
898 | EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS); | ||
899 | const char *pem; | ||
900 | size_t len; | ||
901 | BIO *bio; | ||
902 | int ok; | ||
903 | |||
904 | lua_settop(L, 2); | ||
905 | |||
906 | pem = luaL_checklstring(L, 2, &len); | ||
907 | |||
908 | if (!(bio = BIO_new_mem_buf((void *)pem, len))) | ||
909 | return throwssl(L, "pubkey.new"); | ||
910 | |||
911 | ok = !!PEM_read_bio_PrivateKey(bio, key, 0, 0); | ||
912 | |||
913 | BIO_free(bio); | ||
914 | |||
915 | if (!ok) | ||
916 | return throwssl(L, "pubkey.new"); | ||
917 | |||
918 | lua_pushboolean(L, 1); | ||
919 | |||
920 | return 1; | ||
921 | } /* pk_setPrivateKEY() */ | ||
922 | |||
923 | |||
924 | static int pk_toPEM(lua_State *L) { | ||
925 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
926 | int top, i, ok; | ||
927 | BIO *bio; | ||
928 | char *pem; | ||
929 | long len; | ||
930 | |||
931 | if (1 == (top = lua_gettop(L))) { | ||
932 | lua_pushstring(L, "publickey"); | ||
933 | ++top; | ||
934 | } | ||
935 | |||
936 | bio = getbio(L); | ||
937 | |||
938 | for (i = 2; i <= top; i++) { | ||
939 | static const char *opts[] = { | ||
940 | "public", "PublicKey", | ||
941 | "private", "PrivateKey", | ||
942 | // "params", "Parameters", | ||
943 | }; | ||
944 | |||
945 | switch (checkoption(L, i, NULL, opts)) { | ||
946 | case 0: case 1: | ||
947 | if (!PEM_write_bio_PUBKEY(bio, key)) | ||
948 | return throwssl(L, "pubkey:__tostring"); | ||
949 | |||
950 | len = BIO_get_mem_data(bio, &pem); | ||
951 | lua_pushlstring(L, pem, len); | ||
952 | |||
953 | BIO_reset(bio); | ||
954 | break; | ||
955 | case 2: case 3: | ||
956 | if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0)) | ||
957 | throwssl(L, "pubkey:__tostring"); | ||
958 | |||
959 | len = BIO_get_mem_data(bio, &pem); | ||
960 | lua_pushlstring(L, pem, len); | ||
961 | |||
962 | break; | ||
963 | case 4: case 5: | ||
964 | /* EVP_PKEY_base_id not in OS X */ | ||
965 | switch (EVP_PKEY_type(key->type)) { | ||
966 | case EVP_PKEY_RSA: | ||
967 | break; | ||
968 | case EVP_PKEY_DSA: { | ||
969 | DSA *dsa = EVP_PKEY_get1_DSA(key); | ||
970 | |||
971 | ok = !!PEM_write_bio_DSAparams(bio, dsa); | ||
972 | |||
973 | DSA_free(dsa); | ||
974 | |||
975 | if (!ok) | ||
976 | return throwssl(L, "pubkey:__tostring"); | ||
977 | |||
978 | break; | ||
979 | } | ||
980 | case EVP_PKEY_DH: { | ||
981 | DH *dh = EVP_PKEY_get1_DH(key); | ||
982 | |||
983 | ok = !!PEM_write_bio_DHparams(bio, dh); | ||
984 | |||
985 | DH_free(dh); | ||
986 | |||
987 | if (!ok) | ||
988 | return throwssl(L, "pubkey:__tostring"); | ||
989 | |||
990 | break; | ||
991 | } | ||
992 | case EVP_PKEY_EC: { | ||
993 | EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); | ||
994 | const EC_GROUP *grp = EC_KEY_get0_group(ec); | ||
995 | |||
996 | ok = !!PEM_write_bio_ECPKParameters(bio, grp); | ||
997 | |||
998 | EC_KEY_free(ec); | ||
999 | |||
1000 | if (!ok) | ||
1001 | return throwssl(L, "pubkey:__tostring"); | ||
1002 | |||
1003 | break; | ||
1004 | } | ||
1005 | default: | ||
1006 | return luaL_error(L, "%d: unknown EVP base type", EVP_PKEY_type(key->type)); | ||
1007 | } | ||
1008 | |||
1009 | lua_pushlstring(L, pem, len); | ||
1010 | |||
1011 | BIO_reset(bio); | ||
1012 | |||
1013 | break; | ||
1014 | default: | ||
1015 | lua_pushnil(L); | ||
1016 | |||
1017 | break; | ||
1018 | } /* switch() */ | ||
1019 | } /* for() */ | ||
1020 | |||
1021 | return lua_gettop(L) - top; | ||
1022 | } /* pk_toPEM() */ | ||
1023 | |||
1024 | |||
1025 | static int pk__tostring(lua_State *L) { | ||
1026 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
1027 | BIO *bio = getbio(L); | ||
1028 | char *pem; | ||
1029 | long len; | ||
1030 | int ok; | ||
1031 | |||
1032 | if (!PEM_write_bio_PUBKEY(bio, key)) | ||
1033 | return throwssl(L, "pubkey:__tostring"); | ||
1034 | |||
1035 | len = BIO_get_mem_data(bio, &pem); | ||
1036 | lua_pushlstring(L, pem, len); | ||
1037 | |||
1038 | return 1; | ||
1039 | } /* pk__tostring() */ | ||
1040 | |||
1041 | |||
1042 | static int pk__gc(lua_State *L) { | ||
1043 | EVP_PKEY **ud = luaL_checkudata(L, 1, PUBKEY_CLASS); | ||
1044 | |||
1045 | EVP_PKEY_free(*ud); | ||
1046 | *ud = NULL; | ||
1047 | |||
1048 | return 0; | ||
1049 | } /* pk__gc() */ | ||
1050 | |||
1051 | |||
1052 | static const luaL_Reg pk_methods[] = { | ||
1053 | { "type", &pk_type }, | ||
1054 | { "setPublicKey", &pk_setPublicKey }, | ||
1055 | { "setPrivateKey", &pk_setPrivateKey }, | ||
1056 | { "toPEM", &pk_toPEM }, | ||
1057 | { NULL, NULL }, | ||
1058 | }; | ||
1059 | |||
1060 | static const luaL_Reg pk_metatable[] = { | ||
1061 | { "__tostring", &pk__tostring }, | ||
1062 | { "__gc", &pk__gc }, | ||
1063 | { NULL, NULL }, | ||
1064 | }; | ||
1065 | |||
1066 | |||
1067 | static const luaL_Reg pk_globals[] = { | ||
1068 | { "new", &pk_new }, | ||
1069 | { "interpose", &pk_interpose }, | ||
1070 | { NULL, NULL }, | ||
1071 | }; | ||
1072 | |||
1073 | int luaopen__openssl_pubkey(lua_State *L) { | ||
1074 | initall(L); | ||
1075 | |||
1076 | luaL_newlib(L, pk_globals); | ||
1077 | |||
1078 | return 1; | ||
1079 | } /* luaopen__openssl_pubkey() */ | ||
1080 | |||
1081 | |||
1082 | /* | ||
558 | * X509_NAME - openssl.x509.name | 1083 | * X509_NAME - openssl.x509.name |
559 | * | 1084 | * |
560 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 1085 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
@@ -1365,7 +1890,9 @@ static int xc_getIssuer(lua_State *L) { | |||
1365 | if ((name = X509_get_issuer_name(crt))) | 1890 | if ((name = X509_get_issuer_name(crt))) |
1366 | xn_dup(L, name); | 1891 | xn_dup(L, name); |
1367 | 1892 | ||
1368 | return !!name; | 1893 | lua_pushboolean(L, 1); |
1894 | |||
1895 | return 1; | ||
1369 | } /* xc_getIssuer() */ | 1896 | } /* xc_getIssuer() */ |
1370 | 1897 | ||
1371 | 1898 | ||
@@ -1376,7 +1903,9 @@ static int xc_setIssuer(lua_State *L) { | |||
1376 | if (!X509_set_issuer_name(crt, name)) | 1903 | if (!X509_set_issuer_name(crt, name)) |
1377 | return throwssl(L, "x509.cert:setIssuer"); | 1904 | return throwssl(L, "x509.cert:setIssuer"); |
1378 | 1905 | ||
1379 | return !!name; | 1906 | lua_pushboolean(L, 1); |
1907 | |||
1908 | return 1; | ||
1380 | } /* xc_setIssuer() */ | 1909 | } /* xc_setIssuer() */ |
1381 | 1910 | ||
1382 | 1911 | ||
@@ -1387,7 +1916,9 @@ static int xc_getSubject(lua_State *L) { | |||
1387 | if ((name = X509_get_subject_name(crt))) | 1916 | if ((name = X509_get_subject_name(crt))) |
1388 | xn_dup(L, name); | 1917 | xn_dup(L, name); |
1389 | 1918 | ||
1390 | return !!name; | 1919 | lua_pushboolean(L, 1); |
1920 | |||
1921 | return 1; | ||
1391 | } /* xc_getSubject() */ | 1922 | } /* xc_getSubject() */ |
1392 | 1923 | ||
1393 | 1924 | ||
@@ -1398,7 +1929,9 @@ static int xc_setSubject(lua_State *L) { | |||
1398 | if (!X509_set_subject_name(crt, name)) | 1929 | if (!X509_set_subject_name(crt, name)) |
1399 | return throwssl(L, "x509.cert:setSubject"); | 1930 | return throwssl(L, "x509.cert:setSubject"); |
1400 | 1931 | ||
1401 | return !!name; | 1932 | lua_pushboolean(L, 1); |
1933 | |||
1934 | return 1; | ||
1402 | } /* xc_setSubject() */ | 1935 | } /* xc_setSubject() */ |
1403 | 1936 | ||
1404 | 1937 | ||
@@ -1669,30 +2202,44 @@ static int xc_setBasicConstraintsCritical(lua_State *L) { | |||
1669 | } /* xc_setBasicConstraintsCritical() */ | 2202 | } /* xc_setBasicConstraintsCritical() */ |
1670 | 2203 | ||
1671 | 2204 | ||
2205 | static int xc_getPublicKey(lua_State *L) { | ||
2206 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2207 | EVP_PKEY **key = prepsimple(L, PUBKEY_CLASS); | ||
2208 | |||
2209 | if (!(*key = X509_get_pubkey(crt))) | ||
2210 | return throwssl(L, "x509.cert:getPublicKey"); | ||
2211 | |||
2212 | return 1; | ||
2213 | } /* xc_getPublicKey() */ | ||
2214 | |||
2215 | |||
2216 | static int xc_setPublicKey(lua_State *L) { | ||
2217 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2218 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
2219 | |||
2220 | if (!X509_set_pubkey(crt, key)) | ||
2221 | return throwssl(L, "x509.cert:setPublicKey"); | ||
2222 | |||
2223 | lua_pushboolean(L, 1); | ||
2224 | |||
2225 | return 1; | ||
2226 | } /* xc_setPublicKey() */ | ||
2227 | |||
2228 | |||
1672 | static int xc__tostring(lua_State *L) { | 2229 | static int xc__tostring(lua_State *L) { |
1673 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | 2230 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); |
1674 | int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", 0 }); | 2231 | int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", 0 }); |
1675 | BIO *tmp; | 2232 | BIO *bio = getbio(L); |
1676 | char *pem; | 2233 | char *pem; |
1677 | long len; | 2234 | long len; |
1678 | 2235 | ||
1679 | if (!(tmp = BIO_new(BIO_s_mem()))) | 2236 | if (!PEM_write_bio_X509(bio, crt)) |
1680 | return throwssl(L, "x509.cert:__tostring"); | ||
1681 | |||
1682 | if (!PEM_write_bio_X509(tmp, crt)) { | ||
1683 | BIO_free(tmp); | ||
1684 | |||
1685 | return throwssl(L, "x509.cert:__tostring"); | 2237 | return throwssl(L, "x509.cert:__tostring"); |
1686 | } | ||
1687 | 2238 | ||
1688 | len = BIO_get_mem_data(tmp, &pem); | 2239 | len = BIO_get_mem_data(bio, &pem); |
1689 | |||
1690 | /* FIXME: leaks on panic */ | ||
1691 | 2240 | ||
1692 | lua_pushlstring(L, pem, len); | 2241 | lua_pushlstring(L, pem, len); |
1693 | 2242 | ||
1694 | BIO_free(tmp); | ||
1695 | |||
1696 | return 1; | 2243 | return 1; |
1697 | } /* xc__tostring() */ | 2244 | } /* xc__tostring() */ |
1698 | 2245 | ||
@@ -1733,6 +2280,8 @@ static const luaL_Reg xc_methods[] = { | |||
1733 | { "setBasicConstraint", &xc_setBasicConstraint }, | 2280 | { "setBasicConstraint", &xc_setBasicConstraint }, |
1734 | { "getBasicConstraintsCritical", &xc_getBasicConstraintsCritical }, | 2281 | { "getBasicConstraintsCritical", &xc_getBasicConstraintsCritical }, |
1735 | { "setBasicConstraintsCritical", &xc_setBasicConstraintsCritical }, | 2282 | { "setBasicConstraintsCritical", &xc_setBasicConstraintsCritical }, |
2283 | { "getPublicKey", &xc_getPublicKey }, | ||
2284 | { "setPublicKey", &xc_setPublicKey }, | ||
1736 | { NULL, NULL }, | 2285 | { NULL, NULL }, |
1737 | }; | 2286 | }; |
1738 | 2287 | ||
@@ -1758,14 +2307,167 @@ int luaopen__openssl_x509_cert(lua_State *L) { | |||
1758 | } /* luaopen__openssl_x509_cert() */ | 2307 | } /* luaopen__openssl_x509_cert() */ |
1759 | 2308 | ||
1760 | 2309 | ||
2310 | /* | ||
2311 | * X509_REQ - openssl.x509.csr | ||
2312 | * | ||
2313 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
2314 | |||
2315 | static int xr_new(lua_State *L) { | ||
2316 | const char *pem; | ||
2317 | size_t len; | ||
2318 | X509_REQ **ud; | ||
2319 | X509 *crt; | ||
2320 | |||
2321 | lua_settop(L, 1); | ||
2322 | |||
2323 | ud = prepsimple(L, X509_CSR_CLASS); | ||
2324 | |||
2325 | if ((crt = testsimple(L, 1, X509_CERT_CLASS))) { | ||
2326 | if (!(*ud = X509_to_X509_REQ(crt, 0, 0))) | ||
2327 | return throwssl(L, "x509.csr.new"); | ||
2328 | } else if ((pem = luaL_optlstring(L, 1, NULL, &len))) { | ||
2329 | BIO *tmp; | ||
2330 | int ok; | ||
2331 | |||
2332 | if (!(tmp = BIO_new_mem_buf((char *)pem, len))) | ||
2333 | return throwssl(L, "x509.csr.new"); | ||
2334 | |||
2335 | ok = !!PEM_read_bio_X509_REQ(tmp, ud, 0, ""); /* no password */ | ||
2336 | |||
2337 | BIO_free(tmp); | ||
2338 | |||
2339 | if (!ok) | ||
2340 | return throwssl(L, "x509.csr.new"); | ||
2341 | } else { | ||
2342 | if (!(*ud = X509_REQ_new())) | ||
2343 | return throwssl(L, "x509.csr.new"); | ||
2344 | } | ||
2345 | |||
2346 | return 1; | ||
2347 | } /* xr_new() */ | ||
2348 | |||
2349 | |||
2350 | static int xr_interpose(lua_State *L) { | ||
2351 | return interpose(L, X509_CSR_CLASS); | ||
2352 | } /* xr_interpose() */ | ||
2353 | |||
2354 | |||
2355 | static int xr_getVersion(lua_State *L) { | ||
2356 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2357 | |||
2358 | lua_pushinteger(L, X509_REQ_get_version(csr) + 1); | ||
2359 | |||
2360 | return 1; | ||
2361 | } /* xr_getVersion() */ | ||
2362 | |||
2363 | |||
2364 | static int xr_setVersion(lua_State *L) { | ||
2365 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2366 | int version = luaL_checkint(L, 2); | ||
2367 | |||
2368 | if (!X509_REQ_set_version(csr, version - 1)) | ||
2369 | return luaL_error(L, "x509.csr:setVersion: %d: invalid version", version); | ||
2370 | |||
2371 | lua_pushboolean(L, 1); | ||
2372 | |||
2373 | return 1; | ||
2374 | } /* xr_setVersion() */ | ||
2375 | |||
2376 | |||
2377 | static int xr_setSubjectName(lua_State *L) { | ||
2378 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2379 | X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS); | ||
2380 | |||
2381 | if (!X509_REQ_set_subject_name(csr, name)) | ||
2382 | return throwssl(L, "x509.csr:setSubject"); | ||
2383 | |||
2384 | lua_pushboolean(L, 1); | ||
2385 | |||
2386 | return 1; | ||
2387 | } /* xr_setSubjectName() */ | ||
2388 | |||
2389 | |||
2390 | static int xr_setPublicKey(lua_State *L) { | ||
2391 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2392 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
2393 | |||
2394 | if (!X509_REQ_set_pubkey(csr, key)) | ||
2395 | return throwssl(L, "x509.csr:setPublicKey"); | ||
2396 | |||
2397 | lua_pushboolean(L, 1); | ||
2398 | |||
2399 | return 1; | ||
2400 | } /* xr_setPublicKey() */ | ||
2401 | |||
2402 | |||
2403 | static int xr__tostring(lua_State *L) { | ||
2404 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2405 | int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", 0 }); | ||
2406 | BIO *bio = getbio(L); | ||
2407 | char *pem; | ||
2408 | long len; | ||
2409 | |||
2410 | if (!PEM_write_bio_X509_REQ(bio, csr)) | ||
2411 | return throwssl(L, "x509.csr:__tostring"); | ||
2412 | |||
2413 | len = BIO_get_mem_data(bio, &pem); | ||
2414 | |||
2415 | lua_pushlstring(L, pem, len); | ||
2416 | |||
2417 | return 1; | ||
2418 | } /* xr__tostring() */ | ||
2419 | |||
2420 | |||
2421 | static int xr__gc(lua_State *L) { | ||
2422 | X509_REQ **ud = luaL_checkudata(L, 1, X509_CSR_CLASS); | ||
2423 | |||
2424 | X509_REQ_free(*ud); | ||
2425 | *ud = NULL; | ||
2426 | |||
2427 | return 0; | ||
2428 | } /* xr__gc() */ | ||
2429 | |||
2430 | static const luaL_Reg xr_methods[] = { | ||
2431 | { "getVersion", &xr_getVersion }, | ||
2432 | { "setVersion", &xr_setVersion }, | ||
2433 | { "setSubjectName", &xr_setSubjectName }, | ||
2434 | { "setPublicKey", &xr_setPublicKey }, | ||
2435 | { NULL, NULL }, | ||
2436 | }; | ||
2437 | |||
2438 | static const luaL_Reg xr_metatable[] = { | ||
2439 | { "__tostring", &xr__tostring }, | ||
2440 | { "__gc", &xr__gc }, | ||
2441 | { NULL, NULL }, | ||
2442 | }; | ||
2443 | |||
2444 | |||
2445 | static const luaL_Reg xr_globals[] = { | ||
2446 | { "new", &xr_new }, | ||
2447 | { "interpose", &xr_interpose }, | ||
2448 | { NULL, NULL }, | ||
2449 | }; | ||
2450 | |||
2451 | int luaopen__openssl_x509_csr(lua_State *L) { | ||
2452 | initall(L); | ||
2453 | |||
2454 | luaL_newlib(L, xr_globals); | ||
2455 | |||
2456 | return 1; | ||
2457 | } /* luaopen__openssl_x509_csr() */ | ||
2458 | |||
2459 | |||
2460 | |||
1761 | static void initall(lua_State *L) { | 2461 | static void initall(lua_State *L) { |
1762 | ERR_load_crypto_strings(); | 2462 | ERR_load_crypto_strings(); |
1763 | OpenSSL_add_all_algorithms(); | 2463 | OpenSSL_add_all_algorithms(); |
1764 | 2464 | ||
1765 | addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); | 2465 | addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); |
2466 | addclass(L, PUBKEY_CLASS, pk_methods, pk_metatable); | ||
1766 | addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); | 2467 | addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); |
1767 | addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable); | 2468 | addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable); |
1768 | addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable); | 2469 | addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable); |
2470 | addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable); | ||
1769 | } /* initall() */ | 2471 | } /* initall() */ |
1770 | 2472 | ||
1771 | 2473 | ||