ref: ce450582513dcea0d8f7b721ab693b954332f5ba
parent: 7ac6345a64f3b32ed61519cd15a81d1faf7d379f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Dec 29 22:28:56 EST 2017
libsec: keep in sync with 9front
--- a/libsec/thumb.c
+++ b/libsec/thumb.c
@@ -66,6 +66,11 @@
if(okThumbprint(hash, SHA2_256dlen, table))
return 1;
+ if(X509digestSPKI(cert, len, sha2_256, hash) < 0)
+ return 0;
+ if(okThumbprint(hash, SHA2_256dlen, table))
+ return 1;
+
len = enc64(thumb, sizeof(thumb), hash, SHA2_256dlen);
while(len > 0 && thumb[len-1] == '=')
len--;
--- a/libsec/x509.c
+++ b/libsec/x509.c
@@ -1474,8 +1474,7 @@
freeints(v->u.objidval);
break;
case VString:
- if(v->u.stringval)
- free(v->u.stringval);
+ free(v->u.stringval);
break;
case VSeq:
el = v->u.seqval;
@@ -1490,6 +1489,7 @@
freeelist(el);
break;
}
+ memset(v, 0, sizeof(*v));
}
static mpint*
@@ -1585,9 +1585,9 @@
char* validity_end;
char* subject;
int publickey_alg;
- Bytes* publickey;
+ Bits* publickey;
int signature_alg;
- Bytes* signature;
+ Bits* signature;
int curve;
} CertX509;
@@ -1733,8 +1733,8 @@
free(c->validity_start);
free(c->validity_end);
free(c->subject);
- freebytes(c->publickey);
- freebytes(c->signature);
+ freebits(c->publickey);
+ freebits(c->signature);
free(c);
}
@@ -1827,11 +1827,10 @@
}
static CertX509*
-decode_cert(Bytes* a)
+decode_cert(uchar *buf, int len)
{
int ok = 0;
int n;
- CertX509* c = nil;
Elem ecert;
Elem* ecertinfo;
Elem* esigalg;
@@ -1849,8 +1848,9 @@
Bits* bits = nil;
Bytes* b;
Elem* e;
+ CertX509* c = nil;
- if(decode(a->data, a->len, &ecert) != ASN_OK)
+ if(decode(buf, len, &ecert) != ASN_OK)
goto errret;
c = (CertX509*)emalloc(sizeof(CertX509));
@@ -1942,18 +1942,19 @@
if(c->curve < 0)
goto errret;
}
- if(!is_bitstring(&elpubkey->tl->hd, &bits))
+ elpubkey = elpubkey->tl;
+ if(!is_bitstring(&elpubkey->hd, &bits))
goto errret;
- if(bits->unusedbits != 0)
- goto errret;
- c->publickey = makebytes(bits->data, bits->len);
+ elpubkey->hd.val.u.bitstringval = nil; /* transfer ownership */
+ c->publickey = bits;
/*resume Certificate */
if(c->signature_alg < 0)
goto errret;
- if(!is_bitstring(esig, &bits))
+ if(!is_bitstring(esig, &bits))
goto errret;
- c->signature = makebytes(bits->data, bits->len);
+ esig->val.u.bitstringval = nil; /* transfer ownership */
+ c->signature = bits;
ok = 1;
errret:
@@ -2000,12 +2001,6 @@
}
-static RSApub*
-decode_rsapubkey(Bytes* a)
-{
- return asn1toRSApub(a->data, a->len);
-}
-
/*
* RSAPrivateKey ::= SEQUENCE {
* version Version,
@@ -2018,16 +2013,16 @@
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER -- (inverse of q) mod p }
*/
-static RSApriv*
-decode_rsaprivkey(Bytes* a)
+RSApriv*
+asn1toRSApriv(uchar *buf, int len)
{
int version;
Elem e;
Elist *el;
- RSApriv* key;
+ Bytes *b;
+ RSApriv* key = nil;
- key = nil;
- if(decode(a->data, a->len, &e) != ASN_OK)
+ if(decode(buf, len, &e) != ASN_OK)
goto errret;
if(!is_seq(&e, &el))
goto errret;
@@ -2038,8 +2033,8 @@
if(elistlen(el) != 9){
if(elistlen(el) == 3
&& parse_alg(&el->tl->hd) == ALG_rsaEncryption
- && is_octetstring(&el->tl->tl->hd, &a)){
- key = decode_rsaprivkey(a);
+ && is_octetstring(&el->tl->tl->hd, &b)){
+ key = asn1toRSApriv(b->data, b->len);
if(key != nil)
goto done;
}
@@ -2098,16 +2093,15 @@
* priv_key INTEGER, -- secret
* }
*/
-static DSApriv*
-decode_dsaprivkey(Bytes* a)
+DSApriv*
+asn1toDSApriv(uchar *buf, int len)
{
int version;
Elem e;
Elist *el;
- DSApriv* key;
+ DSApriv* key = nil;
- key = dsaprivalloc();
- if(decode(a->data, a->len, &e) != ASN_OK)
+ if(decode(buf, len, &e) != ASN_OK)
goto errret;
if(!is_seq(&e, &el) || elistlen(el) != 6)
goto errret;
@@ -2115,6 +2109,7 @@
if(!is_int(&el->hd, &version) || version != 0)
goto errret;
+ key = dsaprivalloc();
el = el->tl;
if((key->pub.p = asn1mpint(&el->hd)) == nil)
goto errret;
@@ -2143,30 +2138,6 @@
return nil;
}
-RSApriv*
-asn1toRSApriv(uchar *kd, int kn)
-{
- Bytes *b;
- RSApriv *key;
-
- b = makebytes(kd, kn);
- key = decode_rsaprivkey(b);
- freebytes(b);
- return key;
-}
-
-DSApriv*
-asn1toDSApriv(uchar *kd, int kn)
-{
- Bytes *b;
- DSApriv *key;
-
- b = makebytes(kd, kn);
- key = decode_dsaprivkey(b);
- freebytes(b);
- return key;
-}
-
/*
* digest(CertificateInfo)
* Our ASN.1 library doesn't return pointers into the original
@@ -2173,16 +2144,15 @@
* data array, so we need to do a little hand decoding.
*/
static int
-digest_certinfo(Bytes *cert, DigestAlg *da, uchar *digest)
+digest_certinfo(uchar *cert, int ncert, DigestAlg *da, uchar *digest)
{
uchar *info, *p, *pend;
- ulong infolen;
int isconstr, length;
Tag tag;
Elem elem;
- p = cert->data;
- pend = cert->data + cert->len;
+ p = cert;
+ pend = cert + ncert;
if(tag_decode(&p, pend, &tag, &isconstr) != ASN_OK ||
tag.class != Universal || tag.num != SEQUENCE ||
length_decode(&p, pend, &length) != ASN_OK ||
@@ -2195,8 +2165,7 @@
freevalfields(&elem.val);
if(elem.tag.num != SEQUENCE)
return -1;
- infolen = p - info;
- (*da->fun)(info, infolen, digest, nil);
+ (*da->fun)(info, p - info, digest, nil);
return da->len;
}
@@ -2320,27 +2289,32 @@
return err;
}
+static void
+copysubject(char *name, int nname, char *subject)
+{
+ char *e;
+
+ if(name == nil)
+ return;
+ memset(name, 0, nname);
+ if(subject == nil)
+ return;
+ strncpy(name, subject, nname-1);
+ e = strchr(name, ',');
+ if(e != nil)
+ *e = 0; /* take just CN part of Distinguished Name */
+}
+
ECpub*
X509toECpub(uchar *cert, int ncert, char *name, int nname, ECdomain *dom)
{
CertX509 *c;
ECpub *pub;
- Bytes *b;
- if(name != nil)
- memset(name, 0, nname);
-
- b = makebytes(cert, ncert);
- c = decode_cert(b);
- freebytes(b);
+ c = decode_cert(cert, ncert);
if(c == nil)
return nil;
- if(name != nil && c->subject != nil){
- char *e = strchr(c->subject, ',');
- if(e != nil)
- *e = 0; /* take just CN part of Distinguished Name */
- strncpy(name, c->subject, nname);
- }
+ copysubject(name, nname, c->subject);
pub = nil;
if(c->publickey_alg == ALG_ecPublicKey){
ecdominit(dom, namedcurves[c->curve]);
@@ -2356,19 +2330,14 @@
X509ecdsaverify(uchar *cert, int ncert, ECdomain *dom, ECpub *pk)
{
char *e;
- Bytes *b;
CertX509 *c;
int digestlen;
uchar digest[MAXdlen];
- b = makebytes(cert, ncert);
- c = decode_cert(b);
- if(c == nil){
- freebytes(b);
+ c = decode_cert(cert, ncert);
+ if(c == nil)
return "cannot decode cert";
- }
- digestlen = digest_certinfo(b, digestalg[c->signature_alg], digest);
- freebytes(b);
+ digestlen = digest_certinfo(cert, ncert, digestalg[c->signature_alg], digest);
if(digestlen <= 0){
freecert(c);
return "cannot decode certinfo";
@@ -2381,27 +2350,16 @@
RSApub*
X509toRSApub(uchar *cert, int ncert, char *name, int nname)
{
- Bytes *b;
CertX509 *c;
RSApub *pub;
- if(name != nil)
- memset(name, 0, nname);
-
- b = makebytes(cert, ncert);
- c = decode_cert(b);
- freebytes(b);
+ c = decode_cert(cert, ncert);
if(c == nil)
return nil;
- if(name != nil && c->subject != nil){
- char *e = strchr(c->subject, ',');
- if(e != nil)
- *e = 0; /* take just CN part of Distinguished Name */
- strncpy(name, c->subject, nname);
- }
+ copysubject(name, nname, c->subject);
pub = nil;
if(c->publickey_alg == ALG_rsaEncryption)
- pub = decode_rsapubkey(c->publickey);
+ pub = asn1toRSApub(c->publickey->data, c->publickey->len);
freecert(c);
return pub;
}
@@ -2410,19 +2368,14 @@
X509rsaverify(uchar *cert, int ncert, RSApub *pk)
{
char *e;
- Bytes *b;
CertX509 *c;
int digestlen;
uchar digest[MAXdlen];
- b = makebytes(cert, ncert);
- c = decode_cert(b);
- if(c == nil){
- freebytes(b);
+ c = decode_cert(cert, ncert);
+ if(c == nil)
return "cannot decode cert";
- }
- digestlen = digest_certinfo(b, digestalg[c->signature_alg], digest);
- freebytes(b);
+ digestlen = digest_certinfo(cert, ncert, digestalg[c->signature_alg], digest);
if(digestlen <= 0){
freecert(c);
return "cannot decode certinfo";
@@ -2643,20 +2596,14 @@
static Bytes*
encode_digest(DigestAlg *da, uchar *digest)
{
- Bytes *ans;
- int err;
- Elem e;
-
- e = mkseq(
+ Bytes *b = nil;
+ Elem e = mkseq(
mkel(mkalg(da->alg),
mkel(mkoctet(digest, da->len),
nil)));
- err = encode(e, &ans);
+ encode(e, &b);
freevalfields(&e.val);
- if(err != ASN_OK)
- return nil;
-
- return ans;
+ return b;
}
int
@@ -2875,12 +2822,10 @@
free(buf);
if(encode(e, &certbytes) != ASN_OK)
goto errret;
- if(certlen)
+ if(certlen != nil)
*certlen = certbytes->len;
- cert = malloc(certbytes->len);
- if(cert != nil)
- memmove(cert, certbytes->data, certbytes->len);
- freebytes(certbytes);
+ cert = (uchar*)certbytes;
+ memmove(cert, certbytes->data, certbytes->len);
errret:
freevalfields(&e.val);
free(subj);
@@ -2942,12 +2887,10 @@
free(buf);
if(encode(e, &certbytes) != ASN_OK)
goto errret;
- if(certlen)
+ if(certlen != nil)
*certlen = certbytes->len;
- cert = malloc(certbytes->len);
- if(cert != nil)
- memmove(cert, certbytes->data, certbytes->len);
- freebytes(certbytes);
+ cert = (uchar*)certbytes;
+ memmove(cert, certbytes->data, certbytes->len);
errret:
freevalfields(&e.val);
free(subj);
@@ -2954,6 +2897,32 @@
return cert;
}
+static void
+digestSPKI(int alg, uchar *pubkey, int npubkey, DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest)
+{
+ Bytes *b = nil;
+ Elem e = mkseq(mkel(mkalg(alg), mkel(mkbits(pubkey, npubkey), nil)));
+ encode(e, &b);
+ freevalfields(&e.val);
+ (*fun)(b->data, b->len, digest, nil);
+ freebytes(b);
+}
+
+int
+X509digestSPKI(uchar *cert, int ncert, DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest)
+{
+ CertX509 *c;
+
+ c = decode_cert(cert, ncert);
+ if(c == nil){
+ werrstr("cannot decode cert");
+ return -1;
+ }
+ digestSPKI(c->publickey_alg, c->publickey->data, c->publickey->len, fun, digest);
+ freecert(c);
+ return 0;
+}
+
static char*
tagdump(Tag tag)
{
@@ -3048,7 +3017,6 @@
X509dump(uchar *cert, int ncert)
{
char *e;
- Bytes *b;
CertX509 *c;
RSApub *rsapub;
ECpub *ecpub;
@@ -3057,15 +3025,13 @@
uchar digest[MAXdlen];
print("begin X509dump\n");
- b = makebytes(cert, ncert);
- c = decode_cert(b);
+ c = decode_cert(cert, ncert);
if(c == nil){
- freebytes(b);
print("cannot decode cert\n");
return;
}
- digestlen = digest_certinfo(b, digestalg[c->signature_alg], digest);
- freebytes(b);
+
+ digestlen = digest_certinfo(cert, ncert, digestalg[c->signature_alg], digest);
if(digestlen <= 0){
freecert(c);
print("cannot decode certinfo\n");
@@ -3082,10 +3048,11 @@
switch(c->publickey_alg){
case ALG_rsaEncryption:
- rsapub = decode_rsapubkey(c->publickey);
+ rsapub = asn1toRSApub(c->publickey->data, c->publickey->len);
if(rsapub != nil){
print("rsa pubkey e=%B n(%d)=%B\n", rsapub->ek, mpsignif(rsapub->n), rsapub->n);
- e = X509rsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, rsapub);
+ e = X509rsaverifydigest(c->signature->data, c->signature->len,
+ digest, digestlen, rsapub);
if(e==nil)
e = "nil (meaning ok)";
print("self-signed X509rsaverifydigest returns: %s\n", e);
@@ -3096,7 +3063,8 @@
ecdominit(&ecdom, namedcurves[c->curve]);
ecpub = ecdecodepub(&ecdom, c->publickey->data, c->publickey->len);
if(ecpub != nil){
- e = X509ecdsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, &ecdom, ecpub);
+ e = X509ecdsaverifydigest(c->signature->data, c->signature->len,
+ digest, digestlen, &ecdom, ecpub);
if(e==nil)
e = "nil (meaning ok)";
print("self-signed X509ecdsaverifydigest returns: %s\n", e);
@@ -3105,6 +3073,16 @@
ecdomfree(&ecdom);
break;
}
+
+ digestSPKI(c->publickey_alg, c->publickey->data, c->publickey->len, sha2_256, digest);
+ print("publickey_thumbprint sha256=%.*[\n", SHA2_256dlen, digest);
+
+ sha2_256(cert, ncert, digest, nil);
+ print("cert_thumbprint sha256=%.*[\n", SHA2_256dlen, digest);
+
+ sha1(cert, ncert, digest, nil);
+ print("cert_thumbprint sha1=%.*H\n", SHA1dlen, digest);
+
freecert(c);
print("end X509dump\n");
}