summaryrefslogtreecommitdiff
path: root/openssl.c
diff options
context:
space:
mode:
authorWilliam Ahern <william@server.local>2012-10-05 18:31:17 -0700
committerWilliam Ahern <william@server.local>2012-10-05 18:31:17 -0700
commite4d2a3e899701a6b0bd88f2820361fb3c24fb231 (patch)
treee6fbcd46f278d564a1b4011ca52f24337ce77c57 /openssl.c
parent6a069b6d93892bfce6be1ca368887835cd4ccbfa (diff)
downloadluaossl-e4d2a3e899701a6b0bd88f2820361fb3c24fb231.tar.gz
luaossl-e4d2a3e899701a6b0bd88f2820361fb3c24fb231.tar.bz2
luaossl-e4d2a3e899701a6b0bd88f2820361fb3c24fb231.zip
-n
wrap GENERAL_NAMES and add more alt name routines
Diffstat (limited to 'openssl.c')
-rw-r--r--openssl.c430
1 files changed, 405 insertions, 25 deletions
diff --git a/openssl.c b/openssl.c
index 7ec8b73..d491106 100644
--- a/openssl.c
+++ b/openssl.c
@@ -28,9 +28,13 @@
28 28
29#include <limits.h> /* INT_MAX INT_MIN */ 29#include <limits.h> /* INT_MAX INT_MIN */
30#include <string.h> /* memset(3) */ 30#include <string.h> /* memset(3) */
31#include <strings.h> /* strcasecmp(3) */
31#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) */
32#include <time.h> /* struct tm time_t strptime(3) */ 33#include <time.h> /* struct tm time_t strptime(3) */
33 34
35#include <netinet/in.h> /* struct in_addr struct in6_addr */
36#include <arpa/inet.h> /* AF_INET6 AF_INET inet_pton(3) */
37
34#include <openssl/err.h> 38#include <openssl/err.h>
35#include <openssl/bn.h> 39#include <openssl/bn.h>
36#include <openssl/asn1.h> 40#include <openssl/asn1.h>
@@ -45,6 +49,7 @@
45 49
46 50
47#define X509_NAME_CLASS "OpenSSL X.509 Name" 51#define X509_NAME_CLASS "OpenSSL X.509 Name"
52#define X509_GENS_CLASS "OpenSSL X.509 AltName"
48#define X509_CERT_CLASS "OpenSSL X.509 Cert" 53#define X509_CERT_CLASS "OpenSSL X.509 Cert"
49#define BIGNUM_CLASS "OpenSSL BN" 54#define BIGNUM_CLASS "OpenSSL BN"
50 55
@@ -54,22 +59,45 @@
54 59
55#define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i)) 60#define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i))
56 61
62#define stricmp(a, b) strcasecmp((a), (b))
63#define strieq(a, b) (!stricmp((a), (b)))
64
57 65
58static void *prepudata(lua_State *L, const char *tname, size_t size) { 66static void *prepudata(lua_State *L, size_t size, const char *tname, int (*gc)(lua_State *)) {
59 void *p = memset(lua_newuserdata(L, size), 0, size); 67 void *p = memset(lua_newuserdata(L, size), 0, size);
60 luaL_setmetatable(L, tname); 68
69 if (tname) {
70 luaL_setmetatable(L, tname);
71 } else {
72 lua_newtable(L);
73 lua_pushcfunction(L, gc);
74 lua_setfield(L, -2, "__gc");
75 lua_setmetatable(L, -2);
76 }
77
61 return p; 78 return p;
62} /* prepudata() */ 79} /* prepudata() */
63 80
64 81
65static void *prepsimple(lua_State *L, const char *tname) { 82static void *prepsimple(lua_State *L, const char *tname, int (*gc)(lua_State *)) {
66 void **p = prepudata(L, tname, sizeof (void *)); 83 void **p = prepudata(L, sizeof (void *), tname, gc);
67 return p; 84 return p;
68} /* presimple() */ 85} /* prepsimple() */
86
87#define prepsimple_(a, b, c, ...) prepsimple((a), (b), (c))
88#define prepsimple(...) prepsimple_(__VA_ARGS__, 0)
69 89
70 90
71static void *checksimple(lua_State *L, int index, const char *tname) { 91static void *checksimple(lua_State *L, int index, const char *tname) {
72 void **p = luaL_checkudata(L, index, tname); 92 void **p;
93
94 if (tname) {
95 p = luaL_checkudata(L, index, tname);
96 } else {
97 luaL_checktype(L, index, LUA_TUSERDATA);
98 p = lua_touserdata(L, index);
99 }
100
73 return *p; 101 return *p;
74} /* checksimple() */ 102} /* checksimple() */
75 103
@@ -309,13 +337,7 @@ static BN_CTX *getctx(lua_State *L) {
309 if (lua_isnil(L, -1)) { 337 if (lua_isnil(L, -1)) {
310 lua_pop(L, 1); 338 lua_pop(L, 1);
311 339
312 ctx = lua_newuserdata(L, sizeof *ctx); 340 ctx = prepsimple(L, NULL, &ctx__gc);
313 *ctx = NULL;
314
315 lua_newtable(L);
316 lua_pushcfunction(L, &ctx__gc);
317 lua_setfield(L, -2, "__gc");
318 lua_setmetatable(L, -2);
319 341
320 if (!(*ctx = BN_CTX_new())) 342 if (!(*ctx = BN_CTX_new()))
321 throwssl(L, "bignum"); 343 throwssl(L, "bignum");
@@ -665,6 +687,239 @@ int luaopen__openssl_x509_name(lua_State *L) {
665 687
666 688
667/* 689/*
690 * GENERAL_NAMES - openssl.x509.altname
691 *
692 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
693
694static GENERAL_NAMES *gn_dup(lua_State *L, GENERAL_NAMES *gens) {
695 GENERAL_NAMES **ud = prepsimple(L, X509_GENS_CLASS);
696
697 if (!(*ud = sk_GENERAL_NAMES_dup(gens)))
698 throwssl(L, "x509.altname.dup");
699
700 return *ud;
701} /* gn_dup() */
702
703
704static int gn_new(lua_State *L) {
705 GENERAL_NAMES **ud = prepsimple(L, X509_GENS_CLASS);
706
707 if (!(*ud = sk_GENERAL_NAME_new_null()))
708 return throwssl(L, "x509.altname.new");
709
710 return 1;
711} /* gn_new() */
712
713
714static int gn_interpose(lua_State *L) {
715 return interpose(L, X509_GENS_CLASS);
716} /* gn_interpose() */
717
718
719static int gn_setCritical(lua_State *L) {
720 GENERAL_NAMES *gens = checksimple(L, 1, X509_GENS_CLASS);
721
722 return 0;
723} /* gn_setCritical() */
724
725
726static int gn_checktype(lua_State *L, int index) {
727 static const struct { int type; const char *name; } table[] = {
728 { GEN_EMAIL, "RFC822Name" },
729 { GEN_EMAIL, "RFC822" },
730 { GEN_EMAIL, "email" },
731 { GEN_URI, "UniformResourceIdentifier" },
732 { GEN_URI, "URI" },
733 { GEN_DNS, "DNSName" },
734 { GEN_DNS, "DNS" },
735 { GEN_IPADD, "IPAddress" },
736 { GEN_IPADD, "IP" },
737 };
738 const char *type = luaL_checkstring(L, index);
739 unsigned i;
740
741 for (i = 0; i < countof(table); i++) {
742 if (strieq(table[i].name, type))
743 return table[i].type;
744 }
745
746 return luaL_error(L, "%s: invalid type", type), 0;
747} /* gn_checktype() */
748
749
750static int gn_add(lua_State *L) {
751 GENERAL_NAMES *gens = checksimple(L, 1, X509_GENS_CLASS);
752 int type = gn_checktype(L, 2);
753 size_t len;
754 const char *txt = luaL_checklstring(L, 3, &len);
755 GENERAL_NAME *gen = NULL;
756 union { struct in6_addr in6; struct in_addr in; } ip;
757
758 if (type == GEN_IPADD) {
759 if (strchr(txt, ':')) {
760 if (1 != inet_pton(AF_INET6, txt, &ip.in6))
761 return luaL_error(L, "%s: invalid address", txt);
762
763 txt = (char *)ip.in6.s6_addr;
764 len = 16;
765 } else {
766 if (1 != inet_pton(AF_INET, txt, &ip.in))
767 return luaL_error(L, "%s: invalid address", txt);
768
769 txt = (char *)&ip.in.s_addr;
770 len = 4;
771 }
772 }
773
774 if (!(gen = GENERAL_NAME_new()))
775 goto error;
776
777 gen->type = type;
778
779 if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()))
780 goto error;
781
782 if (!ASN1_STRING_set(gen->d.ia5, (unsigned char *)txt, len))
783 goto error;
784
785 sk_GENERAL_NAME_push(gens, gen);
786
787 lua_pushboolean(L, 1);
788
789 return 1;
790error:
791 GENERAL_NAME_free(gen);
792
793 return throwssl(L, "x509.altname:add");
794} /* gn_add() */
795
796
797static int gn__next(lua_State *L) {
798 GENERAL_NAMES *gens = checksimple(L, lua_upvalueindex(1), X509_GENS_CLASS);
799 int i = lua_tointeger(L, lua_upvalueindex(2));
800 int n = sk_GENERAL_NAME_num(gens);
801
802 lua_settop(L, 0);
803
804 while (i < n) {
805 GENERAL_NAME *name;
806 const char *tag, *txt;
807 size_t len;
808 union { struct in_addr in; struct in6_addr in6; } ip;
809 char buf[INET6_ADDRSTRLEN + 1];
810 int af;
811
812 if (!(name = sk_GENERAL_NAME_value(gens, i++)))
813 continue;
814
815 switch (name->type) {
816 case GEN_EMAIL:
817 tag = "RFC822";
818 txt = (char *)M_ASN1_STRING_data(name->d.rfc822Name);
819 len = M_ASN1_STRING_length(name->d.rfc822Name);
820
821 break;
822 case GEN_URI:
823 tag = "URI";
824 txt = (char *)M_ASN1_STRING_data(name->d.uniformResourceIdentifier);
825 len = M_ASN1_STRING_length(name->d.uniformResourceIdentifier);
826
827 break;
828 case GEN_DNS:
829 tag = "DNS";
830 txt = (char *)M_ASN1_STRING_data(name->d.dNSName);
831 len = M_ASN1_STRING_length(name->d.dNSName);
832
833 break;
834 case GEN_IPADD:
835 tag = "IP";
836 txt = (char *)M_ASN1_STRING_data(name->d.iPAddress);
837 len = M_ASN1_STRING_length(name->d.iPAddress);
838
839 switch (len) {
840 case 16:
841 memcpy(ip.in6.s6_addr, txt, 16);
842 af = AF_INET6;
843
844 break;
845 case 4:
846 memcpy(&ip.in.s_addr, txt, 4);
847 af = AF_INET;
848
849 break;
850 default:
851 continue;
852 }
853
854 if (!(txt = inet_ntop(af, &ip, buf, sizeof buf)))
855 continue;
856
857 len = strlen(txt);
858
859 break;
860 default:
861 continue;
862 }
863
864 lua_pushstring(L, tag);
865 lua_pushlstring(L, txt, len);
866
867 break;
868 }
869
870 lua_pushinteger(L, i);
871 lua_replace(L, lua_upvalueindex(2));
872
873 return lua_gettop(L);
874} /* gn__next() */
875
876static int gn__pairs(lua_State *L) {
877 lua_settop(L, 1);
878 lua_pushinteger(L, 0);
879 lua_pushcclosure(L, &gn__next, 2);
880
881 return 1;
882} /* gn__pairs() */
883
884
885static int gn__gc(lua_State *L) {
886 GENERAL_NAMES **ud = luaL_checkudata(L, 1, X509_GENS_CLASS);
887
888 sk_GENERAL_NAME_pop_free(*ud, GENERAL_NAME_free);
889 *ud = NULL;
890
891 return 0;
892} /* gn__gc() */
893
894
895static const luaL_Reg gn_methods[] = {
896 { "add", &gn_add },
897 { NULL, NULL },
898};
899
900static const luaL_Reg gn_metatable[] = {
901 { "__pairs", &gn__pairs },
902 { "__gc", &gn__gc },
903 { NULL, NULL },
904};
905
906
907static const luaL_Reg gn_globals[] = {
908 { "new", &gn_new },
909 { "interpose", &gn_interpose },
910 { NULL, NULL },
911};
912
913int luaopen__openssl_x509_altname(lua_State *L) {
914 initall(L);
915
916 luaL_newlib(L, gn_globals);
917
918 return 1;
919} /* luaopen__openssl_x509_altname() */
920
921
922/*
668 * X509 - openssl.x509.cert 923 * X509 - openssl.x509.cert
669 * 924 *
670 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 925 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -1071,6 +1326,122 @@ static int xc_setSubject(lua_State *L) {
1071} /* xc_setSubject() */ 1326} /* xc_setSubject() */
1072 1327
1073 1328
1329static void xc_setCritical(X509 *crt, int nid, _Bool yes) {
1330 X509_EXTENSION *ext;
1331 int loc;
1332
1333 if ((loc = X509_get_ext_by_NID(crt, nid, -1)) >= 0
1334 && (ext = X509_get_ext(crt, loc)))
1335 X509_EXTENSION_set_critical(ext, yes);
1336} /* xc_setCritical() */
1337
1338
1339static _Bool xc_getCritical(X509 *crt, int nid) {
1340 X509_EXTENSION *ext;
1341 int loc;
1342
1343 if ((loc = X509_get_ext_by_NID(crt, nid, -1)) >= 0
1344 && (ext = X509_get_ext(crt, loc)))
1345 return X509_EXTENSION_get_critical(ext);
1346 else
1347 return 0;
1348} /* xc_getCritical() */
1349
1350
1351static int xc_getIssuerAlt(lua_State *L) {
1352 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1353 GENERAL_NAMES *gens;
1354
1355 if (!(gens = X509_get_ext_d2i(crt, NID_issuer_alt_name, 0, 0)))
1356 return 0;
1357
1358 gn_dup(L, gens);
1359
1360 return 1;
1361} /* xc_getIssuerAlt() */
1362
1363
1364static int xc_setIssuerAlt(lua_State *L) {
1365 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1366 GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
1367
1368 if (!X509_add1_ext_i2d(crt, NID_issuer_alt_name, gens, 0, X509V3_ADD_REPLACE))
1369 return throwssl(L, "x509.altname:setIssuerAlt");
1370
1371 lua_pushboolean(L, 1);
1372
1373 return 1;
1374} /* xc_setIssuerAlt() */
1375
1376
1377static int xc_getSubjectAlt(lua_State *L) {
1378 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1379 GENERAL_NAMES *gens;
1380
1381 if (!(gens = X509_get_ext_d2i(crt, NID_subject_alt_name, 0, 0)))
1382 return 0;
1383
1384 gn_dup(L, gens);
1385
1386 return 1;
1387} /* xc_getSubjectAlt() */
1388
1389
1390static int xc_setSubjectAlt(lua_State *L) {
1391 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1392 GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
1393
1394 if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, X509V3_ADD_REPLACE))
1395 return throwssl(L, "x509.altname:setSubjectAlt");
1396
1397 lua_pushboolean(L, 1);
1398
1399 return 1;
1400} /* xc_setSubjectAlt() */
1401
1402
1403static int xc_getIssuerAltCritical(lua_State *L) {
1404 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1405
1406 lua_pushboolean(L, xc_getCritical(crt, NID_issuer_alt_name));
1407
1408 return 1;
1409} /* xc_getIssuerAltCritical() */
1410
1411
1412static int xc_setIssuerAltCritical(lua_State *L) {
1413 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1414
1415 luaL_checkany(L, 2);
1416 xc_setCritical(crt, NID_issuer_alt_name, lua_toboolean(L, 2));
1417
1418 lua_pushboolean(L, 1);
1419
1420 return 1;
1421} /* xc_setIssuerAltCritical() */
1422
1423
1424static int xc_getSubjectAltCritical(lua_State *L) {
1425 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1426
1427 lua_pushboolean(L, xc_getCritical(crt, NID_subject_alt_name));
1428
1429 return 1;
1430} /* xc_getSubjectAltCritical() */
1431
1432
1433static int xc_setSubjectAltCritical(lua_State *L) {
1434 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1435
1436 luaL_checkany(L, 2);
1437 xc_setCritical(crt, NID_subject_alt_name, lua_toboolean(L, 2));
1438
1439 lua_pushboolean(L, 1);
1440
1441 return 1;
1442} /* xc_setSubjectAltCritical() */
1443
1444
1074static int xc__tostring(lua_State *L) { 1445static int xc__tostring(lua_State *L) {
1075 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 1446 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
1076 int fmt = luaL_checkoption(L, 2, "pem", (const char *[]){ "pem", 0 }); 1447 int fmt = luaL_checkoption(L, 2, "pem", (const char *[]){ "pem", 0 });
@@ -1110,18 +1481,26 @@ static int xc__gc(lua_State *L) {
1110 1481
1111 1482
1112static const luaL_Reg xc_methods[] = { 1483static const luaL_Reg xc_methods[] = {
1113 { "getVersion", &xc_getVersion }, 1484 { "getVersion", &xc_getVersion },
1114 { "setVersion", &xc_setVersion }, 1485 { "setVersion", &xc_setVersion },
1115 { "getSerial", &xc_getSerial }, 1486 { "getSerial", &xc_getSerial },
1116 { "setSerial", &xc_setSerial }, 1487 { "setSerial", &xc_setSerial },
1117 { "digest", &xc_digest }, 1488 { "digest", &xc_digest },
1118 { "getLifetime", &xc_getLifetime }, 1489 { "getLifetime", &xc_getLifetime },
1119 { "setLifetime", &xc_setLifetime }, 1490 { "setLifetime", &xc_setLifetime },
1120 { "getIssuer", &xc_getIssuer }, 1491 { "getIssuer", &xc_getIssuer },
1121 { "setIssuer", &xc_setIssuer }, 1492 { "setIssuer", &xc_setIssuer },
1122 { "getSubject", &xc_getSubject }, 1493 { "getSubject", &xc_getSubject },
1123 { "setSubject", &xc_setSubject }, 1494 { "setSubject", &xc_setSubject },
1124 { NULL, NULL }, 1495 { "getIssuerAlt", &xc_getIssuerAlt },
1496 { "setIssuerAlt", &xc_setIssuerAlt },
1497 { "getSubjectAlt", &xc_getSubjectAlt },
1498 { "setSubjectAlt", &xc_setSubjectAlt },
1499 { "getIssuerAltCritical", &xc_getIssuerAltCritical },
1500 { "setIssuerAltCritical", &xc_setIssuerAltCritical },
1501 { "getSubjectAltCritical", &xc_getSubjectAltCritical },
1502 { "setSubjectAltCritical", &xc_setSubjectAltCritical },
1503 { NULL, NULL },
1125}; 1504};
1126 1505
1127static const luaL_Reg xc_metatable[] = { 1506static const luaL_Reg xc_metatable[] = {
@@ -1152,6 +1531,7 @@ static void initall(lua_State *L) {
1152 1531
1153 addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); 1532 addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable);
1154 addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); 1533 addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable);
1534 addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable);
1155 addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable); 1535 addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable);
1156} /* initall() */ 1536} /* initall() */
1157 1537