summaryrefslogtreecommitdiff
path: root/src/openssl.c
diff options
context:
space:
mode:
authorwilliam <william@25tandclement.com>2014-03-25 19:58:02 -0700
committerwilliam <william@25tandclement.com>2014-03-25 19:58:02 -0700
commite28605d441ecd909c814ee1893b7dde07c7684d2 (patch)
tree500b56c3b35d179814bd103cf705c02f80cbb0ee /src/openssl.c
parent9975e282f13d63378e54081056c6597508c2ddb4 (diff)
downloadluaossl-e28605d441ecd909c814ee1893b7dde07c7684d2.tar.gz
luaossl-e28605d441ecd909c814ee1893b7dde07c7684d2.tar.bz2
luaossl-e28605d441ecd909c814ee1893b7dde07c7684d2.zip
add DER input and output formats, plus 'autodetect' PEM-or-DER, for almost everything (except pk__tostring and pk_toPEM, FIXME)
Diffstat (limited to 'src/openssl.c')
-rw-r--r--src/openssl.c229
1 files changed, 167 insertions, 62 deletions
diff --git a/src/openssl.c b/src/openssl.c
index 1554053..84d8079 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -31,6 +31,7 @@
31#include <strings.h> /* strcasecmp(3) */ 31#include <strings.h> /* strcasecmp(3) */
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#include <ctype.h> /* tolower(3) */
34 35
35#include <sys/types.h> 36#include <sys/types.h>
36#include <sys/stat.h> /* struct stat stat(2) */ 37#include <sys/stat.h> /* struct stat stat(2) */
@@ -96,6 +97,8 @@
96#define stricmp(a, b) strcasecmp((a), (b)) 97#define stricmp(a, b) strcasecmp((a), (b))
97#define strieq(a, b) (!stricmp((a), (b))) 98#define strieq(a, b) (!stricmp((a), (b)))
98 99
100#define xtolower(c) tolower((unsigned char)(c))
101
99#define SAY_(file, func, line, fmt, ...) \ 102#define SAY_(file, func, line, fmt, ...) \
100 fprintf(stderr, "%s:%d: " fmt "%s", __func__, __LINE__, __VA_ARGS__) 103 fprintf(stderr, "%s:%d: " fmt "%s", __func__, __LINE__, __VA_ARGS__)
101 104
@@ -218,7 +221,7 @@ static void addclass(lua_State *L, const char *name, const luaL_Reg *methods, co
218} /* addclass() */ 221} /* addclass() */
219 222
220 223
221static int checkoption(struct lua_State *L, int index, const char *def, const char *opts[]) { 224static int checkoption(struct lua_State *L, int index, const char *def, const char *const opts[]) {
222 const char *opt = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index); 225 const char *opt = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index);
223 int i; 226 int i;
224 227
@@ -231,6 +234,34 @@ static int checkoption(struct lua_State *L, int index, const char *def, const ch
231} /* checkoption() */ 234} /* checkoption() */
232 235
233 236
237#define X509_ANY 0x01
238#define X509_PEM 0x02
239#define X509_DER 0x04
240#define X509_ALL (X509_PEM|X509_DER)
241
242static int optencoding(lua_State *L, int index, const char *def, int allow) {
243 static const char *const opts[] = { "*", "pem", "der", NULL };
244 int type = 0;
245
246 switch (checkoption(L, index, def, opts)) {
247 case 0:
248 type = X509_ANY;
249 break;
250 case 1:
251 type = X509_PEM;
252 break;
253 case 2:
254 type = X509_DER;
255 break;
256 }
257
258 if (!(type & allow))
259 luaL_argerror(L, index, lua_pushfstring(L, "invalid option %s", luaL_checkstring(L, index)));
260
261 return type;
262} /* optencoding() */
263
264
234static _Bool getfield(lua_State *L, int index, const char *k) { 265static _Bool getfield(lua_State *L, int index, const char *k) {
235 lua_getfield(L, index, k); 266 lua_getfield(L, index, k);
236 267
@@ -719,11 +750,12 @@ static BIO *getbio(lua_State *L) {
719static int pk_new(lua_State *L) { 750static int pk_new(lua_State *L) {
720 EVP_PKEY **ud; 751 EVP_PKEY **ud;
721 752
722 lua_settop(L, 1); 753 /* #1 table or key; if key, #2 format and #3 type */
754 lua_settop(L, 3);
723 755
724 ud = prepsimple(L, PUBKEY_CLASS); 756 ud = prepsimple(L, PUBKEY_CLASS);
725 757
726 if (lua_istable(L, 1)) { 758 if (lua_istable(L, 1) || lua_isnil(L, 1)) {
727 int type = EVP_PKEY_RSA; 759 int type = EVP_PKEY_RSA;
728 unsigned bits = 1024; 760 unsigned bits = 1024;
729 unsigned exp = 65537; 761 unsigned exp = 65537;
@@ -860,37 +892,69 @@ creat:
860 default: 892 default:
861 return luaL_error(L, "%d: unknown EVP base type (%d)", EVP_PKEY_type(type), type); 893 return luaL_error(L, "%d: unknown EVP base type (%d)", EVP_PKEY_type(type), type);
862 } /* switch() */ 894 } /* switch() */
863 } else { 895 } else if (lua_isstring(L, 1)) {
864 const char *pem; 896 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
897 int ispub = -1;
898 const char *opt, *data;
865 size_t len; 899 size_t len;
866 BIO *bio; 900 BIO *bio;
867 int ok; 901 int ok = 0;
902
903 /* check if specified publickey or privatekey */
904 if ((opt = luaL_optstring(L, 3, NULL))) {
905 if (xtolower(opt[0]) == 'p' && xtolower(opt[1]) == 'u') {
906 ispub = 1;
907 } else if (xtolower(opt[0]) == 'p' && xtolower(opt[1]) == 'r') {
908 ispub = 0;
909 } else {
910 return luaL_argerror(L, 3, lua_pushfstring(L, "invalid option %s", opt));
911 }
912 }
868 913
869 if (!(*ud = EVP_PKEY_new())) 914 data = luaL_checklstring(L, 1, &len);
915
916 if (!(bio = BIO_new_mem_buf((void *)data, len)))
870 return throwssl(L, "pubkey.new"); 917 return throwssl(L, "pubkey.new");
871 918
872 switch (lua_type(L, 1)) { 919 if (type == X509_PEM || type == X509_ANY) {
873 case LUA_TSTRING: 920 if (ispub == 1 || ispub == -1) {
874 pem = luaL_checklstring(L, 1, &len); 921 ok = !!(*ud = PEM_read_bio_PUBKEY(bio, NULL, 0, ""));
875 922
876 if (!(bio = BIO_new_mem_buf((void *)pem, len))) 923 if (ok || (type == X509_PEM && ispub == 1))
877 return throwssl(L, "pubkey.new"); 924 goto done;
925 }
878 926
879 if (strstr(pem, "PUBLIC KEY")) { 927 if (ispub == 0 || ispub == -1) {
880 ok = !!PEM_read_bio_PUBKEY(bio, ud, 0, 0); 928 ok = !!(*ud = PEM_read_bio_PrivateKey(bio, NULL, 0, ""));
881 } else { 929
882 ok = !!PEM_read_bio_PrivateKey(bio, ud, 0, 0); 930 if (ok || (type == X509_PEM && ispub == 0))
931 goto done;
883 } 932 }
933 }
884 934
885 BIO_free(bio); 935 if (type == X509_DER || type == X509_ANY) {
936 if (ispub == 1 || ispub == -1) {
937 ok = !!(*ud = d2i_PUBKEY_bio(bio, NULL));
886 938
887 if (!ok) 939 if (ok || (type == X509_DER && ispub == 1))
888 return throwssl(L, "pubkey.new"); 940 goto done;
941 }
889 942
890 break; 943 if (ispub == 0 || ispub == -1) {
891 default: 944 ok = !!(*ud = d2i_PrivateKey_bio(bio, NULL));
892 return luaL_error(L, "%s: unknown key initializer", lua_typename(L, lua_type(L, 1))); 945
893 } /* switch() */ 946 if (ok || (type == X509_DER && ispub == 0))
947 goto done;
948 }
949 }
950
951done:
952 BIO_free(bio);
953
954 if (!ok)
955 return throwssl(L, "pubkey.new");
956 } else {
957 return luaL_error(L, "%s: unknown key initializer", lua_typename(L, lua_type(L, 1)));
894 } 958 }
895 959
896 return 1; 960 return 1;
@@ -914,19 +978,24 @@ static int pk_type(lua_State *L) {
914 978
915static int pk_setPublicKey(lua_State *L) { 979static int pk_setPublicKey(lua_State *L) {
916 EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS); 980 EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS);
917 const char *pem; 981 const char *data;
918 size_t len; 982 size_t len;
919 BIO *bio; 983 BIO *bio;
920 int ok; 984 int type, ok = 0;
921
922 lua_settop(L, 2);
923 985
924 pem = luaL_checklstring(L, 2, &len); 986 data = luaL_checklstring(L, 2, &len);
987 type = optencoding(L, 3, "*", X509_ANY|X509_PEM|X509_DER);
925 988
926 if (!(bio = BIO_new_mem_buf((void *)pem, len))) 989 if (!(bio = BIO_new_mem_buf((void *)data, len)))
927 return throwssl(L, "pubkey.new"); 990 return throwssl(L, "pubkey.new");
928 991
929 ok = !!PEM_read_bio_PUBKEY(bio, key, 0, 0); 992 if (type == X509_ANY || type == X509_PEM) {
993 ok = !!PEM_read_bio_PUBKEY(bio, key, 0, "");
994 }
995
996 if (!ok && (type == X509_ANY || type == X509_DER)) {
997 ok = !!d2i_PUBKEY_bio(bio, key);
998 }
930 999
931 BIO_free(bio); 1000 BIO_free(bio);
932 1001
@@ -941,19 +1010,24 @@ static int pk_setPublicKey(lua_State *L) {
941 1010
942static int pk_setPrivateKey(lua_State *L) { 1011static int pk_setPrivateKey(lua_State *L) {
943 EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS); 1012 EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS);
944 const char *pem; 1013 const char *data;
945 size_t len; 1014 size_t len;
946 BIO *bio; 1015 BIO *bio;
947 int ok; 1016 int type, ok = 0;
948 1017
949 lua_settop(L, 2); 1018 data = luaL_checklstring(L, 2, &len);
1019 type = optencoding(L, 3, "*", X509_ANY|X509_PEM|X509_DER);
950 1020
951 pem = luaL_checklstring(L, 2, &len); 1021 if (!(bio = BIO_new_mem_buf((void *)data, len)))
952
953 if (!(bio = BIO_new_mem_buf((void *)pem, len)))
954 return throwssl(L, "pubkey.new"); 1022 return throwssl(L, "pubkey.new");
955 1023
956 ok = !!PEM_read_bio_PrivateKey(bio, key, 0, 0); 1024 if (type == X509_ANY || type == X509_PEM) {
1025 ok = !!PEM_read_bio_PrivateKey(bio, key, 0, "");
1026 }
1027
1028 if (!ok && (type == X509_ANY || type == X509_DER)) {
1029 ok = !!d2i_PrivateKey_bio(bio, key);
1030 }
957 1031
958 BIO_free(bio); 1032 BIO_free(bio);
959 1033
@@ -1027,7 +1101,7 @@ static int pk_toPEM(lua_State *L) {
1027 bio = getbio(L); 1101 bio = getbio(L);
1028 1102
1029 for (i = 2; i <= top; i++) { 1103 for (i = 2; i <= top; i++) {
1030 static const char *opts[] = { 1104 static const char *const opts[] = {
1031 "public", "PublicKey", 1105 "public", "PublicKey",
1032 "private", "PrivateKey", 1106 "private", "PrivateKey",
1033// "params", "Parameters", 1107// "params", "Parameters",
@@ -1624,22 +1698,29 @@ int luaopen__openssl_x509_altname(lua_State *L) {
1624 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1698 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1625 1699
1626static int xc_new(lua_State *L) { 1700static int xc_new(lua_State *L) {
1627 const char *pem; 1701 const char *data;
1628 size_t len; 1702 size_t len;
1629 X509 **ud; 1703 X509 **ud;
1630 1704
1631 lua_settop(L, 1); 1705 lua_settop(L, 2);
1632 1706
1633 ud = prepsimple(L, X509_CERT_CLASS); 1707 ud = prepsimple(L, X509_CERT_CLASS);
1634 1708
1635 if ((pem = luaL_optlstring(L, 1, NULL, &len))) { 1709 if ((data = luaL_optlstring(L, 1, NULL, &len))) {
1710 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
1636 BIO *tmp; 1711 BIO *tmp;
1637 int ok; 1712 int ok = 0;
1638 1713
1639 if (!(tmp = BIO_new_mem_buf((char *)pem, len))) 1714 if (!(tmp = BIO_new_mem_buf((char *)data, len)))
1640 return throwssl(L, "x509.cert.new"); 1715 return throwssl(L, "x509.cert.new");
1641 1716
1642 ok = !!PEM_read_bio_X509(tmp, ud, 0, ""); /* no password */ 1717 if (type == X509_PEM || type == X509_ANY) {
1718 ok = !!(*ud = PEM_read_bio_X509(tmp, NULL, 0, "")); /* no password */
1719 }
1720
1721 if (!ok && (type == X509_DER || type == X509_ANY)) {
1722 ok = !!(*ud = d2i_X509_bio(tmp, NULL));
1723 }
1643 1724
1644 BIO_free(tmp); 1725 BIO_free(tmp);
1645 1726
@@ -2399,17 +2480,25 @@ static int xc_sign(lua_State *L) {
2399 2480
2400static int xc__tostring(lua_State *L) { 2481static int xc__tostring(lua_State *L) {
2401 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 2482 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
2402 int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", NULL }); 2483 int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
2403 BIO *bio = getbio(L); 2484 BIO *bio = getbio(L);
2404 char *pem; 2485 char *data;
2405 long len; 2486 long len;
2406 2487
2407 if (!PEM_write_bio_X509(bio, crt)) 2488 switch (type) {
2408 return throwssl(L, "x509.cert:__tostring"); 2489 case X509_PEM:
2490 if (!PEM_write_bio_X509(bio, crt))
2491 return throwssl(L, "x509.cert:__tostring");
2492 break;
2493 case X509_DER:
2494 if (!i2d_X509_bio(bio, crt))
2495 return throwssl(L, "x509.cert:__tostring");
2496 break;
2497 } /* switch() */
2409 2498
2410 len = BIO_get_mem_data(bio, &pem); 2499 len = BIO_get_mem_data(bio, &data);
2411 2500
2412 lua_pushlstring(L, pem, len); 2501 lua_pushlstring(L, data, len);
2413 2502
2414 return 1; 2503 return 1;
2415} /* xc__tostring() */ 2504} /* xc__tostring() */
@@ -2486,26 +2575,34 @@ int luaopen__openssl_x509_cert(lua_State *L) {
2486 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2575 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2487 2576
2488static int xr_new(lua_State *L) { 2577static int xr_new(lua_State *L) {
2489 const char *pem; 2578 const char *data;
2490 size_t len; 2579 size_t len;
2491 X509_REQ **ud; 2580 X509_REQ **ud;
2492 X509 *crt; 2581 X509 *crt;
2493 2582
2494 lua_settop(L, 1); 2583 lua_settop(L, 1);
2584 lua_settop(L, 2);
2495 2585
2496 ud = prepsimple(L, X509_CSR_CLASS); 2586 ud = prepsimple(L, X509_CSR_CLASS);
2497 2587
2498 if ((crt = testsimple(L, 1, X509_CERT_CLASS))) { 2588 if ((crt = testsimple(L, 1, X509_CERT_CLASS))) {
2499 if (!(*ud = X509_to_X509_REQ(crt, 0, 0))) 2589 if (!(*ud = X509_to_X509_REQ(crt, 0, 0)))
2500 return throwssl(L, "x509.csr.new"); 2590 return throwssl(L, "x509.csr.new");
2501 } else if ((pem = luaL_optlstring(L, 1, NULL, &len))) { 2591 } else if ((data = luaL_optlstring(L, 1, NULL, &len))) {
2592 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
2502 BIO *tmp; 2593 BIO *tmp;
2503 int ok; 2594 int ok = 0;
2504 2595
2505 if (!(tmp = BIO_new_mem_buf((char *)pem, len))) 2596 if (!(tmp = BIO_new_mem_buf((char *)data, len)))
2506 return throwssl(L, "x509.csr.new"); 2597 return throwssl(L, "x509.csr.new");
2507 2598
2508 ok = !!PEM_read_bio_X509_REQ(tmp, ud, 0, ""); /* no password */ 2599 if (type == X509_PEM || type == X509_ANY) {
2600 ok = !!(*ud = PEM_read_bio_X509_REQ(tmp, NULL, 0, "")); /* no password */
2601 }
2602
2603 if (!ok && (type == X509_DER || type == X509_ANY)) {
2604 ok = !!(*ud = d2i_X509_REQ_bio(tmp, NULL));
2605 }
2509 2606
2510 BIO_free(tmp); 2607 BIO_free(tmp);
2511 2608
@@ -2612,17 +2709,25 @@ static int xr_sign(lua_State *L) {
2612 2709
2613static int xr__tostring(lua_State *L) { 2710static int xr__tostring(lua_State *L) {
2614 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); 2711 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
2615 int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", NULL }); 2712 int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
2616 BIO *bio = getbio(L); 2713 BIO *bio = getbio(L);
2617 char *pem; 2714 char *data;
2618 long len; 2715 long len;
2619 2716
2620 if (!PEM_write_bio_X509_REQ(bio, csr)) 2717 switch (type) {
2621 return throwssl(L, "x509.csr:__tostring"); 2718 case X509_PEM:
2719 if (!PEM_write_bio_X509_REQ(bio, csr))
2720 return throwssl(L, "x509.csr:__tostring");
2721 break;
2722 case X509_DER:
2723 if (!i2d_X509_REQ_bio(bio, csr))
2724 return throwssl(L, "x509.csr:__tostring");
2725 break;
2726 } /* switch() */
2622 2727
2623 len = BIO_get_mem_data(bio, &pem); 2728 len = BIO_get_mem_data(bio, &data);
2624 2729
2625 lua_pushlstring(L, pem, len); 2730 lua_pushlstring(L, data, len);
2626 2731
2627 return 1; 2732 return 1;
2628} /* xr__tostring() */ 2733} /* xr__tostring() */
@@ -3063,7 +3168,7 @@ int luaopen__openssl_x509_store_context(lua_State *L) {
3063 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 3168 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3064 3169
3065static int sx_new(lua_State *L) { 3170static int sx_new(lua_State *L) {
3066 static const char *opts[] = { 3171 static const char *const opts[] = {
3067 "SSLv2", "SSLv3", "SSLv23", "SSL", "TLSv1", "TLS", NULL 3172 "SSLv2", "SSLv3", "SSLv23", "SSL", "TLSv1", "TLS", NULL
3068 }; 3173 };
3069 /* later versions of SSL declare a const qualifier on the return type */ 3174 /* later versions of SSL declare a const qualifier on the return type */