Index: net/socket/ssl_client_socket_openssl.cc |
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc |
index 82ced7cbfeabb55172b155d570b169e92e35cbb1..21cd9fd9d17c1e1c93cd9787f23ea7feae1f3268 100644 |
--- a/net/socket/ssl_client_socket_openssl.cc |
+++ b/net/socket/ssl_client_socket_openssl.cc |
@@ -26,6 +26,7 @@ |
#include "base/metrics/histogram_macros.h" |
#include "base/metrics/sparse_histogram.h" |
#include "base/profiler/scoped_tracker.h" |
+#include "base/stl_util.h" |
davidben
2016/01/22 00:19:21
Unused?
nharper
2016/01/22 19:36:52
Removed.
|
#include "base/strings/string_piece.h" |
#include "base/synchronization/lock.h" |
#include "base/threading/thread_local.h" |
@@ -526,6 +527,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
channel_id_service_(context.channel_id_service), |
tb_was_negotiated_(false), |
tb_negotiated_param_(TB_PARAM_ECDSAP256), |
+ tb_signed_ekm_map_(10), |
ssl_(NULL), |
transport_bio_(NULL), |
transport_(std::move(transport_socket)), |
@@ -577,6 +579,47 @@ SSLClientSocketOpenSSL::GetChannelIDService() const { |
return channel_id_service_; |
} |
+int SSLClientSocketOpenSSL::GetSignedEKMForTokenBinding( |
+ crypto::ECPrivateKey* key, |
+ std::vector<uint8_t>* out) { |
+ // The same key will be used across multiple requests to sign the same value, |
+ // so the signature is cached. |
+ std::string raw_public_key; |
+ if (!key->ExportRawPublicKey(&raw_public_key)) |
+ return ERR_FAILED; |
+ SignedEkmMap::iterator it = tb_signed_ekm_map_.Get(raw_public_key); |
+ if (it != tb_signed_ekm_map_.end()) { |
+ *out = it->second; |
+ return OK; |
+ } |
+ |
+ size_t tb_ekm_size = 32; |
davidben
2016/01/22 00:19:21
Nit: Could just use sizeof(tb_ekm_buf) everywhere
nharper
2016/01/22 19:36:52
Done.
|
+ uint8_t tb_ekm_buf[32]; |
+ static const char kTokenBindingExporterLabel[] = "EXPORTER-Token-Binding"; |
+ size_t ekm_label_length = strlen(kTokenBindingExporterLabel); |
davidben
2016/01/22 00:19:21
Nit: Could just use strlen(kTokenBindingExporterLa
nharper
2016/01/22 19:36:52
Done.
|
+ if (!SSL_export_keying_material(ssl_, tb_ekm_buf, tb_ekm_size, |
+ kTokenBindingExporterLabel, ekm_label_length, |
+ nullptr, 0, false)) { |
davidben
2016/01/22 00:19:21
Nit: false /* no context */
nharper
2016/01/22 19:36:52
I've made this change, but I'm not sure it's any c
|
+ return ERR_FAILED; |
+ } |
+ |
+ size_t sig_len; |
+ crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(key->key(), nullptr)); |
+ if (!EVP_PKEY_sign_init(pctx.get()) || |
+ !EVP_PKEY_sign(pctx.get(), nullptr, &sig_len, tb_ekm_buf, tb_ekm_size)) { |
+ return ERR_FAILED; |
+ } |
+ out->resize(sig_len); |
+ if (!EVP_PKEY_sign(pctx.get(), out->data(), &sig_len, tb_ekm_buf, |
+ tb_ekm_size)) { |
+ return ERR_FAILED; |
+ } |
+ out->resize(sig_len); |
+ |
+ tb_signed_ekm_map_.Put(raw_public_key, *out); |
+ return OK; |
+} |
+ |
SSLFailureState SSLClientSocketOpenSSL::GetSSLFailureState() const { |
return ssl_failure_state_; |
} |