summaryrefslogtreecommitdiffstats
path: root/net/third_party/nss/ssl
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 15:41:45 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 15:41:45 +0000
commitf95f89147dbc66f2b3c54f6e8179c9400607338c (patch)
tree4442cd54775f9eefc37844994b7f4306a2d17d23 /net/third_party/nss/ssl
parenta0d5eada2a9f69c41b0345dd670aaceb74c04cb9 (diff)
downloadchromium_src-f95f89147dbc66f2b3c54f6e8179c9400607338c.zip
chromium_src-f95f89147dbc66f2b3c54f6e8179c9400607338c.tar.gz
chromium_src-f95f89147dbc66f2b3c54f6e8179c9400607338c.tar.bz2
net: add NSS support for RFC 5705
(Keying Material Exporters for TLS). This is a reworked version of the patch from https://bugzilla.mozilla.org/show_bug.cgi?id=507359. BUG=none TEST=none yet Review URL: http://codereview.chromium.org/7464031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93635 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party/nss/ssl')
-rw-r--r--net/third_party/nss/ssl/ssl.h11
-rw-r--r--net/third_party/nss/ssl/ssl3con.c60
-rw-r--r--net/third_party/nss/ssl/sslimpl.h6
-rw-r--r--net/third_party/nss/ssl/sslinfo.c63
4 files changed, 118 insertions, 22 deletions
diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
index 53ca301..1537aae 100644
--- a/net/third_party/nss/ssl/ssl.h
+++ b/net/third_party/nss/ssl/ssl.h
@@ -686,6 +686,17 @@ SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
/* Returnes negotiated through SNI host info. */
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.
+*/
+SSL_IMPORT SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd,
+ const char *label,
+ const unsigned char *context,
+ unsigned int contextlen,
+ unsigned char *out,
+ unsigned int outlen);
+
/*
** Return a new reference to the certificate that was most recently sent
** to the peer on this SSL/TLS connection, or NULL if none has been sent.
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index c39b8f8..dee5555 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -8442,18 +8442,17 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
return rv;
}
-static SECStatus
-ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
- PRBool isServer,
- const SSL3Finished * hashes,
- TLSFinished * tlsFinished)
+/* 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.
+ */
+SECStatus
+ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label,
+ unsigned int labelLen, const unsigned char *val, unsigned int valLen,
+ unsigned char *out, unsigned int outLen)
{
- const char * label;
- unsigned int len;
- SECStatus rv;
-
- label = isServer ? "server finished" : "client finished";
- len = 15;
+ SECStatus rv = SECSuccess;
+ unsigned int retLen;
if (spec->master_secret && !spec->bypassCiphers) {
SECItem param = {siBuffer, NULL, 0};
@@ -8464,11 +8463,11 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
return SECFailure;
rv = PK11_DigestBegin(prf_context);
- rv |= PK11_DigestOp(prf_context, (const unsigned char *) label, len);
- rv |= PK11_DigestOp(prf_context, hashes->md5, sizeof *hashes);
- rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data,
- &len, sizeof tlsFinished->verify_data);
- PORT_Assert(rv != SECSuccess || len == sizeof *tlsFinished);
+ rv |= PK11_DigestOp(prf_context, (unsigned char *) label, labelLen);
+ rv |= PK11_DigestOp(prf_context, val, valLen);
+ rv |= PK11_DigestFinal(prf_context, out,
+ &retLen, outLen);
+ PORT_Assert(rv != SECSuccess || retLen == outLen);
PK11_DestroyContext(prf_context, PR_TRUE);
} else {
@@ -8477,17 +8476,34 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
SECItem outData = { siBuffer, };
PRBool isFIPS = PR_FALSE;
- inData.data = (unsigned char *)hashes->md5;
- inData.len = sizeof hashes[0];
- outData.data = tlsFinished->verify_data;
- outData.len = sizeof tlsFinished->verify_data;
+ inData.data = (unsigned char *) val;
+ inData.len = valLen;
+ outData.data = out;
+ outData.len = outLen;
rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
- PORT_Assert(rv != SECSuccess || \
- outData.len == sizeof tlsFinished->verify_data);
+ PORT_Assert(rv != SECSuccess || outData.len == outLen);
}
return rv;
}
+static SECStatus
+ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
+ PRBool isServer,
+ const SSL3Finished * hashes,
+ TLSFinished * tlsFinished)
+{
+ const char * label;
+ SECStatus rv;
+
+ label = isServer ? "server finished" : "client finished";
+
+ rv = ssl3_TLSPRFWithMasterSecret(spec, label, 15, hashes->md5,
+ sizeof *hashes, tlsFinished->verify_data,
+ sizeof tlsFinished->verify_data);
+
+ return rv;
+}
+
/* called from ssl3_HandleServerHelloDone
*/
static SECStatus
diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
index df30029..073616f 100644
--- a/net/third_party/nss/ssl/sslimpl.h
+++ b/net/third_party/nss/ssl/sslimpl.h
@@ -1726,6 +1726,12 @@ 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);
+
/********************** FNV hash *********************/
void FNV1A64_Init(PRUint64 *digest);
diff --git a/net/third_party/nss/ssl/sslinfo.c b/net/third_party/nss/ssl/sslinfo.c
index 96377b0..9a58b4d 100644
--- a/net/third_party/nss/ssl/sslinfo.c
+++ b/net/third_party/nss/ssl/sslinfo.c
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ * Douglas Stebila <douglas@stebila.ca>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -38,6 +39,7 @@
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
+#include "pk11func.h"
static const char *
ssl_GetCompressionMethodName(SSLCompressionMethod compression)
@@ -316,6 +318,67 @@ SSL_IsExportCipherSuite(PRUint16 cipherSuite)
return PR_FALSE;
}
+/* Export keying material according to draft-ietf-tls-extractor-06.
+** fd must correspond to a TLS 1.0 or higher socket, out must
+** be already allocated.
+*/
+SECStatus
+SSL_ExportKeyingMaterial(PRFileDesc *fd, const char *label,
+ const unsigned char *context,
+ unsigned int contextLen,
+ unsigned char *out,
+ unsigned int outLen)
+{
+ sslSocket *ss;
+ unsigned char *val = NULL;
+ unsigned int valLen, i;
+ SECStatus rv = SECFailure;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
+ return SECFailure;
+ }
+
+ if (ss->ssl3.hs.ws != idle_handshake) {
+ PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
+ return SECFailure;
+ }
+
+ valLen = SSL3_RANDOM_LENGTH * 2;
+ if (contextLen > 0)
+ valLen += 2 /* uint16 length */ + contextLen;
+ val = PORT_Alloc(valLen);
+ if (val == NULL)
+ 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) {
+ val[i++] = contextLen >> 8;
+ val[i++] = contextLen;
+ PORT_Memcpy(val + i, context, contextLen);
+ i += contextLen;
+ }
+ PORT_Assert(i == valLen);
+
+ ssl_GetSpecReadLock(ss);
+ rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.crSpec, label, strlen(label), val, valLen, out, outLen);
+ ssl_ReleaseSpecReadLock(ss);
+
+ if (val != NULL)
+ PORT_ZFree(val, valLen);
+ return rv;
+}
+
SECItem*
SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
{