summaryrefslogtreecommitdiffstats
path: root/net/third_party/nss/ssl/ssl3ext.c
diff options
context:
space:
mode:
authorekasper@google.com <ekasper@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-21 02:36:55 +0000
committerekasper@google.com <ekasper@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-21 02:36:55 +0000
commitb04dff61dbf2c71c021eed65dd549c7e84dfb34b (patch)
treecdd1783d87edb19c35a99e56d6c87d245020cfd3 /net/third_party/nss/ssl/ssl3ext.c
parent6bfe8216bf3258382f19da1a9dd220a9851914e0 (diff)
downloadchromium_src-b04dff61dbf2c71c021eed65dd549c7e84dfb34b.zip
chromium_src-b04dff61dbf2c71c021eed65dd549c7e84dfb34b.tar.gz
chromium_src-b04dff61dbf2c71c021eed65dd549c7e84dfb34b.tar.bz2
Certificate Transparency TLS extension patch for NSS
BUG=309578 Review URL: https://codereview.chromium.org/64553002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236376 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party/nss/ssl/ssl3ext.c')
-rw-r--r--net/third_party/nss/ssl/ssl3ext.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
index adb81ed..02e104d 100644
--- a/net/third_party/nss/ssl/ssl3ext.c
+++ b/net/third_party/nss/ssl/ssl3ext.c
@@ -81,6 +81,12 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
SECItem *data);
+static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss,
+ PRBool append,
+ PRUint32 maxBytes);
+static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss,
+ PRUint16 ex_type,
+ SECItem *data);
/*
* Write bytes. Using this function means the SECItem structure
@@ -259,6 +265,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
{ ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { ssl_signed_certificate_timestamp_xtn,
+ &ssl3_ClientHandleSignedCertTimestampXtn },
{ -1, NULL }
};
@@ -287,7 +295,9 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
{ ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
{ ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
- { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
+ { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
+ { ssl_signed_certificate_timestamp_xtn,
+ &ssl3_ClientSendSignedCertTimestampXtn }
/* any extra entries will appear as { 0, NULL } */
};
@@ -2364,3 +2374,65 @@ ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
return extensionLen;
}
+
+/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
+ * extension for TLS ClientHellos. */
+static PRInt32
+ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length = 2 /* extension_type */ +
+ 2 /* length(extension_data) */;
+
+ /* Only send the extension if processing is enabled. */
+ if (!ss->opt.enableSignedCertTimestamps)
+ return 0;
+
+ if (append && maxBytes >= extension_length) {
+ SECStatus rv;
+ /* extension_type */
+ rv = ssl3_AppendHandshakeNumber(ss,
+ ssl_signed_certificate_timestamp_xtn,
+ 2);
+ if (rv != SECSuccess)
+ goto loser;
+ /* zero length */
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
+ ssl_signed_certificate_timestamp_xtn;
+ } else if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ return extension_length;
+loser:
+ return -1;
+}
+
+static SECStatus
+ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
+ SECItem *data)
+{
+ /* We do not yet know whether we'll be resuming a session or creating
+ * a new one, so we keep a pointer to the data in the TLSExtensionData
+ * structure. This pointer is only valid in the scope of
+ * ssl3_HandleServerHello, and, if not resuming a session, the data is
+ * copied once a new session structure has been set up.
+ * All parsing is currently left to the application and we accept
+ * everything, including empty data.
+ */
+ SECItem *scts = &ss->xtnData.signedCertTimestamps;
+ PORT_Assert(!scts->data && !scts->len);
+
+ if (!data->len) {
+ /* Empty extension data: RFC 6962 mandates non-empty contents. */
+ return SECFailure;
+ }
+ *scts = *data;
+ /* Keep track of negotiated extensions. */
+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+ return SECSuccess;
+}