]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/libsec/port/x509.c
import E script from bell labs
[plan9front.git] / sys / src / libsec / port / x509.c
index 9d10145b4c43cc7d1c256f40dd74ef966ba1b5fa..a6dc9e5d735821cf0a7a93efc7f9b69579bf0b26 100644 (file)
@@ -177,14 +177,13 @@ emalloc(int n)
 static char*
 estrdup(char *s)
 {
-       char *d, *d0;
+       char *d;
+       int n;
 
-       if(!s)
-               return 0;
-       d = d0 = emalloc(strlen(s)+1);
-       while(*d++ = *s++)
-               ;
-       return d0;
+       n = strlen(s)+1;
+       d = emalloc(n);
+       memmove(d, s, n);
+       return d;
 }
 
 
@@ -1287,6 +1286,8 @@ newbytes(int len)
 {
        Bytes* ans;
 
+       if(len < 0)
+               abort();
        ans = (Bytes*)emalloc(OFFSETOF(data[0], Bytes) + len);
        ans->len = len;
        return ans;
@@ -1308,8 +1309,7 @@ makebytes(uchar* buf, int len)
 static void
 freebytes(Bytes* b)
 {
-       if(b != nil)
-               free(b);
+       free(b);
 }
 
 /*
@@ -1347,6 +1347,8 @@ newints(int len)
 {
        Ints* ans;
 
+       if(len < 0 || len > ((uint)-1>>1)/sizeof(int))
+               abort();
        ans = (Ints*)emalloc(OFFSETOF(data[0], Ints) + len*sizeof(int));
        ans->len = len;
        return ans;
@@ -1358,16 +1360,14 @@ makeints(int* buf, int len)
        Ints* ans;
 
        ans = newints(len);
-       if(len > 0)
-               memmove(ans->data, buf, len*sizeof(int));
+       memmove(ans->data, buf, len*sizeof(int));
        return ans;
 }
 
 static void
 freeints(Ints* b)
 {
-       if(b != nil)
-               free(b);
+       free(b);
 }
 
 /* len is number of bytes */
@@ -1376,6 +1376,8 @@ newbits(int len)
 {
        Bits* ans;
 
+       if(len < 0)
+               abort();
        ans = (Bits*)emalloc(OFFSETOF(data[0], Bits) + len);
        ans->len = len;
        ans->unusedbits = 0;
@@ -1396,8 +1398,7 @@ makebits(uchar* buf, int len, int unusedbits)
 static void
 freebits(Bits* b)
 {
-       if(b != nil)
-               free(b);
+       free(b);
 }
 
 static Elist*
@@ -1471,15 +1472,13 @@ freevalfields(Value* v)
                el = v->u.seqval;
                for(l = el; l != nil; l = l->tl)
                        freevalfields(&l->hd.val);
-               if(el)
-                       freeelist(el);
+               freeelist(el);
                break;
        case VSet:
                el = v->u.setval;
                for(l = el; l != nil; l = l->tl)
                        freevalfields(&l->hd.val);
-               if(el)
-                       freeelist(el);
+               freeelist(el);
                break;
        }
 }
@@ -1669,15 +1668,12 @@ static DigestAlg *digestalg[NUMALGS+1] = {
 static void
 freecert(CertX509* c)
 {
-       if(!c) return;
-       if(c->issuer != nil)
-               free(c->issuer);
-       if(c->validity_start != nil)
-               free(c->validity_start);
-       if(c->validity_end != nil)
-               free(c->validity_end);
-       if(c->subject != nil)
-               free(c->subject);
+       if(c == nil)
+               return;
+       free(c->issuer);
+       free(c->validity_start);
+       free(c->validity_end);
+       free(c->subject);
        freebytes(c->publickey);
        freebytes(c->signature);
        free(c);
@@ -1925,12 +1921,10 @@ decode_rsapubkey(Bytes* a)
        if(mp == nil)
                goto errret;
 
-       if(l != nil)
-               freeelist(l);
+       freeelist(l);
        return key;
 errret:
-       if(l != nil)
-               freeelist(l);
+       freeelist(l);
        rsapubfree(key);
        return nil;
 }
@@ -2145,7 +2139,7 @@ asn1toDSApriv(uchar *kd, int kn)
  * Our ASN.1 library doesn't return pointers into the original
  * data array, so we need to do a little hand decoding.
  */
-static void
+static int
 digest_certinfo(Bytes *cert, DigestAlg *da, uchar *digest)
 {
        uchar *info, *p, *pend;
@@ -2161,19 +2155,20 @@ digest_certinfo(Bytes *cert, DigestAlg *da, uchar *digest)
           length_decode(&p, pend, &length) != ASN_OK ||
           p+length > pend ||
           p+length < p)
-               return;
+               return -1;
        info = p;
        if(ber_decode(&p, pend, &elem) != ASN_OK)
-               return;
+               return -1;
        freevalfields(&elem.val);
        if(elem.tag.num != SEQUENCE)
-               return;
+               return -1;
        infolen = p - info;
        (*da->fun)(info, infolen, digest, nil);
+       return da->len;
 }
 
 static char*
