diff options
-rw-r--r-- | sys/include/ape/libsec.h | 4 | ||||
-rw-r--r-- | sys/include/libsec.h | 1 | ||||
-rw-r--r-- | sys/man/8/tlssrv | 5 | ||||
-rw-r--r-- | sys/src/cmd/tlsclient.c | 5 | ||||
-rw-r--r-- | sys/src/libsec/port/thumb.c | 5 | ||||
-rw-r--r-- | sys/src/libsec/port/x509.c | 36 |
6 files changed, 52 insertions, 4 deletions
diff --git a/sys/include/ape/libsec.h b/sys/include/ape/libsec.h index bd4b352f7..610e69e28 100644 --- a/sys/include/ape/libsec.h +++ b/sys/include/ape/libsec.h @@ -382,7 +382,9 @@ int pkcs1unpadbuf(uchar *buf, int len, mpint *modulus, int blocktype); int asn1encodeRSApub(RSApub *pk, uchar *buf, int len); int asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len); - + +int X509digestSPKI(uchar *, int, DigestState* (*)(uchar*, ulong, uchar*, DigestState*), uchar *); + /* * elgamal */ diff --git a/sys/include/libsec.h b/sys/include/libsec.h index b1616782f..f9c75306b 100644 --- a/sys/include/libsec.h +++ b/sys/include/libsec.h @@ -375,6 +375,7 @@ int asn1encodeRSApub(RSApub *pk, uchar *buf, int len); int asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len); +int X509digestSPKI(uchar *, int, DigestState* (*)(uchar*, ulong, uchar*, DigestState*), uchar *); /* * elgamal diff --git a/sys/man/8/tlssrv b/sys/man/8/tlssrv index 462be928b..9ebaa0104 100644 --- a/sys/man/8/tlssrv +++ b/sys/man/8/tlssrv @@ -134,9 +134,8 @@ flag (and, optionally, the .B -x flag) -is given, the remote server must present a key -whose SHA1 hash is listed in -the file +is given, the remote server must present a public key +whose SHA1 or SHA256 hash is listed in the file .I trustedkeys but not in the file .IR excludedkeys . diff --git a/sys/src/cmd/tlsclient.c b/sys/src/cmd/tlsclient.c index 1b79fb739..7be56c279 100644 --- a/sys/src/cmd/tlsclient.c +++ b/sys/src/cmd/tlsclient.c @@ -49,6 +49,8 @@ main(int argc, char **argv) Thumbprint *thumb; AuthInfo *ai = nil; + fmtinstall('B', mpfmt); + fmtinstall('[', encodefmt); fmtinstall('H', encodefmt); ARGBEGIN{ @@ -122,6 +124,9 @@ main(int argc, char **argv) if(fd < 0) sysfatal("tlsclient: %r"); + if(debug) + X509dump(conn->cert, conn->certlen); + if(thumb){ if(!okCertificate(conn->cert, conn->certlen, thumb)) sysfatal("cert for %s not recognized: %r", servername ? servername : addr); diff --git a/sys/src/libsec/port/thumb.c b/sys/src/libsec/port/thumb.c index 39757939b..73add8db1 100644 --- a/sys/src/libsec/port/thumb.c +++ b/sys/src/libsec/port/thumb.c @@ -66,6 +66,11 @@ okCertificate(uchar *cert, int len, Thumbprint *table) 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--; diff --git a/sys/src/libsec/port/x509.c b/sys/src/libsec/port/x509.c index e5b92039c..2ec9d9551 100644 --- a/sys/src/libsec/port/x509.c +++ b/sys/src/libsec/port/x509.c @@ -2897,6 +2897,32 @@ errret: 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) { @@ -3047,6 +3073,16 @@ X509dump(uchar *cert, int ncert) 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"); } |