summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/ape/libsec.h4
-rw-r--r--sys/include/libsec.h1
-rw-r--r--sys/man/8/tlssrv5
-rw-r--r--sys/src/cmd/tlsclient.c5
-rw-r--r--sys/src/libsec/port/thumb.c5
-rw-r--r--sys/src/libsec/port/x509.c36
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");
}