• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
2index 67cc3a7..4cf02aa 100644
3--- a/net/third_party/nss/ssl/ssl.h
4+++ b/net/third_party/nss/ssl/ssl.h
5@@ -161,6 +161,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
6  */
7 #define SSL_CBC_RANDOM_IV 23
8 #define SSL_ENABLE_OCSP_STAPLING       24 /* Request OCSP stapling (client) */
9+/* Request Signed Certificate Timestamps via TLS extension (client) */
10+#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 25
11
12 #ifdef SSL_DEPRECATED_FUNCTION
13 /* Old deprecated function names */
14@@ -464,6 +466,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
15  */
16 SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
17
18+/* SSL_PeerSignedCertTimestamps returns the signed_certificate_timestamp
19+ * extension data provided by the TLS server. The return value is a pointer
20+ * to an internal SECItem that contains the returned response (as a serialized
21+ * SignedCertificateTimestampList, see RFC 6962). The returned pointer is only
22+ * valid until the callback function that calls SSL_PeerSignedCertTimestamps
23+ * (e.g. the authenticate certificate hook, or the handshake callback) returns.
24+ *
25+ * If no Signed Certificate Timestamps were given by the server then the result
26+ * will be empty. If there was an error, then the result will be NULL.
27+ *
28+ * You must set the SSL_ENABLE_SIGNED_CERT_TIMESTAMPS option to indicate support
29+ * for Signed Certificate Timestamps to a server.
30+ *
31+ * libssl does not do any parsing or validation of the response itself.
32+ */
33+SSL_IMPORT const SECItem * SSL_PeerSignedCertTimestamps(PRFileDesc *fd);
34+
35 /* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses
36  * in the fd's data, which may be sent as part of a server side cert_status
37  * handshake message. Parameter |responses| is for the server certificate of
38diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
39index 0f1eea4..c2d9eeb 100644
40--- a/net/third_party/nss/ssl/ssl3con.c
41+++ b/net/third_party/nss/ssl/ssl3con.c
42@@ -6639,10 +6639,22 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
43     sid->u.ssl3.sessionIDLength = sidBytes.len;
44     PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
45
46+    /* Copy Signed Certificate Timestamps, if any. */
47+    if (ss->xtnData.signedCertTimestamps.data) {
48+	rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
49+			      &ss->xtnData.signedCertTimestamps);
50+	if (rv != SECSuccess)
51+	    goto loser;
52+    }
53+
54     ss->ssl3.hs.isResuming = PR_FALSE;
55     ss->ssl3.hs.ws         = wait_server_cert;
56
57 winner:
58+    /* Clean up the temporary pointer to the handshake buffer. */
59+    ss->xtnData.signedCertTimestamps.data = NULL;
60+    ss->xtnData.signedCertTimestamps.len = 0;
61+
62     /* If we will need a ChannelID key then we make the callback now. This
63      * allows the handshake to be restarted cleanly if the callback returns
64      * SECWouldBlock. */
65@@ -6668,6 +6680,9 @@ alert_loser:
66     (void)SSL3_SendAlert(ss, alert_fatal, desc);
67
68 loser:
69+    /* Clean up the temporary pointer to the handshake buffer. */
70+    ss->xtnData.signedCertTimestamps.data = NULL;
71+    ss->xtnData.signedCertTimestamps.len = 0;
72     errCode = ssl_MapLowLevelError(errCode);
73     return SECFailure;
74 }
75diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
76index adb81ed..02e104d 100644
77--- a/net/third_party/nss/ssl/ssl3ext.c
78+++ b/net/third_party/nss/ssl/ssl3ext.c
79@@ -81,6 +81,12 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
80                                          PRUint32 maxBytes);
81 static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
82                                              SECItem *data);
83+static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss,
84+						     PRBool append,
85+						     PRUint32 maxBytes);
86+static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss,
87+							 PRUint16 ex_type,
88+							 SECItem *data);
89
90 /*
91  * Write bytes.  Using this function means the SECItem structure
92@@ -259,6 +265,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
93     { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
94     { ssl_channel_id_xtn,         &ssl3_ClientHandleChannelIDXtn },
95     { ssl_cert_status_xtn,        &ssl3_ClientHandleStatusRequestXtn },
96+    { ssl_signed_certificate_timestamp_xtn,
97+      &ssl3_ClientHandleSignedCertTimestampXtn },
98     { -1, NULL }
99 };
100
101@@ -287,7 +295,9 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
102     { ssl_use_srtp_xtn,               &ssl3_SendUseSRTPXtn },
103     { ssl_channel_id_xtn,             &ssl3_ClientSendChannelIDXtn },
104     { ssl_cert_status_xtn,            &ssl3_ClientSendStatusRequestXtn },
105-    { ssl_signature_algorithms_xtn,   &ssl3_ClientSendSigAlgsXtn }
106+    { ssl_signature_algorithms_xtn,   &ssl3_ClientSendSigAlgsXtn },
107+    { ssl_signed_certificate_timestamp_xtn,
108+      &ssl3_ClientSendSignedCertTimestampXtn }
109     /* any extra entries will appear as { 0, NULL }    */
110 };
111
112@@ -2364,3 +2374,65 @@ ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
113
114     return extensionLen;
115 }
116+
117+/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
118+ * extension for TLS ClientHellos. */
119+static PRInt32
120+ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
121+				      PRUint32 maxBytes)
122+{
123+    PRInt32 extension_length = 2 /* extension_type */ +
124+	    2 /* length(extension_data) */;
125+
126+    /* Only send the extension if processing is enabled. */
127+    if (!ss->opt.enableSignedCertTimestamps)
128+	return 0;
129+
130+    if (append && maxBytes >= extension_length) {
131+	SECStatus rv;
132+	/* extension_type */
133+	rv = ssl3_AppendHandshakeNumber(ss,
134+					ssl_signed_certificate_timestamp_xtn,
135+					2);
136+	if (rv != SECSuccess)
137+	    goto loser;
138+	/* zero length */
139+	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
140+	if (rv != SECSuccess)
141+	    goto loser;
142+	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
143+		ssl_signed_certificate_timestamp_xtn;
144+    } else if (maxBytes < extension_length) {
145+	PORT_Assert(0);
146+	return 0;
147+    }
148+
149+    return extension_length;
150+loser:
151+    return -1;
152+}
153+
154+static SECStatus
155+ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
156+					SECItem *data)
157+{
158+    /* We do not yet know whether we'll be resuming a session or creating
159+     * a new one, so we keep a pointer to the data in the TLSExtensionData
160+     * structure. This pointer is only valid in the scope of
161+     * ssl3_HandleServerHello, and, if not resuming a session, the data is
162+     * copied once a new session structure has been set up.
163+     * All parsing is currently left to the application and we accept
164+     * everything, including empty data.
165+     */
166+    SECItem *scts = &ss->xtnData.signedCertTimestamps;
167+    PORT_Assert(!scts->data && !scts->len);
168+
169+    if (!data->len) {
170+	/* Empty extension data: RFC 6962 mandates non-empty contents. */
171+	return SECFailure;
172+    }
173+    *scts = *data;
174+    /* Keep track of negotiated extensions. */
175+    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
176+    return SECSuccess;
177+}
178diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
179index 79aca60..1e4655f 100644
180--- a/net/third_party/nss/ssl/sslimpl.h
181+++ b/net/third_party/nss/ssl/sslimpl.h
182@@ -312,29 +312,30 @@ typedef struct sslOptionsStr {
183      * list of supported protocols. */
184     SECItem nextProtoNego;
185
186-    unsigned int useSecurity		: 1;  /*  1 */
187-    unsigned int useSocks		: 1;  /*  2 */
188-    unsigned int requestCertificate	: 1;  /*  3 */
189-    unsigned int requireCertificate	: 2;  /*  4-5 */
190-    unsigned int handshakeAsClient	: 1;  /*  6 */
191-    unsigned int handshakeAsServer	: 1;  /*  7 */
192-    unsigned int enableSSL2		: 1;  /*  8 */
193-    unsigned int unusedBit9		: 1;  /*  9 */
194-    unsigned int unusedBit10		: 1;  /* 10 */
195-    unsigned int noCache		: 1;  /* 11 */
196-    unsigned int fdx			: 1;  /* 12 */
197-    unsigned int v2CompatibleHello	: 1;  /* 13 */
198-    unsigned int detectRollBack  	: 1;  /* 14 */
199-    unsigned int noStepDown             : 1;  /* 15 */
200-    unsigned int bypassPKCS11           : 1;  /* 16 */
201-    unsigned int noLocks                : 1;  /* 17 */
202-    unsigned int enableSessionTickets   : 1;  /* 18 */
203-    unsigned int enableDeflate          : 1;  /* 19 */
204-    unsigned int enableRenegotiation    : 2;  /* 20-21 */
205-    unsigned int requireSafeNegotiation : 1;  /* 22 */
206-    unsigned int enableFalseStart       : 1;  /* 23 */
207-    unsigned int cbcRandomIV            : 1;  /* 24 */
208-    unsigned int enableOCSPStapling     : 1;  /* 25 */
209+    unsigned int useSecurity		    : 1;  /*  1 */
210+    unsigned int useSocks		    : 1;  /*  2 */
211+    unsigned int requestCertificate	    : 1;  /*  3 */
212+    unsigned int requireCertificate	    : 2;  /*  4-5 */
213+    unsigned int handshakeAsClient	    : 1;  /*  6 */
214+    unsigned int handshakeAsServer	    : 1;  /*  7 */
215+    unsigned int enableSSL2		    : 1;  /*  8 */
216+    unsigned int unusedBit9		    : 1;  /*  9 */
217+    unsigned int unusedBit10		    : 1;  /* 10 */
218+    unsigned int noCache		    : 1;  /* 11 */
219+    unsigned int fdx			    : 1;  /* 12 */
220+    unsigned int v2CompatibleHello	    : 1;  /* 13 */
221+    unsigned int detectRollBack  	    : 1;  /* 14 */
222+    unsigned int noStepDown                 : 1;  /* 15 */
223+    unsigned int bypassPKCS11               : 1;  /* 16 */
224+    unsigned int noLocks                    : 1;  /* 17 */
225+    unsigned int enableSessionTickets       : 1;  /* 18 */
226+    unsigned int enableDeflate              : 1;  /* 19 */
227+    unsigned int enableRenegotiation        : 2;  /* 20-21 */
228+    unsigned int requireSafeNegotiation     : 1;  /* 22 */
229+    unsigned int enableFalseStart           : 1;  /* 23 */
230+    unsigned int cbcRandomIV                : 1;  /* 24 */
231+    unsigned int enableOCSPStapling	    : 1;  /* 25 */
232+    unsigned int enableSignedCertTimestamps : 1;  /* 26 */
233 } sslOptions;
234
235 typedef enum { sslHandshakingUndetermined = 0,
236@@ -713,6 +714,11 @@ struct sslSessionIDStr {
237              * negotiated as it's used to bind the ChannelID signature on the
238              * resumption handshake to the original handshake. */
239 	    SECItem           originalHandshakeHash;
240+
241+	    /* Signed certificate timestamps received in a TLS extension.
242+	    ** (used only in client).
243+	    */
244+	    SECItem	      signedCertTimestamps;
245 	} ssl3;
246     } u;
247 };
248@@ -804,6 +810,18 @@ struct TLSExtensionDataStr {
249      * is beyond ssl3_HandleClientHello function. */
250     SECItem *sniNameArr;
251     PRUint32 sniNameArrSize;
252+
253+    /* Signed Certificate Timestamps extracted from the TLS extension.
254+     * (client only).
255+     * This container holds a temporary pointer to the extension data,
256+     * until a session structure (the sec.ci.sid of an sslSocket) is setup
257+     * that can hold a permanent copy of the data
258+     * (in sec.ci.sid.u.ssl3.signedCertTimestamps).
259+     * The data pointed to by this structure is neither explicitly allocated
260+     * nor copied: the pointer points to the handshake message buffer and is
261+     * only valid in the scope of ssl3_HandleServerHello.
262+     */
263+    SECItem signedCertTimestamps;
264 };
265
266 typedef SECStatus (*sslRestartTarget)(sslSocket *);
267diff --git a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c
268index eb5004c..1ca19ca 100644
269--- a/net/third_party/nss/ssl/sslnonce.c
270+++ b/net/third_party/nss/ssl/sslnonce.c
271@@ -122,7 +122,21 @@ ssl_DestroySID(sslSessionID *sid)
272     if (sid->version < SSL_LIBRARY_VERSION_3_0) {
273 	SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
274 	SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
275+    } else {
276+	if (sid->u.ssl3.sessionTicket.ticket.data) {
277+	    SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE);
278+	}
279+	if (sid->u.ssl3.srvName.data) {
280+	    SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
281+	}
282+	if (sid->u.ssl3.signedCertTimestamps.data) {
283+	    SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
284+	}
285+	if (sid->u.ssl3.originalHandshakeHash.data) {
286+	  SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
287+	}
288     }
289+
290     if (sid->peerID != NULL)
291 	PORT_Free((void *)sid->peerID);		/* CONST */
292
293@@ -142,16 +156,7 @@ ssl_DestroySID(sslSessionID *sid)
294     if ( sid->localCert ) {
295 	CERT_DestroyCertificate(sid->localCert);
296     }
297-    if (sid->u.ssl3.sessionTicket.ticket.data) {
298-	SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE);
299-    }
300-    if (sid->u.ssl3.srvName.data) {
301-	SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
302-    }
303-    if (sid->u.ssl3.originalHandshakeHash.data) {
304-	SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
305-    }
306-
307+
308     PORT_ZFree(sid, sizeof(sslSessionID));
309 }
310
311diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
312index b5c17f0..965215d 100644
313--- a/net/third_party/nss/ssl/sslsock.c
314+++ b/net/third_party/nss/ssl/sslsock.c
315@@ -173,7 +173,8 @@ static sslOptions ssl_defaults = {
316     PR_FALSE,   /* requireSafeNegotiation */
317     PR_FALSE,   /* enableFalseStart   */
318     PR_TRUE,    /* cbcRandomIV        */
319-    PR_FALSE    /* enableOCSPStapling */
320+    PR_FALSE,   /* enableOCSPStapling */
321+    PR_FALSE    /* enableSignedCertTimestamps */
322 };
323
324 /*
325@@ -865,6 +866,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
326        ss->opt.enableOCSPStapling = on;
327        break;
328
329+      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
330+       ss->opt.enableSignedCertTimestamps = on;
331+       break;
332+
333       default:
334 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
335 	rv = SECFailure;
336@@ -935,6 +940,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
337     case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
338     case SSL_CBC_RANDOM_IV:       on = ss->opt.cbcRandomIV;        break;
339     case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
340+    case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
341+       on = ss->opt.enableSignedCertTimestamps;
342+       break;
343
344     default:
345 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
346@@ -996,6 +1004,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
347     case SSL_ENABLE_OCSP_STAPLING:
348        on = ssl_defaults.enableOCSPStapling;
349        break;
350+    case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
351+       on = ssl_defaults.enableSignedCertTimestamps;
352+       break;
353
354     default:
355 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
356@@ -1163,6 +1174,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
357        ssl_defaults.enableOCSPStapling = on;
358        break;
359
360+      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
361+       ssl_defaults.enableSignedCertTimestamps = on;
362+       break;
363+
364       default:
365 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
366 	return SECFailure;
367@@ -1993,6 +2008,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
368     return &ss->sec.ci.sid->peerCertStatus;
369 }
370
371+const SECItem *
372+SSL_PeerSignedCertTimestamps(PRFileDesc *fd)
373+{
374+    sslSocket *ss = ssl_FindSocket(fd);
375+
376+    if (!ss) {
377+       SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerSignedCertTimestamps",
378+		SSL_GETPID(), fd));
379+       return NULL;
380+    }
381+
382+    if (!ss->sec.ci.sid) {
383+       PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
384+       return NULL;
385+    }
386+
387+    if (ss->sec.ci.sid->version < SSL_LIBRARY_VERSION_3_0) {
388+	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
389+	return NULL;
390+    }
391+    return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps;
392+}
393+
394 SECStatus
395 SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
396     sslSocket *ss = ssl_FindSocket(fd);
397@@ -3133,4 +3171,3 @@ loser:
398     }
399     return ss;
400 }
401-
402diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
403index b813c04..1f5e2c6 100644
404--- a/net/third_party/nss/ssl/sslt.h
405+++ b/net/third_party/nss/ssl/sslt.h
406@@ -202,6 +202,7 @@ typedef enum {
407     ssl_signature_algorithms_xtn     = 13,
408     ssl_use_srtp_xtn                 = 14,
409     ssl_app_layer_protocol_xtn       = 16,
410+    ssl_signed_certificate_timestamp_xtn = 18,   /* RFC 6962 */
411     ssl_session_ticket_xtn           = 35,
412     ssl_next_proto_nego_xtn          = 13172,
413     ssl_channel_id_xtn               = 30032,
414@@ -209,6 +210,6 @@ typedef enum {
415     ssl_renegotiation_info_xtn       = 0xff01	/* experimental number */
416 } SSLExtensionType;
417
418-#define SSL_MAX_EXTENSIONS             11 /* doesn't include ssl_padding_xtn. */
419+#define SSL_MAX_EXTENSIONS             12 /* doesn't include ssl_padding_xtn. */
420
421 #endif /* __sslt_h_ */
422