1diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c 2--- a/nss/lib/ssl/ssl3con.c 2014-01-17 18:11:28.314468184 -0800 3+++ b/nss/lib/ssl/ssl3con.c 2014-01-17 18:23:17.946207727 -0800 4@@ -6682,10 +6682,22 @@ ssl3_HandleServerHello(sslSocket *ss, SS 5 sid->u.ssl3.sessionIDLength = sidBytes.len; 6 PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len); 7 8+ /* Copy Signed Certificate Timestamps, if any. */ 9+ if (ss->xtnData.signedCertTimestamps.data) { 10+ rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps, 11+ &ss->xtnData.signedCertTimestamps); 12+ if (rv != SECSuccess) 13+ goto loser; 14+ } 15+ 16 ss->ssl3.hs.isResuming = PR_FALSE; 17 ss->ssl3.hs.ws = wait_server_cert; 18 19 winner: 20+ /* Clean up the temporary pointer to the handshake buffer. */ 21+ ss->xtnData.signedCertTimestamps.data = NULL; 22+ ss->xtnData.signedCertTimestamps.len = 0; 23+ 24 /* If we will need a ChannelID key then we make the callback now. This 25 * allows the handshake to be restarted cleanly if the callback returns 26 * SECWouldBlock. */ 27@@ -6711,6 +6723,9 @@ alert_loser: 28 (void)SSL3_SendAlert(ss, alert_fatal, desc); 29 30 loser: 31+ /* Clean up the temporary pointer to the handshake buffer. */ 32+ ss->xtnData.signedCertTimestamps.data = NULL; 33+ ss->xtnData.signedCertTimestamps.len = 0; 34 errCode = ssl_MapLowLevelError(errCode); 35 return SECFailure; 36 } 37diff -pu a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c 38--- a/nss/lib/ssl/ssl3ext.c 2014-01-17 18:22:54.945827814 -0800 39+++ b/nss/lib/ssl/ssl3ext.c 2014-01-17 18:35:21.798168722 -0800 40@@ -81,6 +81,12 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn 41 PRUint32 maxBytes); 42 static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, 43 SECItem *data); 44+static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, 45+ PRBool append, 46+ PRUint32 maxBytes); 47+static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, 48+ PRUint16 ex_type, 49+ SECItem *data); 50 51 /* 52 * Write bytes. Using this function means the SECItem structure 53@@ -259,6 +265,8 @@ static const ssl3HelloExtensionHandler s 54 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, 55 { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, 56 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, 57+ { ssl_signed_certificate_timestamp_xtn, 58+ &ssl3_ClientHandleSignedCertTimestampXtn }, 59 { -1, NULL } 60 }; 61 62@@ -287,7 +295,9 @@ ssl3HelloExtensionSender clientHelloSend 63 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, 64 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, 65 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, 66- { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn } 67+ { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, 68+ { ssl_signed_certificate_timestamp_xtn, 69+ &ssl3_ClientSendSignedCertTimestampXtn } 70 /* any extra entries will appear as { 0, NULL } */ 71 }; 72 73@@ -2379,3 +2389,65 @@ ssl3_AppendPaddingExtension(sslSocket *s 74 75 return extensionLen; 76 } 77+ 78+/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp 79+ * extension for TLS ClientHellos. */ 80+static PRInt32 81+ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append, 82+ PRUint32 maxBytes) 83+{ 84+ PRInt32 extension_length = 2 /* extension_type */ + 85+ 2 /* length(extension_data) */; 86+ 87+ /* Only send the extension if processing is enabled. */ 88+ if (!ss->opt.enableSignedCertTimestamps) 89+ return 0; 90+ 91+ if (append && maxBytes >= extension_length) { 92+ SECStatus rv; 93+ /* extension_type */ 94+ rv = ssl3_AppendHandshakeNumber(ss, 95+ ssl_signed_certificate_timestamp_xtn, 96+ 2); 97+ if (rv != SECSuccess) 98+ goto loser; 99+ /* zero length */ 100+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 101+ if (rv != SECSuccess) 102+ goto loser; 103+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 104+ ssl_signed_certificate_timestamp_xtn; 105+ } else if (maxBytes < extension_length) { 106+ PORT_Assert(0); 107+ return 0; 108+ } 109+ 110+ return extension_length; 111+loser: 112+ return -1; 113+} 114+ 115+static SECStatus 116+ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, 117+ SECItem *data) 118+{ 119+ /* We do not yet know whether we'll be resuming a session or creating 120+ * a new one, so we keep a pointer to the data in the TLSExtensionData 121+ * structure. This pointer is only valid in the scope of 122+ * ssl3_HandleServerHello, and, if not resuming a session, the data is 123+ * copied once a new session structure has been set up. 124+ * All parsing is currently left to the application and we accept 125+ * everything, including empty data. 126+ */ 127+ SECItem *scts = &ss->xtnData.signedCertTimestamps; 128+ PORT_Assert(!scts->data && !scts->len); 129+ 130+ if (!data->len) { 131+ /* Empty extension data: RFC 6962 mandates non-empty contents. */ 132+ return SECFailure; 133+ } 134+ *scts = *data; 135+ /* Keep track of negotiated extensions. */ 136+ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 137+ return SECSuccess; 138+} 139diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h 140--- a/nss/lib/ssl/ssl.h 2014-01-17 18:00:11.213237373 -0800 141+++ b/nss/lib/ssl/ssl.h 2014-01-17 18:38:15.791045050 -0800 142@@ -181,6 +181,9 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF 143 */ 144 #define SSL_ENABLE_ALPN 26 145 146+/* Request Signed Certificate Timestamps via TLS extension (client) */ 147+#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 27 148+ 149 #ifdef SSL_DEPRECATED_FUNCTION 150 /* Old deprecated function names */ 151 SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on); 152@@ -483,6 +486,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertifi 153 */ 154 SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd); 155 156+/* SSL_PeerSignedCertTimestamps returns the signed_certificate_timestamp 157+ * extension data provided by the TLS server. The return value is a pointer 158+ * to an internal SECItem that contains the returned response (as a serialized 159+ * SignedCertificateTimestampList, see RFC 6962). The returned pointer is only 160+ * valid until the callback function that calls SSL_PeerSignedCertTimestamps 161+ * (e.g. the authenticate certificate hook, or the handshake callback) returns. 162+ * 163+ * If no Signed Certificate Timestamps were given by the server then the result 164+ * will be empty. If there was an error, then the result will be NULL. 165+ * 166+ * You must set the SSL_ENABLE_SIGNED_CERT_TIMESTAMPS option to indicate support 167+ * for Signed Certificate Timestamps to a server. 168+ * 169+ * libssl does not do any parsing or validation of the response itself. 170+ */ 171+SSL_IMPORT const SECItem * SSL_PeerSignedCertTimestamps(PRFileDesc *fd); 172+ 173 /* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses 174 * in the fd's data, which may be sent as part of a server side cert_status 175 * handshake message. Parameter |responses| is for the server certificate of 176diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h 177--- a/nss/lib/ssl/sslimpl.h 2014-01-17 18:11:28.314468184 -0800 178+++ b/nss/lib/ssl/sslimpl.h 2014-01-17 18:27:22.540248428 -0800 179@@ -337,6 +337,7 @@ typedef struct sslOptionsStr { 180 unsigned int enableOCSPStapling : 1; /* 25 */ 181 unsigned int enableNPN : 1; /* 26 */ 182 unsigned int enableALPN : 1; /* 27 */ 183+ unsigned int enableSignedCertTimestamps : 1; /* 28 */ 184 } sslOptions; 185 186 typedef enum { sslHandshakingUndetermined = 0, 187@@ -719,6 +720,11 @@ struct sslSessionIDStr { 188 * resumption handshake to the original handshake. */ 189 SECItem originalHandshakeHash; 190 191+ /* Signed certificate timestamps received in a TLS extension. 192+ ** (used only in client). 193+ */ 194+ SECItem signedCertTimestamps; 195+ 196 /* This lock is lazily initialized by CacheSID when a sid is first 197 * cached. Before then, there is no need to lock anything because 198 * the sid isn't being shared by anything. 199@@ -827,6 +833,18 @@ struct TLSExtensionDataStr { 200 * is beyond ssl3_HandleClientHello function. */ 201 SECItem *sniNameArr; 202 PRUint32 sniNameArrSize; 203+ 204+ /* Signed Certificate Timestamps extracted from the TLS extension. 205+ * (client only). 206+ * This container holds a temporary pointer to the extension data, 207+ * until a session structure (the sec.ci.sid of an sslSocket) is setup 208+ * that can hold a permanent copy of the data 209+ * (in sec.ci.sid.u.ssl3.signedCertTimestamps). 210+ * The data pointed to by this structure is neither explicitly allocated 211+ * nor copied: the pointer points to the handshake message buffer and is 212+ * only valid in the scope of ssl3_HandleServerHello. 213+ */ 214+ SECItem signedCertTimestamps; 215 }; 216 217 typedef SECStatus (*sslRestartTarget)(sslSocket *); 218diff -pu a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c 219--- a/nss/lib/ssl/sslnonce.c 2014-01-17 18:11:28.314468184 -0800 220+++ b/nss/lib/ssl/sslnonce.c 2014-01-17 18:23:17.956207890 -0800 221@@ -131,6 +131,9 @@ ssl_DestroySID(sslSessionID *sid) 222 if (sid->u.ssl3.originalHandshakeHash.data) { 223 SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); 224 } 225+ if (sid->u.ssl3.signedCertTimestamps.data) { 226+ SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE); 227+ } 228 229 if (sid->u.ssl3.lock) { 230 PR_DestroyRWLock(sid->u.ssl3.lock); 231diff -pu a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c 232--- a/nss/lib/ssl/sslsock.c 2014-01-17 18:04:43.127747463 -0800 233+++ b/nss/lib/ssl/sslsock.c 2014-01-17 18:44:09.246889487 -0800 234@@ -87,7 +87,8 @@ static sslOptions ssl_defaults = { 235 PR_TRUE, /* cbcRandomIV */ 236 PR_FALSE, /* enableOCSPStapling */ 237 PR_TRUE, /* enableNPN */ 238- PR_FALSE /* enableALPN */ 239+ PR_FALSE, /* enableALPN */ 240+ PR_FALSE /* enableSignedCertTimestamps */ 241 }; 242 243 /* 244@@ -787,6 +788,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh 245 ss->opt.enableALPN = on; 246 break; 247 248+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: 249+ ss->opt.enableSignedCertTimestamps = on; 250+ break; 251+ 252 default: 253 PORT_SetError(SEC_ERROR_INVALID_ARGS); 254 rv = SECFailure; 255@@ -859,6 +864,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh 256 case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; 257 case SSL_ENABLE_NPN: on = ss->opt.enableNPN; break; 258 case SSL_ENABLE_ALPN: on = ss->opt.enableALPN; break; 259+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: 260+ on = ss->opt.enableSignedCertTimestamps; 261+ break; 262 263 default: 264 PORT_SetError(SEC_ERROR_INVALID_ARGS); 265@@ -922,6 +930,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBo 266 break; 267 case SSL_ENABLE_NPN: on = ssl_defaults.enableNPN; break; 268 case SSL_ENABLE_ALPN: on = ssl_defaults.enableALPN; break; 269+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: 270+ on = ssl_defaults.enableSignedCertTimestamps; 271+ break; 272 273 default: 274 PORT_SetError(SEC_ERROR_INVALID_ARGS); 275@@ -1097,6 +1108,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo 276 ssl_defaults.enableALPN = on; 277 break; 278 279+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS: 280+ ssl_defaults.enableSignedCertTimestamps = on; 281+ break; 282+ 283 default: 284 PORT_SetError(SEC_ERROR_INVALID_ARGS); 285 return SECFailure; 286@@ -1921,6 +1936,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc 287 return &ss->sec.ci.sid->peerCertStatus; 288 } 289 290+const SECItem * 291+SSL_PeerSignedCertTimestamps(PRFileDesc *fd) 292+{ 293+ sslSocket *ss = ssl_FindSocket(fd); 294+ 295+ if (!ss) { 296+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerSignedCertTimestamps", 297+ SSL_GETPID(), fd)); 298+ return NULL; 299+ } 300+ 301+ if (!ss->sec.ci.sid) { 302+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 303+ return NULL; 304+ } 305+ 306+ if (ss->sec.ci.sid->version < SSL_LIBRARY_VERSION_3_0) { 307+ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); 308+ return NULL; 309+ } 310+ return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps; 311+} 312+ 313 SECStatus 314 SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) { 315 sslSocket *ss = ssl_FindSocket(fd); 316diff -pu a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h 317--- a/nss/lib/ssl/sslt.h 2014-01-17 18:10:16.793281867 -0800 318+++ b/nss/lib/ssl/sslt.h 2014-01-17 18:23:17.956207890 -0800 319@@ -202,6 +202,7 @@ typedef enum { 320 ssl_signature_algorithms_xtn = 13, 321 ssl_use_srtp_xtn = 14, 322 ssl_app_layer_protocol_xtn = 16, 323+ ssl_signed_certificate_timestamp_xtn = 18, /* RFC 6962 */ 324 ssl_session_ticket_xtn = 35, 325 ssl_next_proto_nego_xtn = 13172, 326 ssl_channel_id_xtn = 30032, 327@@ -209,6 +210,6 @@ typedef enum { 328 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ 329 } SSLExtensionType; 330 331-#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */ 332+#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */ 333 334 #endif /* __sslt_h_ */ 335