From ba87f31c41dc4730486b3da588be77080ea6b201 Mon Sep 17 00:00:00 2001 From: Richard Aas Date: Thu, 7 Mar 2013 08:35:16 +0000 Subject: [PATCH] tls: add fingerprint api --- include/re_tls.h | 10 +++++++ src/tls/openssl/tls.c | 63 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/re_tls.h b/include/re_tls.h index d53a6ca..605c668 100644 --- a/include/re_tls.h +++ b/include/re_tls.h @@ -18,12 +18,22 @@ enum tls_method { TLS_METHOD_DTLSV1, }; +struct tls_fingerprint { + uint8_t md[64]; + unsigned int len; +}; + int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile, const char *pwd); int tls_add_ca(struct tls *tls, const char *capath); int tls_verify_cert(struct tls_conn *tc, char *cn, size_t cn_size); +int tls_get_local_fingerprint(const struct tls *tls, const char *type, + struct tls_fingerprint *fp); +int tls_get_remote_fingerprint(const struct tls_conn *tc, const char *type, + struct tls_fingerprint *fp); + int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp, int layer); int tls_start_udp(struct tls_sock **tsp, struct tls *tls, diff --git a/src/tls/openssl/tls.c b/src/tls/openssl/tls.c index cf80a69..2d54689 100644 --- a/src/tls/openssl/tls.c +++ b/src/tls/openssl/tls.c @@ -251,3 +251,66 @@ int tls_verify_cert(struct tls_conn *tc, char *cn, size_t cn_size) return 0; } + + +static const EVP_MD *type2evp(const char *type) +{ + if (0 == str_casecmp(type, "SHA-1")) + return EVP_sha1(); + else + return NULL; +} + + +int tls_get_local_fingerprint(const struct tls *tls, const char *type, + struct tls_fingerprint *fp) +{ + SSL *ssl; + X509 *x; + int err = 0; + + if (!tls || !fp) + return EINVAL; + + ssl = SSL_new(tls->ctx); + if (!ssl) + return ENOMEM; + + x = SSL_get_certificate(ssl); + if (!x) { + err = ENOENT; + goto out; + } + + fp->len = sizeof(fp->md); + if (1 != X509_digest(x, type2evp(type), fp->md, &fp->len)) { + err = ENOENT; + goto out; + } + + out: + (void)SSL_shutdown(ssl); + SSL_free(ssl); + + return err; +} + + +int tls_get_remote_fingerprint(const struct tls_conn *tc, const char *type, + struct tls_fingerprint *fp) +{ + X509 *x; + + if (!tc || !fp) + return EINVAL; + + x = SSL_get_peer_certificate(tc->ssl); + if (!x) + return EPROTO; + + fp->len = sizeof(fp->md); + if (1 != X509_digest(x, type2evp(type), fp->md, &fp->len)) + return ENOENT; + + return 0; +}