summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Ahern <william@server.local>2012-10-02 17:10:16 -0700
committerWilliam Ahern <william@server.local>2012-10-02 17:10:16 -0700
commitee1f51dd7a1aaa12e0857a698ac99a5d55c897f0 (patch)
tree0e8e464f2853c910aa7b0f41dc916a7cbf7a74cf
parentbc29b5bd1989ae5c222c18d0e124f50b5dcb400d (diff)
downloadluaossl-ee1f51dd7a1aaa12e0857a698ac99a5d55c897f0.tar.gz
luaossl-ee1f51dd7a1aaa12e0857a698ac99a5d55c897f0.tar.bz2
luaossl-ee1f51dd7a1aaa12e0857a698ac99a5d55c897f0.zip
-n
commit lots of time conversion work
-rw-r--r--openssl.c288
1 files changed, 240 insertions, 48 deletions
diff --git a/openssl.c b/openssl.c
index 949176a..2c4c032 100644
--- a/openssl.c
+++ b/openssl.c
@@ -28,12 +28,14 @@
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 <math.h> /* fabs(3) floor(3) round(3) isfinite(3) */ 31#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) */
32 33
33#include <openssl/err.h> 34#include <openssl/err.h>
34#include <openssl/bn.h> 35#include <openssl/bn.h>
35#include <openssl/x509.h> 36#include <openssl/x509.h>
36#include <openssl/x509v3.h> 37#include <openssl/x509v3.h>
38#include <openssl/evp.h>
37 39
38#include <lua.h> 40#include <lua.h>
39#include <lualib.h> 41#include <lualib.h>
@@ -48,6 +50,8 @@
48#define countof(a) (sizeof (a) / sizeof *(a)) 50#define countof(a) (sizeof (a) / sizeof *(a))
49#define endof(a) (&(a)[countof(a)]) 51#define endof(a) (&(a)[countof(a)])
50 52
53#define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i))
54
51 55
52static void *prepudata(lua_State *L, const char *tname, size_t size) { 56static void *prepudata(lua_State *L, const char *tname, size_t size) {
53 void *p = memset(lua_newuserdata(L, size), 0, size); 57 void *p = memset(lua_newuserdata(L, size), 0, size);
@@ -124,10 +128,24 @@ static BIGNUM *bn_push(lua_State *L) {
124} /* bn_push() */ 128} /* bn_push() */
125 129
126 130
131#define checkbig_(a, b, c, ...) checkbig((a), (b), (c))
132#define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 })
133
134static BIGNUM *(checkbig)(lua_State *, int, _Bool *);
135
127static int bn_new(lua_State *L) { 136static int bn_new(lua_State *L) {
128 bn_push(L); 137 int i, n;
129 138
130 return 1; 139 if ((n = lua_gettop(L)) > 0) {
140 for (i = 1; i <= n; i++)
141 checkbig(L, i);
142
143 return n;
144 } else {
145 bn_push(L);
146
147 return 1;
148 }
131} /* bn_new() */ 149} /* bn_new() */
132 150
133 151
@@ -204,7 +222,7 @@ static _Bool f2bn(BIGNUM **bn, double f) {
204} /* f2bn() */ 222} /* f2bn() */
205 223
206 224
207static BIGNUM *checkbig(lua_State *L, int index, _Bool *lvalue) { 225static BIGNUM *(checkbig)(lua_State *L, int index, _Bool *lvalue) {
208 BIGNUM **bn; 226 BIGNUM **bn;
209 const char *dec; 227 const char *dec;
210 size_t len; 228 size_t len;
@@ -385,6 +403,15 @@ static int bn__pow(lua_State *L) {
385} /* bn__pow() */ 403} /* bn__pow() */
386 404
387 405
406static int bn__unm(lua_State *L) {
407 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS);
408
409 BN_set_negative(a, !BN_is_negative(a));
410
411 return 1;
412} /* bn__unm() */
413
414
388static int bn__eq(lua_State *L) { 415static int bn__eq(lua_State *L) {
389 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS); 416 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS);
390 BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS); 417 BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS);
@@ -451,6 +478,7 @@ static const luaL_Reg bn_metatable[] = {
451 { "__div", &bn__div }, 478 { "__div", &bn__div },
452 { "__mod", &bn__mod }, 479 { "__mod", &bn__mod },
453 { "__pow", &bn__pow }, 480 { "__pow", &bn__pow },
481 { "__unm", &bn__unm },
454 { "__eq", &bn__eq }, 482 { "__eq", &bn__eq },
455 { "__lt", &bn__lt }, 483 { "__lt", &bn__lt },
456 { "__le", &bn__le }, 484 { "__le", &bn__le },
@@ -622,12 +650,12 @@ static int xc_setVersion(lua_State *L) {
622 650
623static int xc_getSerialNumber(lua_State *L) { 651static int xc_getSerialNumber(lua_State *L) {
624 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 652 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
625 BIGNUM *srl = bn_push(L); 653 BIGNUM *serial = bn_push(L);
626 ASN1_INTEGER *num; 654 ASN1_INTEGER *i;
627 655
628 if ((num = X509_get_serialNumber(crt))) { 656 if ((i = X509_get_serialNumber(crt))) {
629 if (!ASN1_INTEGER_to_BN(num, srl)) 657 if (!ASN1_INTEGER_to_BN(i, serial))
630 return throwssl(L, "x509.cert.getSerialNumber"); 658 return throwssl(L, "x509.cert:getSerialNumber");
631 } 659 }
632 660
633 return 1; 661 return 1;
@@ -636,69 +664,233 @@ static int xc_getSerialNumber(lua_State *L) {
636 664
637static int xc_setSerialNumber(lua_State *L) { 665static int xc_setSerialNumber(lua_State *L) {
638 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 666 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
639 ASN1_INTEGER *srl = NULL; 667 ASN1_INTEGER *serial;
640 int ok;
641
642 luaL_checkany(L, 2);
643
644 if (lua_isstring(L, 2)) {
645 BIGNUM *num = NULL;
646
647 if (!BN_dec2bn(&num, lua_tostring(L, 2)))
648 goto error;
649 668
650 if (!(srl = ASN1_INTEGER_new()) || !(BN_to_ASN1_INTEGER(num, srl))) 669 if (!(serial = BN_to_ASN1_INTEGER(checkbig(L, 2), NULL)))
651 goto error; 670 goto error;
652 671
653 ok = X509_set_serialNumber(crt, srl); 672 if (!X509_set_serialNumber(crt, serial))
654 ASN1_INTEGER_free(srl); 673 goto error;
655 674
656 if (!ok) 675 ASN1_INTEGER_free(serial);
657 goto error;
658 } else {
659 BIGNUM *num = checksimple(L, 2, BIGNUM_CLASS);
660
661 if (!(srl = ASN1_INTEGER_new()) || !(BN_to_ASN1_INTEGER(num, srl)))
662 goto error;
663
664 ok = X509_set_serialNumber(crt, srl);
665 ASN1_INTEGER_free(srl);
666
667 if (!ok)
668 goto error;
669 }
670 676
671 lua_pushboolean(L, 1); 677 lua_pushboolean(L, 1);
672 678
673 return 1; 679 return 1;
674error: 680error:
675 return throwssl(L, "x509.cert.setSerialNumber"); 681 ASN1_INTEGER_free(serial);
682
683 return throwssl(L, "x509.cert:setSerialNumber");
676} /* xc_setSerialNumber() */ 684} /* xc_setSerialNumber() */
677 685
678 686
679#if 0
680static int xc_digest(lua_State *L) { 687static int xc_digest(lua_State *L) {
681 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 688 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
682 const char *type = luaL_optstring(L, 2, "sha1"); 689 const char *type = luaL_optstring(L, 2, "sha1");
683 const EVP_MD *dgst; 690 int format = luaL_checkoption(L, 3, "*s", (const char *[]){ "*s", "*x", "*n", NULL });
691 const EVP_MD *ctx;
684 unsigned char md[EVP_MAX_MD_SIZE]; 692 unsigned char md[EVP_MAX_MD_SIZE];
685 unsigned int len; 693 unsigned len;
694
695 lua_settop(L, 3); /* self, type, hex */
686 696
687 if (!(dgst = EVP_getdigestbyname(type))) 697 if (!(ctx = EVP_get_digestbyname(type)))
688 return luaL_error(L, "x509.cert:digest: %s: invalid digest type", type); 698 return luaL_error(L, "x509.cert:digest: %s: invalid digest type", type);
689 699
690 X509_digest(crt, dgst, md, &len); 700 X509_digest(crt, ctx, md, &len);
701
702 switch (format) {
703 case 2: {
704 BIGNUM *bn = bn_push(L);
705
706 if (!BN_bin2bn(md, len, bn))
707 return throwssl(L, "x509.cert:digest");
708
709 break;
710 }
711 case 1: {
712 static const unsigned char x[16] = "0123456789abcdef";
713 luaL_Buffer B;
714
715 luaL_buffinitsize(L, &B, 2 * len);
716
717 for (unsigned i = 0; i < len; i++) {
718 luaL_addchar(&B, x[0x0f & (md[i] >> 4)]);
719 luaL_addchar(&B, x[0x0f & (md[i] >> 0)]);
720 }
721
722 luaL_pushresult(&B);
691 723
692 lua_pushlstring(L, md, len); 724 break;
725 }
726 default:
727 lua_pushlstring(L, (const char *)md, len);
728
729 break;
730 } /* switch() */
693 731
694 return 1; 732 return 1;
695} /* xc_digest() */ 733} /* xc_digest() */
696#endif
697 734
698static int xc_lifetime(lua_State *L) { 735
736static _Bool isleap(int year) {
737 if (year >= 0)
738 return !(year % 4) && ((year % 100) || !(year % 400));
739 else
740 return isleap(-(year + 1));
741} /* isleap() */
742
743
744static int yday(int year, int mon, int mday) {
745 static const int past[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
746 int yday = past[CLAMP(mon, 0, 11)] + CLAMP(mday, 1, 31) - 1;
747
748 return yday + (isleap(year) && mon > 1);
749} /* yday() */
750
751
752static int leaps(int year) {
753 if (year >= 0)
754 return (year / 400) + (year / 4) - (year / 100);
755 else
756 return -(leaps(-(year + 1)) + 1);
757} /* leaps() */
758
759
760static _Bool scan(int *i, char **cp, int n, int signok) {
761 int sign = 1;
762
763 *i = 0;
764
765 if (signok) {
766 if (**cp == '-') {
767 sign = -1;
768 ++*cp;
769 } else if (**cp == '+') {
770 ++*cp;
771 }
772 }
773
774 while (n-- > 0) {
775 if (**cp < '0' || **cp > '9')
776 return 0;
777
778 *i *= 10;
779 *i += *(*cp)++ - '0';
780 }
781
782 *i *= sign;
783
784 return 1;
785} /* scan() */
786
787
788static double timeutc(ASN1_TIME *time) {
789 char buf[32] = "", *cp;
790 struct tm tm;
791 int gmtoff, year, i;
792 double ts;
793
794 if (!ASN1_TIME_check(time))
795 return 0;
796
797 cp = strncpy(buf, (const char *)ASN1_STRING_data((ASN1_STRING *)time), sizeof buf - 1);
798
799 if (ASN1_STRING_type(time) == V_ASN1_GENERALIZEDTIME) {
800 if (!scan(&year, &cp, 4, 1))
801 goto badfmt;
802 } else {
803 if (!scan(&year, &cp, 2, 0))
804 goto badfmt;
805 year += (year < 50)? 2000 : 1999;
806 }
807
808 tm.tm_year = year - 1900;
809
810 if (!scan(&i, &cp, 2, 0))
811 goto badfmt;
812
813 tm.tm_mon = CLAMP(i, 1, 12) - 1;
814
815 if (!scan(&i, &cp, 2, 0))
816 goto badfmt;
817
818 tm.tm_mday = CLAMP(i, 1, 31);
819
820 tm.tm_yday = yday(year, tm.tm_mon, tm.tm_mday);
821
822 if (!scan(&i, &cp, 2, 0))
823 goto badfmt;
824
825 tm.tm_hour = CLAMP(i, 0, 23);
826
827 if (!scan(&i, &cp, 2, 0))
828 goto badfmt;
829
830 tm.tm_min = CLAMP(i, 0, 59);
831
832 if (*cp >= '0' && *cp <= '9') {
833 if (!scan(&i, &cp, 2, 0))
834 goto badfmt;
835
836 tm.tm_sec = CLAMP(i, 0, 59);
837 }
838
839 if (*cp == '+' || *cp == '-') {
840 int sign = (*cp++ == '-')? -1 : 1;
841 int hh, mm;
842
843 if (!scan(&hh, &cp, 2, 0) || !scan(&mm, &cp, 2, 0))
844 goto badfmt;
845
846 gmtoff = (CLAMP(hh, 0, 23) * 3600)
847 + (CLAMP(mm, 0, 59) * 60);
848
849 gmtoff *= sign;
850 }
851
852 ts = 86400.0 * 365.0 * (year - 1970);
853 ts += 86400.0 * (leaps(year - 1) - leaps(1969));
854 ts += 86400 * tm.tm_yday;
855 ts += 3600 * tm.tm_hour;
856 ts += 60 * tm.tm_min;
857 ts += tm.tm_sec;
858 ts += (year < 1970)? gmtoff : -gmtoff;
859
860 return ts;
861badfmt:
862 return INFINITY;
863} /* timeutc() */
864
865
866static int xc_getLifetime(lua_State *L) {
699 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 867 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
700 return 0; 868 double begin = INFINITY, end = INFINITY;
701} /* xc_lifetime() */ 869 ASN1_TIME *time;
870
871 if ((time = X509_get_notBefore(crt)))
872 begin = timeutc(time);
873
874 if ((time = X509_get_notAfter(crt)))
875 end = timeutc(time);
876
877 if (isfinite(begin))
878 lua_pushnumber(L, begin);
879 else
880 lua_pushnil(L);
881
882 if (isfinite(end))
883 lua_pushnumber(L, end);
884 else
885 lua_pushnil(L);
886
887 if (isfinite(begin) && isfinite(end) && begin <= end)
888 lua_pushnumber(L, fabs(end - begin));
889 else
890 lua_pushnumber(L, 0.0);
891
892 return 3;
893} /* xc_getLifetime() */
702 894
703 895
704static int xc_issuer(lua_State *L) { 896static int xc_issuer(lua_State *L) {