changes from plan 9. some clean-up.
diff --git a/src/libsec/port/decodepem.c b/src/libsec/port/decodepem.c index 194a455..a0b0094 100644 --- a/src/libsec/port/decodepem.c +++ b/src/libsec/port/decodepem.c
@@ -6,7 +6,7 @@ #define STRLEN(s) (sizeof(s)-1) uchar* -decodepem(char *s, char *type, int *len) +decodepem(char *s, char *type, int *len, char **news) { uchar *d; char *t, *e, *tt; @@ -44,6 +44,8 @@ return nil; } + if(news) + *news = tt+1; n = ((tt - t) * 6 + 7) / 8; d = malloc(n); if(d == nil){ @@ -59,3 +61,29 @@ *len = n; return d; } + +PEMChain* +decodepemchain(char *s, char *type) +{ + PEMChain *first = nil, *last = nil, *chp; + uchar *d; + char *e; + int n; + + e = strchr(s, '\0'); + while (s < e) { + d = decodepem(s, type, &n, &s); + if(d == nil) + break; + chp = malloc(sizeof(PEMChain)); + chp->next = nil; + chp->pem = d; + chp->pemlen = n; + if (first == nil) + first = chp; + else + last->next = chp; + last = chp; + } + return first; +}
diff --git a/src/libsec/port/md5pickle.c b/src/libsec/port/md5pickle.c index 5b353b5..012489a 100644 --- a/src/libsec/port/md5pickle.c +++ b/src/libsec/port/md5pickle.c
@@ -7,11 +7,12 @@ char *p; int m, n; - m = 4*9+4*((s->blen+3)/3); + m = 17+4*9+4*((s->blen+3)/3); p = malloc(m); if(p == nil) return p; - n = sprint(p, "%8.8ux %8.8ux %8.8ux %8.8ux ", + n = sprint(p, "%16.16llux %8.8ux %8.8ux %8.8ux %8.8ux ", + s->len, s->state[0], s->state[1], s->state[2], s->state[3]); enc64(p+n, m-n, s->buf, s->blen); @@ -26,6 +27,7 @@ s = malloc(sizeof(*s)); if(s == nil) return nil; + s->len = strtoull(p, &p, 16); s->state[0] = strtoul(p, &p, 16); s->state[1] = strtoul(p, &p, 16); s->state[2] = strtoul(p, &p, 16);
diff --git a/src/libsec/port/readcert.c b/src/libsec/port/readcert.c index 9ba801f..b8ddf6d 100644 --- a/src/libsec/port/readcert.c +++ b/src/libsec/port/readcert.c
@@ -40,7 +40,7 @@ werrstr("can't read %s", filename); return nil; } - binary = decodepem(pem, "CERTIFICATE", pcertlen); + binary = decodepem(pem, "CERTIFICATE", pcertlen, nil); free(pem); if(binary == nil){ werrstr("can't parse %s", filename); @@ -49,3 +49,19 @@ return binary; } + +PEMChain * +readcertchain(char *filename) +{ + char *chfile; + PEMChain *chp; + + chfile = readfile(filename); + if (chfile == nil) { + werrstr("can't read %s", filename); + return nil; + } + chp = decodepemchain(chfile, "CERTIFICATE"); + return chp; +} +
diff --git a/src/libsec/port/tlshand.c b/src/libsec/port/tlshand.c index 68c9808..47d0f80 100644 --- a/src/libsec/port/tlshand.c +++ b/src/libsec/port/tlshand.c
@@ -248,7 +248,7 @@ CompressionNull, }; -static TlsConnection *tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...)); +static TlsConnection *tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...), PEMChain *chain); static TlsConnection *tlsClient2(int ctl, int hand, uchar *csid, int ncsid, int (*trace)(char*fmt, ...)); static void msgClear(Msg *m); @@ -273,7 +273,7 @@ static int tlsSecSecretc(TlsSec *sec, uchar *sid, int nsid, uchar *srandom, uchar *cert, int ncert, int vers, uchar **epm, int *nepm, uchar *kd, int nkd); static int tlsSecFinished(TlsSec *sec, MD5state md5, SHAstate sha1, uchar *fin, int nfin, int isclient); static void tlsSecOk(TlsSec *sec); -static void tlsSecKill(TlsSec *sec); +/* static void tlsSecKill(TlsSec *sec); */ static void tlsSecClose(TlsSec *sec); static void setMasterSecret(TlsSec *sec, Bytes *pm); static void serverMasterSecret(TlsSec *sec, uchar *epm, int nepm); @@ -296,14 +296,14 @@ static void put32(uchar *p, u32int); static void put24(uchar *p, int); static void put16(uchar *p, int); -static u32int get32(uchar *p); +/* static u32int get32(uchar *p); */ static int get24(uchar *p); static int get16(uchar *p); static Bytes* newbytes(int len); static Bytes* makebytes(uchar* buf, int len); static void freebytes(Bytes* b); static Ints* newints(int len); -static Ints* makeints(int* buf, int len); +/* static Ints* makeints(int* buf, int len); */ static void freeints(Ints* b); //================= client/server ======================== @@ -337,7 +337,7 @@ return -1; } fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion); - tls = tlsServer2(ctl, hand, conn->cert, conn->certlen, conn->trace); + tls = tlsServer2(ctl, hand, conn->cert, conn->certlen, conn->trace, conn->chain); sprint(dname, "#a/tls/%s/data", buf); data = open(dname, ORDWR); close(fd); @@ -412,15 +412,27 @@ return data; } +static int +countchain(PEMChain *p) +{ + int i = 0; + + while (p) { + i++; + p = p->next; + } + return i; +} + static TlsConnection * -tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...)) +tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...), PEMChain *chp) { TlsConnection *c; Msg m; Bytes *csid; uchar sid[SidSize], kd[MaxKeyData]; char *secrets; - int cipher, compressor, nsid, rv; + int cipher, compressor, nsid, rv, numcerts, i; if(trace) trace("tlsServer2\n"); @@ -498,9 +510,12 @@ msgClear(&m); m.tag = HCertificate; - m.u.certificate.ncert = 1; + numcerts = countchain(chp); + m.u.certificate.ncert = 1 + numcerts; m.u.certificate.certs = emalloc(m.u.certificate.ncert * sizeof(Bytes)); m.u.certificate.certs[0] = makebytes(cert, ncert); + for (i = 0; i < numcerts && chp; i++, chp = chp->next) + m.u.certificate.certs[i+1] = makebytes(chp->pem, chp->pemlen); if(!msgSend(c, &m, AQueue)) goto Err; msgClear(&m); @@ -1824,6 +1839,7 @@ sec->ok = 1; } +/* static void tlsSecKill(TlsSec *sec) { @@ -1832,6 +1848,7 @@ factotum_rsa_close(sec->rpc); sec->ok = -1; } +*/ static void tlsSecClose(TlsSec *sec) @@ -2205,11 +2222,13 @@ p[1] = x; } +/* static u32int get32(uchar *p) { return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; } +*/ static int get24(uchar *p) @@ -2272,6 +2291,7 @@ return ans; } +/* static Ints* makeints(int* buf, int len) { @@ -2282,6 +2302,7 @@ memmove(ans->data, buf, len*sizeof(int)); return ans; } +*/ static void freeints(Ints* b)
diff --git a/src/libsec/port/x509.c b/src/libsec/port/x509.c index 838c8b4..a37b64a 100644 --- a/src/libsec/port/x509.c +++ b/src/libsec/port/x509.c
@@ -134,8 +134,10 @@ static int is_string(Elem* pe, char** pstring); static int is_time(Elem* pe, char** ptime); static int decode(uchar* a, int alen, Elem* pelem); +/* static int decode_seq(uchar* a, int alen, Elist** pelist); static int decode_value(uchar* a, int alen, int kind, int isconstr, Value* pval); +*/ static int encode(Elem e, Bytes** pbytes); static int oid_lookup(Ints* o, Ints** tab); static void freevalfields(Value* v); @@ -206,7 +208,7 @@ /* * Like decode, but continue decoding after first element * of array ends. - */ + * static int decode_seq(uchar* a, int alen, Elist** pelist) { @@ -214,6 +216,7 @@ return seq_decode(&p, &a[alen], -1, 1, pelist); } +*/ /* * Decode the whole array as a BER encoding of an ASN1 value, @@ -223,7 +226,7 @@ * If there's an error, the return string will contain the error. * Depending on the error, the returned value may or may not * be nil. - */ + * static int decode_value(uchar* a, int alen, int kind, int isconstr, Value* pval) { @@ -231,6 +234,7 @@ return value_decode(&p, &a[alen], alen, kind, isconstr, pval); } +*/ /* * All of the following decoding routines take arguments: @@ -1585,12 +1589,12 @@ static Ints7 oid_sha1WithRSAEncryption ={7, 1, 2, 840, 113549, 1, 1, 5 }; static Ints7 oid_md5 ={6, 1, 2, 840, 113549, 2, 5, 0 }; static Ints *alg_oid_tab[NUMALGS+1] = { - (Ints*)&oid_rsaEncryption, - (Ints*)&oid_md2WithRSAEncryption, - (Ints*)&oid_md4WithRSAEncryption, - (Ints*)&oid_md5WithRSAEncryption, - (Ints*)&oid_sha1WithRSAEncryption, - (Ints*)&oid_md5, + (Ints*)(void*)&oid_rsaEncryption, + (Ints*)(void*)&oid_md2WithRSAEncryption, + (Ints*)(void*)&oid_md4WithRSAEncryption, + (Ints*)(void*)&oid_md5WithRSAEncryption, + (Ints*)(void*)&oid_sha1WithRSAEncryption, + (Ints*)(void*)&oid_md5, nil }; static DigestFun digestalg[NUMALGS+1] = { md5, md5, md5, md5, sha1, md5, 0 };