Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / third_party / nss / patches / signedcertificatetimestamps.patch
bloba0c5d2c21a9a0ba0cfede6e57032f4396f8f7b59
1 diff --git a/ssl/ssl.h b/ssl/ssl.h
2 index 80717db..e9f5fb0 100644
3 --- a/ssl/ssl.h
4 +++ b/ssl/ssl.h
5 @@ -191,6 +191,9 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
6 #define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in
7 * handshakes. */
9 +/* Request Signed Certificate Timestamps via TLS extension (client) */
10 +#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 29
12 #ifdef SSL_DEPRECATED_FUNCTION
13 /* Old deprecated function names */
14 SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
15 @@ -493,6 +496,23 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
17 SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
19 +/* SSL_PeerSignedCertTimestamps returns the signed_certificate_timestamp
20 + * extension data provided by the TLS server. The return value is a pointer
21 + * to an internal SECItem that contains the returned response (as a serialized
22 + * SignedCertificateTimestampList, see RFC 6962). The returned pointer is only
23 + * valid until the callback function that calls SSL_PeerSignedCertTimestamps
24 + * (e.g. the authenticate certificate hook, or the handshake callback) returns.
25 + *
26 + * If no Signed Certificate Timestamps were given by the server then the result
27 + * will be empty. If there was an error, then the result will be NULL.
28 + *
29 + * You must set the SSL_ENABLE_SIGNED_CERT_TIMESTAMPS option to indicate support
30 + * for Signed Certificate Timestamps to a server.
31 + *
32 + * libssl does not do any parsing or validation of the response itself.
33 + */
34 +SSL_IMPORT const SECItem * SSL_PeerSignedCertTimestamps(PRFileDesc *fd);
36 /* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses
37 * in the fd's data, which may be sent as part of a server side cert_status
38 * handshake message. Parameter |responses| is for the server certificate of
39 diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
40 index 6a4a443..54c5b80 100644
41 --- a/ssl/ssl3con.c
42 +++ b/ssl/ssl3con.c
43 @@ -6752,6 +6752,14 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
44 sid->u.ssl3.sessionIDLength = sidBytes.len;
45 PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
47 + /* Copy Signed Certificate Timestamps, if any. */
48 + if (ss->xtnData.signedCertTimestamps.data) {
49 + rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
50 + &ss->xtnData.signedCertTimestamps);
51 + if (rv != SECSuccess)
52 + goto loser;
53 + }
55 ss->ssl3.hs.isResuming = PR_FALSE;
56 if (ss->ssl3.hs.kea_def->signKeyType != sign_null) {
57 /* All current cipher suites other than those with sign_null (i.e.,
58 @@ -6765,6 +6773,10 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
61 winner:
62 + /* Clean up the temporary pointer to the handshake buffer. */
63 + ss->xtnData.signedCertTimestamps.data = NULL;
64 + ss->xtnData.signedCertTimestamps.len = 0;
66 /* If we will need a ChannelID key then we make the callback now. This
67 * allows the handshake to be restarted cleanly if the callback returns
68 * SECWouldBlock. */
69 @@ -6790,6 +6802,9 @@ alert_loser:
70 (void)SSL3_SendAlert(ss, alert_fatal, desc);
72 loser:
73 + /* Clean up the temporary pointer to the handshake buffer. */
74 + ss->xtnData.signedCertTimestamps.data = NULL;
75 + ss->xtnData.signedCertTimestamps.len = 0;
76 errCode = ssl_MapLowLevelError(errCode);
77 return SECFailure;
79 diff --git a/ssl/ssl3ext.c b/ssl/ssl3ext.c
80 index 4d17587..c18d6f6 100644
81 --- a/ssl/ssl3ext.c
82 +++ b/ssl/ssl3ext.c
83 @@ -90,6 +90,12 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
84 PRUint32 maxBytes);
85 static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
86 SECItem *data);
87 +static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss,
88 + PRBool append,
89 + PRUint32 maxBytes);
90 +static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss,
91 + PRUint16 ex_type,
92 + SECItem *data);
94 static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
95 PRUint32 maxBytes);
96 @@ -275,6 +281,8 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
97 { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
98 { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
99 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
100 + { ssl_signed_certificate_timestamp_xtn,
101 + &ssl3_ClientHandleSignedCertTimestampXtn },
102 { -1, NULL }
105 @@ -303,6 +311,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
106 { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
107 { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
108 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
109 + { ssl_signed_certificate_timestamp_xtn,
110 + &ssl3_ClientSendSignedCertTimestampXtn },
111 { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
112 { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
113 /* any extra entries will appear as { 0, NULL } */
114 @@ -2616,3 +2626,65 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
116 return SECSuccess;
119 +/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
120 + * extension for TLS ClientHellos. */
121 +static PRInt32
122 +ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
123 + PRUint32 maxBytes)
125 + PRInt32 extension_length = 2 /* extension_type */ +
126 + 2 /* length(extension_data) */;
128 + /* Only send the extension if processing is enabled. */
129 + if (!ss->opt.enableSignedCertTimestamps)
130 + return 0;
132 + if (append && maxBytes >= extension_length) {
133 + SECStatus rv;
134 + /* extension_type */
135 + rv = ssl3_AppendHandshakeNumber(ss,
136 + ssl_signed_certificate_timestamp_xtn,
137 + 2);
138 + if (rv != SECSuccess)
139 + goto loser;
140 + /* zero length */
141 + rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
142 + if (rv != SECSuccess)
143 + goto loser;
144 + ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
145 + ssl_signed_certificate_timestamp_xtn;
146 + } else if (maxBytes < extension_length) {
147 + PORT_Assert(0);
148 + return 0;
151 + return extension_length;
152 +loser:
153 + return -1;
156 +static SECStatus
157 +ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
158 + SECItem *data)
160 + /* We do not yet know whether we'll be resuming a session or creating
161 + * a new one, so we keep a pointer to the data in the TLSExtensionData
162 + * structure. This pointer is only valid in the scope of
163 + * ssl3_HandleServerHello, and, if not resuming a session, the data is
164 + * copied once a new session structure has been set up.
165 + * All parsing is currently left to the application and we accept
166 + * everything, including empty data.
167 + */
168 + SECItem *scts = &ss->xtnData.signedCertTimestamps;
169 + PORT_Assert(!scts->data && !scts->len);
171 + if (!data->len) {
172 + /* Empty extension data: RFC 6962 mandates non-empty contents. */
173 + return SECFailure;
175 + *scts = *data;
176 + /* Keep track of negotiated extensions. */
177 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
178 + return SECSuccess;
180 diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
181 index c4c87b4..0fd0a89 100644
182 --- a/ssl/sslimpl.h
183 +++ b/ssl/sslimpl.h
184 @@ -339,6 +339,7 @@ typedef struct sslOptionsStr {
185 unsigned int enableALPN : 1; /* 27 */
186 unsigned int reuseServerECDHEKey : 1; /* 28 */
187 unsigned int enableFallbackSCSV : 1; /* 29 */
188 + unsigned int enableSignedCertTimestamps : 1; /* 30 */
189 } sslOptions;
191 typedef enum { sslHandshakingUndetermined = 0,
192 @@ -721,6 +722,11 @@ struct sslSessionIDStr {
193 * resumption handshake to the original handshake. */
194 SECItem originalHandshakeHash;
196 + /* Signed certificate timestamps received in a TLS extension.
197 + ** (used only in client).
198 + */
199 + SECItem signedCertTimestamps;
201 /* This lock is lazily initialized by CacheSID when a sid is first
202 * cached. Before then, there is no need to lock anything because
203 * the sid isn't being shared by anything.
204 @@ -835,6 +841,18 @@ struct TLSExtensionDataStr {
205 * is beyond ssl3_HandleClientHello function. */
206 SECItem *sniNameArr;
207 PRUint32 sniNameArrSize;
209 + /* Signed Certificate Timestamps extracted from the TLS extension.
210 + * (client only).
211 + * This container holds a temporary pointer to the extension data,
212 + * until a session structure (the sec.ci.sid of an sslSocket) is setup
213 + * that can hold a permanent copy of the data
214 + * (in sec.ci.sid.u.ssl3.signedCertTimestamps).
215 + * The data pointed to by this structure is neither explicitly allocated
216 + * nor copied: the pointer points to the handshake message buffer and is
217 + * only valid in the scope of ssl3_HandleServerHello.
218 + */
219 + SECItem signedCertTimestamps;
222 typedef SECStatus (*sslRestartTarget)(sslSocket *);
223 diff --git a/ssl/sslnonce.c b/ssl/sslnonce.c
224 index c45849d..cefdda6 100644
225 --- a/ssl/sslnonce.c
226 +++ b/ssl/sslnonce.c
227 @@ -131,6 +131,9 @@ ssl_DestroySID(sslSessionID *sid)
228 if (sid->u.ssl3.originalHandshakeHash.data) {
229 SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
231 + if (sid->u.ssl3.signedCertTimestamps.data) {
232 + SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
235 if (sid->u.ssl3.lock) {
236 PR_DestroyRWLock(sid->u.ssl3.lock);
237 diff --git a/ssl/sslsock.c b/ssl/sslsock.c
238 index 6a6c8d1..72058f5 100644
239 --- a/ssl/sslsock.c
240 +++ b/ssl/sslsock.c
241 @@ -89,7 +89,8 @@ static sslOptions ssl_defaults = {
242 PR_TRUE, /* enableNPN */
243 PR_FALSE, /* enableALPN */
244 PR_TRUE, /* reuseServerECDHEKey */
245 - PR_FALSE /* enableFallbackSCSV */
246 + PR_FALSE, /* enableFallbackSCSV */
247 + PR_FALSE, /* enableSignedCertTimestamps */
251 @@ -807,6 +808,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
252 ss->opt.enableFallbackSCSV = on;
253 break;
255 + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
256 + ss->opt.enableSignedCertTimestamps = on;
257 + break;
259 default:
260 PORT_SetError(SEC_ERROR_INVALID_ARGS);
261 rv = SECFailure;
262 @@ -882,6 +887,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
263 case SSL_REUSE_SERVER_ECDHE_KEY:
264 on = ss->opt.reuseServerECDHEKey; break;
265 case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
266 + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
267 + on = ss->opt.enableSignedCertTimestamps;
268 + break;
270 default:
271 PORT_SetError(SEC_ERROR_INVALID_ARGS);
272 @@ -951,6 +959,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
273 case SSL_ENABLE_FALLBACK_SCSV:
274 on = ssl_defaults.enableFallbackSCSV;
275 break;
276 + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
277 + on = ssl_defaults.enableSignedCertTimestamps;
278 + break;
280 default:
281 PORT_SetError(SEC_ERROR_INVALID_ARGS);
282 @@ -1134,6 +1145,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
283 ssl_defaults.enableFallbackSCSV = on;
284 break;
286 + case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
287 + ssl_defaults.enableSignedCertTimestamps = on;
288 + break;
290 default:
291 PORT_SetError(SEC_ERROR_INVALID_ARGS);
292 return SECFailure;
293 @@ -1963,6 +1978,29 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
294 return &ss->sec.ci.sid->peerCertStatus;
297 +const SECItem *
298 +SSL_PeerSignedCertTimestamps(PRFileDesc *fd)
300 + sslSocket *ss = ssl_FindSocket(fd);
302 + if (!ss) {
303 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerSignedCertTimestamps",
304 + SSL_GETPID(), fd));
305 + return NULL;
308 + if (!ss->sec.ci.sid) {
309 + PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
310 + return NULL;
313 + if (ss->sec.ci.sid->version < SSL_LIBRARY_VERSION_3_0) {
314 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
315 + return NULL;
317 + return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps;
320 SECStatus
321 SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
322 sslSocket *ss = ssl_FindSocket(fd);
323 diff --git a/ssl/sslt.h b/ssl/sslt.h
324 index fe0ad07..c36b8c7 100644
325 --- a/ssl/sslt.h
326 +++ b/ssl/sslt.h
327 @@ -202,6 +202,7 @@ typedef enum {
328 ssl_signature_algorithms_xtn = 13,
329 ssl_use_srtp_xtn = 14,
330 ssl_app_layer_protocol_xtn = 16,
331 + ssl_signed_certificate_timestamp_xtn = 18, /* RFC 6962 */
332 ssl_padding_xtn = 21,
333 ssl_session_ticket_xtn = 35,
334 ssl_next_proto_nego_xtn = 13172,
335 @@ -210,6 +211,6 @@ typedef enum {
336 ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
337 } SSLExtensionType;
339 -#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */
340 +#define SSL_MAX_EXTENSIONS 13 /* doesn't include ssl_padding_xtn. */
342 #endif /* __sslt_h_ */