-verify_signature(Bytes* signature, RSApub *pk, uchar *edigest, Elem **psigalg)
+verify_signature(Bytes* signature, RSApub *pk, uchar *edigest, int edigestlen, Elem **psigalg)
 {
        Elem e;
        Elist *el;
@@ -2199,30 +2194,30 @@ verify_signature(Bytes* signature, RSApub *pk, uchar *edigest, Elem **psigalg)
                err = "expected 1";
                goto end;
        }
-       buf++;
-       while(buf[0] == 0xff)
-               buf++;
-       if(buf[0] != 0) {
+       buf++, buflen--;
+       while(buflen > 0 && buf[0] == 0xff)
+               buf++, buflen--;
+       if(buflen < 1 || buf[0] != 0) {
                err = "expected 0";
                goto end;
        }
-       buf++;
-       buflen -= buf-pkcs1buf;
+       buf++, buflen--;
        if(decode(buf, buflen, &e) != ASN_OK || !is_seq(&e, &el) || elistlen(el) != 2 ||
                        !is_octetstring(&el->tl->hd, &digest)) {
                err = "signature parse error";
                goto end;
        }
        *psigalg = &el->hd;
-       if(memcmp(digest->data, edigest, digest->len) == 0)
+       if(digest->len != edigestlen) {
+               err = "bad digest length";
                goto end;
-       err = "digests did not match";
+       }
+       if(constcmp(digest->data, edigest, edigestlen) != 0)
+               err = "digests did not match";
 
 end:
-       if(pkcs1 != nil)
-               mpfree(pkcs1);
-       if(pkcs1buf != nil)
-               free(pkcs1buf);
+       mpfree(pkcs1);
+       free(pkcs1buf);
        return err;
 }
 
@@ -2256,17 +2251,23 @@ X509verify(uchar *cert, int ncert, RSApub *pk)
        char *e;
        Bytes *b;
        CertX509 *c;
-       uchar digest[256];
+       int digestlen;
+       uchar digest[MAXdlen];
        Elem *sigalg;
 
        b = makebytes(cert, ncert);
        c = decode_cert(b);
-       if(c != nil)
-               digest_certinfo(b, digestalg[c->signature_alg], digest);
-       freebytes(b);
-       if(c == nil)
+       if(c == nil){
+               freebytes(b);
                return "cannot decode cert";
-       e = verify_signature(c->signature, pk, digest, &sigalg);
+       }
+       digestlen = digest_certinfo(b, digestalg[c->signature_alg], digest);
+       freebytes(b);
+       if(digestlen <= 0){
+               freecert(c);
+               return "cannot decode certinfo";
+       }
+       e = verify_signature(c->signature, pk, digest, digestlen, &sigalg);
        freecert(c);
        return e;
 }
@@ -2357,7 +2358,7 @@ mkutc(long t)
        e.tag.class = Universal;
        e.tag.num = UTCTime;
        e.val.tag = VString;
-       snprint(utc, 50, "%.2d%.2d%.2d%.2d%.2d%.2dZ",
+       snprint(utc, sizeof(utc), "%.2d%.2d%.2d%.2d%.2d%.2dZ",
                tm->year % 100, tm->mon+1, tm->mday, tm->hour, tm->min, tm->sec);
        e.val.u.stringval = estrdup(utc);
        return e;
@@ -2671,7 +2672,7 @@ X509dump(uchar *cert, int ncert)
        Bytes *b;
        CertX509 *c;
        RSApub *pk;
-       DigestAlg *da;
+       int digestlen;
        uchar digest[MAXdlen];
        Elem *sigalg;
 
@@ -2680,12 +2681,16 @@ X509dump(uchar *cert, int ncert)
        c = decode_cert(b);
        if(c == nil){
                freebytes(b);
-               print("cannot decode cert");
+               print("cannot decode cert\n");
                return;
        }
-       da = digestalg[c->signature_alg];
-       digest_certinfo(b, da, digest);
+       digestlen = digest_certinfo(b, digestalg[c->signature_alg], digest);
        freebytes(b);
+       if(digestlen <= 0){
+               freecert(c);
+               print("cannot decode certinfo\n");
+               return;
+       }
 
        print("serial %d\n", c->serial);
        print("issuer %s\n", c->issuer);
@@ -2694,8 +2699,8 @@ X509dump(uchar *cert, int ncert)
        pk = decode_rsapubkey(c->publickey);
        print("pubkey e=%B n(%d)=%B\n", pk->ek, mpsignif(pk->n), pk->n);
 
-       print("sigalg=%d digest=%.*H\n", c->signature_alg, da->len, digest);
-       e = verify_signature(c->signature, pk, digest, &sigalg);
+       print("sigalg=%d digest=%.*H\n", c->signature_alg, digestlen, digest);
+       e = verify_signature(c->signature, pk, digest, digestlen, &sigalg);
        if(e==nil){
                e = "nil (meaning ok)";
                print("sigalg=\n");