diff options
24 files changed, 312 insertions, 62 deletions
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index cb7e487..e199307 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc @@ -688,8 +688,9 @@ void MockClientSocket::GetSSLCertRequestInfo( } int MockClientSocket::ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) { memset(out, 'A', outlen); return OK; diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index d059e89..ecd671c 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h @@ -596,8 +596,9 @@ class MockClientSocket : public SSLClientSocket { virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) OVERRIDE; virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) OVERRIDE; virtual NextProtoStatus GetNextProto(std::string* proto, std::string* server_protos) OVERRIDE; diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc index 9a69ec4..927da8c 100644 --- a/net/socket/ssl_client_socket_mac.cc +++ b/net/socket/ssl_client_socket_mac.cc @@ -778,8 +778,9 @@ void SSLClientSocketMac::GetSSLCertRequestInfo( } int SSLClientSocketMac::ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) { return ERR_NOT_IMPLEMENTED; } diff --git a/net/socket/ssl_client_socket_mac.h b/net/socket/ssl_client_socket_mac.h index a7fa3aa..ec2b51a 100644 --- a/net/socket/ssl_client_socket_mac.h +++ b/net/socket/ssl_client_socket_mac.h @@ -45,8 +45,9 @@ class SSLClientSocketMac : public SSLClientSocket { virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) OVERRIDE; virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) OVERRIDE; virtual NextProtoStatus GetNextProto(std::string* proto, std::string* server_protos) OVERRIDE; diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index bc2bc92..688b8e6 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -539,13 +539,14 @@ void SSLClientSocketNSS::GetSSLCertRequestInfo( } int SSLClientSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) { if (!IsConnected()) return ERR_SOCKET_NOT_CONNECTED; SECStatus result = SSL_ExportKeyingMaterial( - nss_fd_, label.data(), label.size(), + nss_fd_, label.data(), label.size(), has_context, reinterpret_cast<const unsigned char*>(context.data()), context.length(), out, outlen); if (result != SECSuccess) { @@ -2037,7 +2038,7 @@ void SSLClientSocketNSS::BufferSendComplete(int result) { int SSLClientSocketNSS::BufferRecv(void) { if (transport_recv_busy_) return ERR_IO_PENDING; - char *buf; + char* buf; int nb = memio_GetReadParams(nss_bufs_, &buf); EnterFunction(nb); int rv; @@ -2066,7 +2067,7 @@ int SSLClientSocketNSS::BufferRecv(void) { void SSLClientSocketNSS::BufferRecvComplete(int result) { EnterFunction(result); if (result > 0) { - char *buf; + char* buf; memio_GetReadParams(nss_bufs_, &buf); memcpy(buf, recv_buffer_->data(), result); } diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 2dc72c5..1582f37 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -62,8 +62,9 @@ class SSLClientSocketNSS : public SSLClientSocket { virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) OVERRIDE; virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) OVERRIDE; virtual NextProtoStatus GetNextProto(std::string* proto, std::string* server_protos) OVERRIDE; diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc index c599d58..f55c613 100644 --- a/net/socket/ssl_client_socket_openssl.cc +++ b/net/socket/ssl_client_socket_openssl.cc @@ -624,8 +624,9 @@ void SSLClientSocketOpenSSL::GetSSLCertRequestInfo( } int SSLClientSocketOpenSSL::ExportKeyingMaterial( - const base::StringPiece& label, const base::StringPiece& context, - unsigned char *out, unsigned int outlen) { + const base::StringPiece& label, + bool has_context, const base::StringPiece& context, + unsigned char* out, unsigned int outlen) { crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); int rv = SSL_export_keying_material( diff --git a/net/socket/ssl_client_socket_openssl.h b/net/socket/ssl_client_socket_openssl.h index 21e2c3c..69f03c9 100644 --- a/net/socket/ssl_client_socket_openssl.h +++ b/net/socket/ssl_client_socket_openssl.h @@ -59,8 +59,9 @@ class SSLClientSocketOpenSSL : public SSLClientSocket { virtual void GetSSLInfo(SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen); virtual NextProtoStatus GetNextProto(std::string* proto, std::string* server_protos); diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index f74b71c..c8dfc8a 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc @@ -811,14 +811,14 @@ TEST_F(SSLClientSocketTest, ExportKeyingMaterial) { const char* kKeyingContext = ""; unsigned char client_out1[kKeyingMaterialSize]; memset(client_out1, 0, sizeof(client_out1)); - rv = sock->ExportKeyingMaterial(kKeyingLabel1, kKeyingContext, + rv = sock->ExportKeyingMaterial(kKeyingLabel1, false, kKeyingContext, client_out1, sizeof(client_out1)); EXPECT_EQ(rv, net::OK); const char* kKeyingLabel2 = "client-socket-test-2"; unsigned char client_out2[kKeyingMaterialSize]; memset(client_out2, 0, sizeof(client_out2)); - rv = sock->ExportKeyingMaterial(kKeyingLabel2, kKeyingContext, + rv = sock->ExportKeyingMaterial(kKeyingLabel2, false, kKeyingContext, client_out2, sizeof(client_out2)); EXPECT_EQ(rv, net::OK); EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0); diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc index 11b3938..990faeb 100644 --- a/net/socket/ssl_client_socket_win.cc +++ b/net/socket/ssl_client_socket_win.cc @@ -540,8 +540,9 @@ void SSLClientSocketWin::GetSSLCertRequestInfo( } int SSLClientSocketWin::ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) { return ERR_NOT_IMPLEMENTED; } diff --git a/net/socket/ssl_client_socket_win.h b/net/socket/ssl_client_socket_win.h index bbf432e..e1ca1120 100644 --- a/net/socket/ssl_client_socket_win.h +++ b/net/socket/ssl_client_socket_win.h @@ -49,8 +49,9 @@ class SSLClientSocketWin : public SSLClientSocket { virtual void GetSSLInfo(SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen); virtual NextProtoStatus GetNextProto(std::string* proto, std::string* server_protos); diff --git a/net/socket/ssl_server_socket_nss.cc b/net/socket/ssl_server_socket_nss.cc index a325f22..bb26b9c 100644 --- a/net/socket/ssl_server_socket_nss.cc +++ b/net/socket/ssl_server_socket_nss.cc @@ -120,13 +120,14 @@ int SSLServerSocketNSS::Handshake(const CompletionCallback& callback) { } int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) { if (!IsConnected()) return ERR_SOCKET_NOT_CONNECTED; SECStatus result = SSL_ExportKeyingMaterial( - nss_fd_, label.data(), label.size(), + nss_fd_, label.data(), label.size(), has_context, reinterpret_cast<const unsigned char*>(context.data()), context.length(), out, outlen); if (result != SECSuccess) { @@ -510,7 +511,7 @@ void SSLServerSocketNSS::BufferSendComplete(int result) { int SSLServerSocketNSS::BufferRecv(void) { if (transport_recv_busy_) return ERR_IO_PENDING; - char *buf; + char* buf; int nb = memio_GetReadParams(nss_bufs_, &buf); int rv; if (!nb) { @@ -536,7 +537,7 @@ int SSLServerSocketNSS::BufferRecv(void) { void SSLServerSocketNSS::BufferRecvComplete(int result) { if (result > 0) { - char *buf; + char* buf; memio_GetReadParams(nss_bufs_, &buf); memcpy(buf, recv_buffer_->data(), result); } diff --git a/net/socket/ssl_server_socket_nss.h b/net/socket/ssl_server_socket_nss.h index 626d136..1496362 100644 --- a/net/socket/ssl_server_socket_nss.h +++ b/net/socket/ssl_server_socket_nss.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -34,8 +34,9 @@ class SSLServerSocketNSS : public SSLServerSocket { // SSLServerSocket interface. virtual int Handshake(const CompletionCallback& callback) OVERRIDE; virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) OVERRIDE; // Socket interface (via StreamSocket). diff --git a/net/socket/ssl_server_socket_unittest.cc b/net/socket/ssl_server_socket_unittest.cc index 86f444c..11276d1 100644 --- a/net/socket/ssl_server_socket_unittest.cc +++ b/net/socket/ssl_server_socket_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -455,19 +455,22 @@ TEST_F(SSLServerSocketTest, ExportKeyingMaterial) { const char* kKeyingLabel = "EXPERIMENTAL-server-socket-test"; const char* kKeyingContext = ""; unsigned char server_out[kKeyingMaterialSize]; - int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel, kKeyingContext, + int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel, + false, kKeyingContext, server_out, sizeof(server_out)); ASSERT_EQ(rv, net::OK); unsigned char client_out[kKeyingMaterialSize]; - rv = client_socket_->ExportKeyingMaterial(kKeyingLabel, kKeyingContext, + rv = client_socket_->ExportKeyingMaterial(kKeyingLabel, + false, kKeyingContext, client_out, sizeof(client_out)); ASSERT_EQ(rv, net::OK); EXPECT_TRUE(memcmp(server_out, client_out, sizeof(server_out)) == 0); const char* kKeyingLabelBad = "EXPERIMENTAL-server-socket-test-bad"; unsigned char client_bad[kKeyingMaterialSize]; - rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, kKeyingContext, + rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad, + false, kKeyingContext, client_bad, sizeof(client_bad)); ASSERT_EQ(rv, net::OK); EXPECT_TRUE(memcmp(server_out, client_bad, sizeof(server_out)) != 0); diff --git a/net/socket/ssl_socket.h b/net/socket/ssl_socket.h index 1291b46..bd063a4 100644 --- a/net/socket/ssl_socket.h +++ b/net/socket/ssl_socket.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,11 +18,14 @@ public: virtual ~SSLSocket() {} // Exports data derived from the SSL master-secret (see RFC 5705). - // The call will fail with an error if the socket is not connected, or the - // SSL implementation does not support the operation. + // If |has_context| is false, uses the no-context construction from the + // RFC and |context| is ignored. The call will fail with an error if + // the socket is not connected or the SSL implementation does not + // support the operation. virtual int ExportKeyingMaterial(const base::StringPiece& label, + bool has_context, const base::StringPiece& context, - unsigned char *out, + unsigned char* out, unsigned int outlen) = 0; }; diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 8a57d92..e01d648 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -643,7 +643,7 @@ int SpdySession::WriteCredentialFrame(const std::string& origin, DCHECK(is_secure_); unsigned char secret[32]; // 32 bytes from the spec GetSSLClientSocket()->ExportKeyingMaterial("SPDY certificate proof", - origin, + true, origin, secret, arraysize(secret)); // Convert the key string into a vector<unit8> diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index b6435f2..dd8c15d 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium @@ -48,6 +48,7 @@ Patches: This is a reworked version of the patch from https://bugzilla.mozilla.org/show_bug.cgi?id=507359 patches/secret_exporter.patch + patches/secret_exporter2.patch * Add a function to restart a handshake after a client certificate request. patches/restartclientauth.patch diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh index 48cbe52..1356eab 100755 --- a/net/third_party/nss/patches/applypatches.sh +++ b/net/third_party/nss/patches/applypatches.sh @@ -38,3 +38,5 @@ patch -p6 < $patches_dir/restartclientauth.patch patch -p6 < $patches_dir/encryptedclientcerts.patch patch -p5 < $patches_dir/nextprotocleanup.patch + +patch -p4 < $patches_dir/secret_exporter2.patch diff --git a/net/third_party/nss/patches/secret_exporter2.patch b/net/third_party/nss/patches/secret_exporter2.patch new file mode 100644 index 0000000..695754d --- /dev/null +++ b/net/third_party/nss/patches/secret_exporter2.patch @@ -0,0 +1,228 @@ +Index: net/third_party/nss/ssl/ssl.h +=================================================================== +--- net/third_party/nss/ssl/ssl.h (revision 125777) ++++ net/third_party/nss/ssl/ssl.h (working copy) +@@ -792,12 +792,14 @@ + + /* Export keying material according to RFC 5705. + ** fd must correspond to a TLS 1.0 or higher socket and out must +-** already be allocated. If contextLen is zero it uses the no-context +-** construction from the RFC. ++** already be allocated. If hasContext is false, it uses the no-context ++** construction from the RFC and ignores the context and contextLen ++** arguments. + */ + SSL_IMPORT SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd, + const char *label, + unsigned int labelLen, ++ PRBool hasContext, + const unsigned char *context, + unsigned int contextLen, + unsigned char *out, +Index: net/third_party/nss/ssl/sslinfo.c +=================================================================== +--- net/third_party/nss/ssl/sslinfo.c (revision 125777) ++++ net/third_party/nss/ssl/sslinfo.c (working copy) +@@ -317,18 +317,12 @@ + return PR_FALSE; + } + +-/* Export keying material according to RFC 5705. +-** fd must correspond to a TLS 1.0 or higher socket, out must +-** be already allocated. +-*/ + SECStatus + SSL_ExportKeyingMaterial(PRFileDesc *fd, +- const char *label, +- unsigned int labelLen, +- const unsigned char *context, +- unsigned int contextLen, +- unsigned char *out, +- unsigned int outLen) ++ const char *label, unsigned int labelLen, ++ PRBool hasContext, ++ const unsigned char *context, unsigned int contextLen, ++ unsigned char *out, unsigned int outLen) + { + sslSocket *ss; + unsigned char *val = NULL; +@@ -347,18 +341,21 @@ + return SECFailure; + } + ++ /* construct PRF arguments */ + valLen = SSL3_RANDOM_LENGTH * 2; +- if (contextLen > 0) ++ if (hasContext) { + valLen += 2 /* uint16 length */ + contextLen; ++ } + val = PORT_Alloc(valLen); +- if (val == NULL) ++ if (!val) { + return SECFailure; ++ } + i = 0; + PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); + i += SSL3_RANDOM_LENGTH; + PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH); + i += SSL3_RANDOM_LENGTH; +- if (contextLen > 0) { ++ if (hasContext) { + val[i++] = contextLen >> 8; + val[i++] = contextLen; + PORT_Memcpy(val + i, context, contextLen); +@@ -366,6 +363,9 @@ + } + PORT_Assert(i == valLen); + ++ /* Allow TLS keying material to be exported sooner, when the master ++ * secret is available and we have sent ChangeCipherSpec. ++ */ + ssl_GetSpecReadLock(ss); + if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) { + PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); +Index: net/third_party/nss/ssl/sslimpl.h +=================================================================== +--- net/third_party/nss/ssl/sslimpl.h (revision 125777) ++++ net/third_party/nss/ssl/sslimpl.h (working copy) +@@ -1715,11 +1715,11 @@ + SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); + PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite); + +-SECStatus ssl3_TLSPRFWithMasterSecret( +- ssl3CipherSpec *spec, const char *label, +- unsigned int labelLen, const unsigned char *val, +- unsigned int valLen, unsigned char *out, +- unsigned int outLen); ++extern SECStatus ++ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, ++ const char *label, unsigned int labelLen, ++ const unsigned char *val, unsigned int valLen, ++ unsigned char *out, unsigned int outLen); + + #ifdef TRACE + #define SSL_TRACE(msg) ssl_Trace msg +Index: net/third_party/nss/ssl/ssl3ext.c +=================================================================== +--- net/third_party/nss/ssl/ssl3ext.c (revision 125777) ++++ net/third_party/nss/ssl/ssl3ext.c (working copy) +@@ -606,10 +606,7 @@ + unsigned char resultBuffer[255]; + SECItem result = { siBuffer, resultBuffer, 0 }; + +- if (ss->firstHsDone) { +- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); +- return SECFailure; +- } ++ PORT_Assert(!ss->firstHsDone); + + rv = ssl3_ValidateNextProtoNego(data->data, data->len); + if (rv != SECSuccess) +@@ -621,6 +618,8 @@ + */ + PORT_Assert(ss->nextProtoCallback != NULL); + if (!ss->nextProtoCallback) { ++ /* XXX Use a better error code. This is an application error, not an ++ * NSS bug. */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } +@@ -631,7 +630,7 @@ + return rv; + /* If the callback wrote more than allowed to |result| it has corrupted our + * stack. */ +- if (result.len > sizeof result) { ++ if (result.len > sizeof resultBuffer) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + return SECFailure; + } +Index: net/third_party/nss/ssl/sslsock.c +=================================================================== +--- net/third_party/nss/ssl/sslsock.c (revision 125777) ++++ net/third_party/nss/ssl/sslsock.c (working copy) +@@ -1344,7 +1344,7 @@ + return SECSuccess; + } + +-/* NextProtoStandardCallback is set as an NPN callback for the case when ++/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when + * SSL_SetNextProtoNego is used. + */ + static SECStatus +@@ -1390,12 +1390,12 @@ + result = ss->opt.nextProtoNego.data; + + found: +- *protoOutLen = result[0]; + if (protoMaxLen < result[0]) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + return SECFailure; + } + memcpy(protoOut, result + 1, result[0]); ++ *protoOutLen = result[0]; + return SECSuccess; + } + +@@ -1449,13 +1449,12 @@ + + if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && + ss->ssl3.nextProto.data) { +- *bufLen = ss->ssl3.nextProto.len; +- if (*bufLen > bufLenMax) { ++ if (ss->ssl3.nextProto.len > bufLenMax) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); +- *bufLen = 0; + return SECFailure; + } + PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len); ++ *bufLen = ss->ssl3.nextProto.len; + } else { + *bufLen = 0; + } +Index: net/third_party/nss/ssl/ssl3con.c +=================================================================== +--- net/third_party/nss/ssl/ssl3con.c (revision 125777) ++++ net/third_party/nss/ssl/ssl3con.c (working copy) +@@ -8484,9 +8484,9 @@ + return rv; + } + +-/* The calling function must acquire and release the appropriate lock (i.e., +- * ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for ss->ssl3.crSpec). Any +- * label must already be concatenated onto the beginning of val. ++/* The calling function must acquire and release the appropriate ++ * lock (e.g., ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for ++ * ss->ssl3.crSpec). + */ + SECStatus + ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, +@@ -8508,8 +8508,7 @@ + rv = PK11_DigestBegin(prf_context); + rv |= PK11_DigestOp(prf_context, (unsigned char *) label, labelLen); + rv |= PK11_DigestOp(prf_context, val, valLen); +- rv |= PK11_DigestFinal(prf_context, out, +- &retLen, outLen); ++ rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen); + PORT_Assert(rv != SECSuccess || retLen == outLen); + + PK11_DestroyContext(prf_context, PR_TRUE); +@@ -8532,15 +8531,15 @@ + static SECStatus + ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, + PRBool isServer, +- const SSL3Finished * hashes, +- TLSFinished * tlsFinished) ++ const SSL3Finished * hashes, ++ TLSFinished * tlsFinished) + { + const char * label; +- SECStatus rv; + unsigned int len; ++ SECStatus rv; + + label = isServer ? "server finished" : "client finished"; +- len = 15; ++ len = 15; + + rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->md5, + sizeof *hashes, tlsFinished->verify_data, diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h index 9f41e62..d8f8e2f 100644 --- a/net/third_party/nss/ssl/ssl.h +++ b/net/third_party/nss/ssl/ssl.h @@ -792,12 +792,14 @@ SSL_IMPORT SECItem *SSL_GetNegotiatedHostInfo(PRFileDesc *fd); /* Export keying material according to RFC 5705. ** fd must correspond to a TLS 1.0 or higher socket and out must -** already be allocated. If contextLen is zero it uses the no-context -** construction from the RFC. +** already be allocated. If hasContext is false, it uses the no-context +** construction from the RFC and ignores the context and contextLen +** arguments. */ SSL_IMPORT SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd, const char *label, unsigned int labelLen, + PRBool hasContext, const unsigned char *context, unsigned int contextLen, unsigned char *out, diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index ab17aa1..804feac 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -8484,9 +8484,9 @@ done: return rv; } -/* The calling function must acquire and release the appropriate lock (i.e., - * ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for ss->ssl3.crSpec). Any - * label must already be concatenated onto the beginning of val. +/* The calling function must acquire and release the appropriate + * lock (e.g., ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for + * ss->ssl3.crSpec). */ SECStatus ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, @@ -8508,8 +8508,7 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, rv = PK11_DigestBegin(prf_context); rv |= PK11_DigestOp(prf_context, (unsigned char *) label, labelLen); rv |= PK11_DigestOp(prf_context, val, valLen); - rv |= PK11_DigestFinal(prf_context, out, - &retLen, outLen); + rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen); PORT_Assert(rv != SECSuccess || retLen == outLen); PK11_DestroyContext(prf_context, PR_TRUE); @@ -8532,15 +8531,15 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, static SECStatus ssl3_ComputeTLSFinished(ssl3CipherSpec *spec, PRBool isServer, - const SSL3Finished * hashes, - TLSFinished * tlsFinished) + const SSL3Finished * hashes, + TLSFinished * tlsFinished) { const char * label; - SECStatus rv; unsigned int len; + SECStatus rv; label = isServer ? "server finished" : "client finished"; - len = 15; + len = 15; rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->md5, sizeof *hashes, tlsFinished->verify_data, diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h index 8f78670..e0e53e1 100644 --- a/net/third_party/nss/ssl/sslimpl.h +++ b/net/third_party/nss/ssl/sslimpl.h @@ -1715,11 +1715,11 @@ SECStatus SSL_DisableDefaultExportCipherSuites(void); SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite); -SECStatus ssl3_TLSPRFWithMasterSecret( - ssl3CipherSpec *spec, const char *label, - unsigned int labelLen, const unsigned char *val, - unsigned int valLen, unsigned char *out, - unsigned int outLen); +extern SECStatus +ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, + const char *label, unsigned int labelLen, + const unsigned char *val, unsigned int valLen, + unsigned char *out, unsigned int outLen); #ifdef TRACE #define SSL_TRACE(msg) ssl_Trace msg diff --git a/net/third_party/nss/ssl/sslinfo.c b/net/third_party/nss/ssl/sslinfo.c index ea51039..5148364 100644 --- a/net/third_party/nss/ssl/sslinfo.c +++ b/net/third_party/nss/ssl/sslinfo.c @@ -317,18 +317,12 @@ SSL_IsExportCipherSuite(PRUint16 cipherSuite) return PR_FALSE; } -/* Export keying material according to RFC 5705. -** fd must correspond to a TLS 1.0 or higher socket, out must -** be already allocated. -*/ SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd, - const char *label, - unsigned int labelLen, - const unsigned char *context, - unsigned int contextLen, - unsigned char *out, - unsigned int outLen) + const char *label, unsigned int labelLen, + PRBool hasContext, + const unsigned char *context, unsigned int contextLen, + unsigned char *out, unsigned int outLen) { sslSocket *ss; unsigned char *val = NULL; @@ -347,18 +341,21 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, return SECFailure; } + /* construct PRF arguments */ valLen = SSL3_RANDOM_LENGTH * 2; - if (contextLen > 0) + if (hasContext) { valLen += 2 /* uint16 length */ + contextLen; + } val = PORT_Alloc(valLen); - if (val == NULL) + if (!val) { return SECFailure; + } i = 0; PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); i += SSL3_RANDOM_LENGTH; PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH); i += SSL3_RANDOM_LENGTH; - if (contextLen > 0) { + if (hasContext) { val[i++] = contextLen >> 8; val[i++] = contextLen; PORT_Memcpy(val + i, context, contextLen); @@ -366,6 +363,9 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, } PORT_Assert(i == valLen); + /* Allow TLS keying material to be exported sooner, when the master + * secret is available and we have sent ChangeCipherSpec. + */ ssl_GetSpecReadLock(ss); if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) { PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); diff --git a/remoting/protocol/auth_util.cc b/remoting/protocol/auth_util.cc index 281dabc..841664c 100644 --- a/remoting/protocol/auth_util.cc +++ b/remoting/protocol/auth_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -47,7 +47,7 @@ std::string GetAuthBytes(net::SSLSocket* socket, // Get keying material from SSL. unsigned char key_material[kAuthDigestLength]; int export_result = socket->ExportKeyingMaterial( - label, "", key_material, kAuthDigestLength); + label, false, "", key_material, kAuthDigestLength); if (export_result != net::OK) { LOG(ERROR) << "Error fetching keying material: " << export_result; return std::string(); |