From b28f60cdd3d7efcb5699cb8360e1e50823238d1f Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 15 Nov 2012 19:32:53 +0100 Subject: add C-Keens tls-client-auth This patch adds client TLS authentication to libsec in compliance with rfc 4346. A new -c flag has been introduced for tlsclient allowing the user to specify a certificate in pem(8) format which will be provided to the server upon request. A -D debug flag has been introduced to enable debugging output. The patch has been tested against OpenSSL 0.9.7j 04 May 2006. It exists today because of the great (debugging) help and insight provided by Matthias Bauer. TODOs: - specification of a certain client key in factotum is not possible at the moment - tlssrv should support this too These will get added in another patch. The first try to submit this patch failed due to a network error. Sorry for the duplication! Kind regards, Christian --- sys/src/cmd/tlsclient.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) (limited to 'sys/src/cmd/tlsclient.c') diff --git a/sys/src/cmd/tlsclient.c b/sys/src/cmd/tlsclient.c index 8bfff5d0f..f4f1a25d8 100644 --- a/sys/src/cmd/tlsclient.c +++ b/sys/src/cmd/tlsclient.c @@ -6,7 +6,7 @@ void usage(void) { - fprint(2, "usage: tlsclient [-t /sys/lib/tls/xxx] [-x /sys/lib/tls/xxx.exclude] dialstring\n"); + fprint(2, "usage: tlsclient [-c lib/tls/clientcert] [-t /sys/lib/tls/xxx] [-x /sys/lib/tls/xxx.exclude] dialstring\n"); exits("usage"); } @@ -21,18 +21,34 @@ xfer(int from, int to) break; } +static int +reporter(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprint(2, "%s: tls reports ", argv0); + vfprint(2, fmt, ap); + fprint(2, "\n"); + + va_end(ap); + return 0; +} + void main(int argc, char **argv) { - int fd, netfd; + int fd, netfd, debug; uchar digest[20]; - TLSconn conn; - char *addr, *file, *filex; + TLSconn *conn; + char *addr, *file, *filex, *ccert; Thumbprint *thumb; file = nil; filex = nil; thumb = nil; + ccert=nil; + debug=0; ARGBEGIN{ case 't': file = EARGF(usage()); @@ -40,6 +56,12 @@ main(int argc, char **argv) case 'x': filex = EARGF(usage()); break; + case 'D': + debug++; + break; + case 'c': + ccert = EARGF(usage()); + break; default: usage(); }ARGEND @@ -59,20 +81,24 @@ main(int argc, char **argv) if((netfd = dial(addr, 0, 0, 0)) < 0) sysfatal("dial %s: %r", addr); - memset(&conn, 0, sizeof conn); - fd = tlsClient(netfd, &conn); + conn = (TLSconn*)mallocz(sizeof *conn, 1); + if(ccert) + conn->cert = readcert(ccert, &conn->certlen); + if(debug) + conn->trace = reporter; + fd = tlsClient(netfd, conn); if(fd < 0) sysfatal("tlsclient: %r"); if(thumb){ - if(conn.cert==nil || conn.certlen<=0) + if(conn->cert==nil || conn->certlen<=0) sysfatal("server did not provide TLS certificate"); - sha1(conn.cert, conn.certlen, digest, nil); + sha1(conn->cert, conn->certlen, digest, nil); if(!okThumbprint(digest, thumb)){ fmtinstall('H', encodefmt); sysfatal("server certificate %.*H not recognized", SHA1dlen, digest); } } - free(conn.cert); + free(conn->cert); close(netfd); rfork(RFNOTEG); -- cgit v1.2.3