| Index: net/third_party/nss/ssl/ssl3ext.c
|
| diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
|
| index 04157701e9028e670098fa47469960ffc05513c9..068223ddd7451e4de7aee59cb7dbd73a98480f2e 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 } */
|
| };
|
|
|
| @@ -2297,3 +2307,60 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| loser:
|
| return -1;
|
| }
|
| +
|
| +/* 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);
|
| + *scts = *data;
|
| + /* Keep track of negotiated extensions. */
|
| + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
| + return SECSuccess;
|
| +}
|
|
|