From 6dd4bc6a277ac560d8ab15e6983dd669efd50158 Mon Sep 17 00:00:00 2001 From: Kyle Nekritz Date: Fri, 28 Aug 2015 13:35:05 -0700 Subject: [PATCH] Log TLS signature_algorithms extension values. Summary: Provide a folly interface for logging the client supported TLS signature algorithms. Reviewed By: @siyengar Differential Revision: D2374528 --- folly/io/async/AsyncSSLSocket.cpp | 23 ++++++++-- folly/io/async/AsyncSSLSocket.h | 74 ++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/folly/io/async/AsyncSSLSocket.cpp b/folly/io/async/AsyncSSLSocket.cpp index e3df3950..c6dd25b5 100644 --- a/folly/io/async/AsyncSSLSocket.cpp +++ b/folly/io/async/AsyncSSLSocket.cpp @@ -1606,13 +1606,30 @@ AsyncSSLSocket::clientHelloParsingCallback(int written, int version, if (cursor.totalLength() > 0) { uint16_t extensionsLength = cursor.readBE(); while (extensionsLength) { + TLSExtension extensionType = static_cast( + cursor.readBE()); sock->clientHelloInfo_-> - clientHelloExtensions_.push_back(cursor.readBE()); + clientHelloExtensions_.push_back(extensionType); extensionsLength -= 2; uint16_t extensionDataLength = cursor.readBE(); extensionsLength -= 2; - cursor.skip(extensionDataLength); - extensionsLength -= extensionDataLength; + + if (extensionType == TLSExtension::SIGNATURE_ALGORITHMS) { + cursor.skip(2); + extensionDataLength -= 2; + while (extensionDataLength) { + HashAlgorithm hashAlg = static_cast( + cursor.readBE()); + SignatureAlgorithm sigAlg = static_cast( + cursor.readBE()); + extensionDataLength -= 2; + sock->clientHelloInfo_-> + clientHelloSigAlgs_.emplace_back(hashAlg, sigAlg); + } + } else { + cursor.skip(extensionDataLength); + extensionsLength -= extensionDataLength; + } } } } catch (std::out_of_range& e) { diff --git a/folly/io/async/AsyncSSLSocket.h b/folly/io/async/AsyncSSLSocket.h index 227e5ea7..31f8b6c4 100644 --- a/folly/io/async/AsyncSSLSocket.h +++ b/folly/io/async/AsyncSSLSocket.h @@ -601,6 +601,27 @@ class AsyncSSLSocket : public virtual AsyncSocket { return folly::join(":", clientHelloInfo_->clientHelloExtensions_); } + std::string getSSLClientSigAlgs() { + if (!parseClientHello_) { + return ""; + } + + std::string sigAlgs; + sigAlgs.reserve(clientHelloInfo_->clientHelloSigAlgs_.size() * 4); + for (size_t i = 0; i < clientHelloInfo_->clientHelloSigAlgs_.size(); i++) { + if (i) { + sigAlgs.push_back(':'); + } + sigAlgs.append(folly::to( + clientHelloInfo_->clientHelloSigAlgs_[i].first)); + sigAlgs.push_back(','); + sigAlgs.append(folly::to( + clientHelloInfo_->clientHelloSigAlgs_[i].second)); + } + + return sigAlgs; + } + /** * Get the list of shared ciphers between the server and the client. * Works well for only SSLv2, not so good for SSLv3 or TLSv1. @@ -634,13 +655,64 @@ class AsyncSSLSocket : public virtual AsyncSocket { static void clientHelloParsingCallback(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); + // http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml + enum class TLSExtension: uint16_t { + SERVER_NAME = 0, + MAX_FRAGMENT_LENGTH = 1, + CLIENT_CERTIFICATE_URL = 2, + TRUSTED_CA_KEYS = 3, + TRUNCATED_HMAC = 4, + STATUS_REQUEST = 5, + USER_MAPPING = 6, + CLIENT_AUTHZ = 7, + SERVER_AUTHZ = 8, + CERT_TYPE = 9, + SUPPORTED_GROUPS = 10, + EC_POINT_FORMATS = 11, + SRP = 12, + SIGNATURE_ALGORITHMS = 13, + USE_SRTP = 14, + HEARTBEAT = 15, + APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16, + STATUS_REQUEST_V2 = 17, + SIGNED_CERTIFICATE_TIMESTAMP = 18, + CLIENT_CERTIFICATE_TYPE = 19, + SERVER_CERTIFICATE_TYPE = 20, + PADDING = 21, + ENCRYPT_THEN_MAC = 22, + EXTENDED_MASTER_SECRET = 23, + SESSION_TICKET = 35, + RENEGOTIATION_INFO = 65281 + }; + + // http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18 + enum class HashAlgorithm: uint8_t { + NONE = 0, + MD5 = 1, + SHA1 = 2, + SHA224 = 3, + SHA256 = 4, + SHA384 = 5, + SHA512 = 6 + }; + + // http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16 + enum class SignatureAlgorithm: uint8_t { + ANONYMOUS = 0, + RSA = 1, + DSA = 2, + ECDSA = 3 + }; + struct ClientHelloInfo { folly::IOBufQueue clientHelloBuf_; uint8_t clientHelloMajorVersion_; uint8_t clientHelloMinorVersion_; std::vector clientHelloCipherSuites_; std::vector clientHelloCompressionMethods_; - std::vector clientHelloExtensions_; + std::vector clientHelloExtensions_; + std::vector< + std::pair> clientHelloSigAlgs_; }; // For unit-tests -- 2.34.1