Index: net/cert/x509_util_openssl.cc |
diff --git a/net/cert/x509_util_openssl.cc b/net/cert/x509_util_openssl.cc |
index 5b6779a76b19356857aaff4d1922f51206f05188..2e8ef2e6c7a95885a9ab299f39bff60ad68f19be 100644 |
--- a/net/cert/x509_util_openssl.cc |
+++ b/net/cert/x509_util_openssl.cc |
@@ -6,6 +6,7 @@ |
#include <limits.h> |
#include <openssl/asn1.h> |
+#include <openssl/digest.h> |
#include <openssl/mem.h> |
#include <algorithm> |
@@ -19,7 +20,10 @@ |
#include "crypto/openssl_util.h" |
#include "crypto/rsa_private_key.h" |
#include "crypto/scoped_openssl_types.h" |
+#include "net/cert/internal/parse_certificate.h" |
+#include "net/cert/internal/signature_algorithm.h" |
#include "net/cert/x509_cert_types.h" |
+#include "net/cert/x509_certificate.h" |
#include "net/cert/x509_util.h" |
#include "net/ssl/scoped_openssl_types.h" |
@@ -303,6 +307,57 @@ bool GetDER(X509* x509, base::StringPiece* der_cache) { |
return true; |
} |
+bool GetTLSServerEndPointChannelBinding(const X509Certificate& certificate, |
+ std::string* token) { |
+ static const char kChannelBindingPrefix[] = "tls-server-end-point:"; |
+ |
+ std::string der_encoded_certificate; |
+ if (!X509Certificate::GetDEREncoded(certificate.os_cert_handle(), |
+ &der_encoded_certificate)) |
+ return false; |
+ |
+ ParsedCertificate parsed_certificate; |
+ if (!ParseCertificate(der::Input(base::StringPiece(der_encoded_certificate)), |
+ &parsed_certificate)) |
+ return false; |
+ |
+ scoped_ptr<SignatureAlgorithm> signature_algorithm = |
+ SignatureAlgorithm::CreateFromDer( |
+ parsed_certificate.signature_algorithm_tlv); |
+ if (!signature_algorithm) |
+ return false; |
+ |
+ const EVP_MD* digest_evp_md = nullptr; |
+ switch (signature_algorithm->digest()) { |
+ case net::DigestAlgorithm::Sha1: |
+ case net::DigestAlgorithm::Sha256: |
+ digest_evp_md = EVP_sha256(); |
+ break; |
+ |
+ case net::DigestAlgorithm::Sha384: |
+ digest_evp_md = EVP_sha384(); |
+ break; |
+ |
+ case net::DigestAlgorithm::Sha512: |
+ digest_evp_md = EVP_sha512(); |
+ break; |
+ } |
+ if (!digest_evp_md) |
+ return false; |
+ |
+ std::vector<uint8_t> digest(EVP_MAX_MD_SIZE); |
+ unsigned int out_size = digest.size(); |
+ if (!EVP_Digest(der_encoded_certificate.data(), |
+ der_encoded_certificate.size(), digest.data(), &out_size, |
+ digest_evp_md, nullptr)) |
+ return false; |
+ |
+ digest.resize(out_size); |
+ token->assign(kChannelBindingPrefix); |
+ token->append(digest.begin(), digest.end()); |
+ return true; |
+} |
+ |
} // namespace x509_util |
} // namespace net |