Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(633)

Side by Side Diff: net/third_party/nss/patches/dtls.patch

Issue 9764001: Add DTLS support to NSS, contributed by Eric Rescorla. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Update AUTHORS Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/nss/patches/applypatches.sh ('k') | net/third_party/nss/ssl.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 Index: net/third_party/nss/ssl/SSLerrs.h
2 ===================================================================
3 --- net/third_party/nss/ssl/SSLerrs.h (revision 127709)
4 +++ net/third_party/nss/ssl/SSLerrs.h (working copy)
5 @@ -423,3 +423,9 @@
6
7 ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 121),
8 "SSL received an unexpected Certificate Status handshake message.")
9 +
10 +ER3(SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 122),
11 +"SSL received a malformed Hello Verify Request handshake message.")
12 +
13 +ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 123),
14 +"SSL received an unexpected Hello Verify Request handshake message.")
15 Index: net/third_party/nss/ssl/ssl.h
16 ===================================================================
17 --- net/third_party/nss/ssl/ssl.h (revision 127709)
18 +++ net/third_party/nss/ssl/ssl.h (working copy)
19 @@ -80,6 +80,12 @@
20 SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
21
22 /*
23 +** Imports fd into DTLS, returning a new socket. Copies DTLS configuration
24 +** from model.
25 +*/
26 +SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
27 +
28 +/*
29 ** Enable/disable an ssl mode
30 **
31 ** SSL_SECURITY:
32 @@ -942,6 +948,14 @@
33 PRBool *last_handshake_resumed );
34
35 /*
36 +** How long should we wait before retransmitting the next flight of
37 +** the DTLS handshake? Returns SECFailure if not DTLS or not in a
38 +** handshake.
39 +*/
40 +SSL_IMPORT SECStatus DTLS_GetTimeout(PRFileDesc *socket,
41 + PRIntervalTime *timeout);
42 +
43 +/*
44 * Return a boolean that indicates whether the underlying library
45 * will perform as the caller expects.
46 *
47 Index: net/third_party/nss/ssl/ssl3gthr.c
48 ===================================================================
49 --- net/third_party/nss/ssl/ssl3gthr.c (revision 127709)
50 +++ net/third_party/nss/ssl/ssl3gthr.c (working copy)
51 @@ -50,7 +50,7 @@
52 *
53 * returns 1 if received a complete SSL3 record.
54 * returns 0 if recv returns EOF
55 - * returns -1 if recv returns <0
56 + * returns -1 if recv returns < 0
57 * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
58 *
59 * Caller must hold the recv buf lock.
60 @@ -59,7 +59,8 @@
61 * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
62 * GS_DATA: waiting for the body of the SSL3 record to come in.
63 *
64 - * This loop returns when either (a) an error or EOF occurs,
65 + * This loop returns when either
66 + * (a) an error or EOF occurs,
67 * (b) PR_WOULD_BLOCK_ERROR,
68 * (c) data (entire SSL3 record) has been received.
69 */
70 @@ -167,6 +168,125 @@
71 return rv;
72 }
73
74 +/*
75 + * Read in an entire DTLS record.
76 + *
77 + * Blocks here for blocking sockets, otherwise returns -1 with
78 + * PR_WOULD_BLOCK_ERROR when socket would block.
79 + *
80 + * This is simpler than SSL because we are reading on a datagram socket
81 + * and datagrams must contain >=1 complete records.
82 + *
83 + * returns 1 if received a complete DTLS record.
84 + * returns 0 if recv returns EOF
85 + * returns -1 if recv returns < 0
86 + * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
87 + *
88 + * Caller must hold the recv buf lock.
89 + *
90 + * This loop returns when either
91 + * (a) an error or EOF occurs,
92 + * (b) PR_WOULD_BLOCK_ERROR,
93 + * (c) data (entire DTLS record) has been received.
94 + */
95 +static int
96 +dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
97 +{
98 + int nb;
99 + int err;
100 + int rv = 1;
101 +
102 + SSL_TRC(30, ("dtls_GatherData"));
103 +
104 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
105 +
106 + gs->state = GS_HEADER;
107 + gs->offset = 0;
108 +
109 + if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
110 + gs->dtlsPacketOffset = 0;
111 + gs->dtlsPacket.len = 0;
112 +
113 + /* Resize to the maximum possible size so we can fit a full datagram */
114 + /* This is the max fragment length for an encrypted fragment
115 + ** plus the size of the record header.
116 + ** This magic constant is copied from ssl3_GatherData, with 5 changed
117 + ** to 13 (the size of the record header).
118 + */
119 + if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
120 + err = sslBuffer_Grow(&gs->dtlsPacket,
121 + MAX_FRAGMENT_LENGTH + 2048 + 13);
122 + if (err) { /* realloc has set error code to no mem. */
123 + return err;
124 + }
125 + }
126 +
127 + /* recv() needs to read a full datagram at a time */
128 + nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
129 +
130 + if (nb > 0) {
131 + PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
132 + } else if (nb == 0) {
133 + /* EOF */
134 + SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
135 + rv = 0;
136 + return rv;
137 + } else /* if (nb < 0) */ {
138 + SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
139 + PR_GetError()));
140 + rv = SECFailure;
141 + return rv;
142 + }
143 +
144 + gs->dtlsPacket.len = nb;
145 + }
146 +
147 + /* At this point we should have >=1 complete records lined up in
148 + * dtlsPacket. Read off the header.
149 + */
150 + if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) {
151 + SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
152 + "too short to contain header", SSL_GETPID(), ss->fd));
153 + PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
154 + gs->dtlsPacketOffset = 0;
155 + gs->dtlsPacket.len = 0;
156 + rv = SECFailure;
157 + return rv;
158 + }
159 + memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13);
160 + gs->dtlsPacketOffset += 13;
161 +
162 + /* Have received SSL3 record header in gs->hdr. */
163 + gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
164 +
165 + if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
166 + SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
167 + "to contain rest of body", SSL_GETPID(), ss->fd));
168 + PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
169 + gs->dtlsPacketOffset = 0;
170 + gs->dtlsPacket.len = 0;
171 + rv = SECFailure;
172 + return rv;
173 + }
174 +
175 + /* OK, we have at least one complete packet, copy into inbuf */
176 + if (gs->remainder > gs->inbuf.space) {
177 + err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
178 + if (err) { /* realloc has set error code to no mem. */
179 + return err;
180 + }
181 + }
182 +
183 + memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
184 + gs->remainder);
185 + gs->inbuf.len = gs->remainder;
186 + gs->offset = gs->remainder;
187 + gs->dtlsPacketOffset += gs->remainder;
188 + gs->state = GS_INIT;
189 +
190 + return 1;
191 +}
192 +
193 /* Gather in a record and when complete, Handle that record.
194 * Repeat this until the handshake is complete,
195 * or until application data is available.
196 @@ -190,6 +310,8 @@
197 int rv;
198 PRBool canFalseStart = PR_FALSE;
199
200 + SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
201 +
202 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
203 do {
204 /* Without this, we may end up wrongly reporting
205 @@ -224,7 +346,24 @@
206 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
207 } else {
208 /* bring in the next sslv3 record. */
209 - rv = ssl3_GatherData(ss, &ss->gs, flags);
210 + if (!IS_DTLS(ss)) {
211 + rv = ssl3_GatherData(ss, &ss->gs, flags);
212 + } else {
213 + rv = dtls_GatherData(ss, &ss->gs, flags);
214 +
215 + /* If we got a would block error, that means that no data was
216 + * available, so we check the timer to see if it's time to
217 + * retransmit */
218 + if (rv == SECFailure &&
219 + (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
220 + ssl_GetSSL3HandshakeLock(ss);
221 + dtls_CheckTimer(ss);
222 + ssl_ReleaseSSL3HandshakeLock(ss);
223 + /* Restore the error in case something succeeded */
224 + PORT_SetError(PR_WOULD_BLOCK_ERROR);
225 + }
226 + }
227 +
228 if (rv <= 0) {
229 return rv;
230 }
231 @@ -236,6 +375,20 @@
232 */
233 cText.type = (SSL3ContentType)ss->gs.hdr[0];
234 cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
235 +
236 + if (IS_DTLS(ss)) {
237 + int i;
238 +
239 + cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
240 + /* DTLS sequence number */
241 + cText.seq_num.high = 0; cText.seq_num.low = 0;
242 + for (i = 0; i < 4; i++) {
243 + cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
244 + cText.seq_num.high |= ss->gs.hdr[3 + i];
245 + cText.seq_num.low |= ss->gs.hdr[7 + i];
246 + }
247 + }
248 +
249 cText.buf = &ss->gs.inbuf;
250 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
251 }
252 Index: net/third_party/nss/ssl/derive.c
253 ===================================================================
254 --- net/third_party/nss/ssl/derive.c (revision 127709)
255 +++ net/third_party/nss/ssl/derive.c (working copy)
256 @@ -583,6 +583,8 @@
257 * arguments were all valid but the slot cannot be bypassed.
258 */
259
260 +/* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */
261 +
262 SECStatus
263 SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey,
264 PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites,
265 Index: net/third_party/nss/ssl/sslerr.h
266 ===================================================================
267 --- net/third_party/nss/ssl/sslerr.h (revision 127709)
268 +++ net/third_party/nss/ssl/sslerr.h (working copy)
269 @@ -215,6 +215,9 @@
270
271 SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 121),
272
273 +SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
274 +SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
275 +
276 SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
277 } SSLErrorCodes;
278 #endif /* NO_SECURITY_ERROR_ENUM */
279 Index: net/third_party/nss/ssl/ssldef.c
280 ===================================================================
281 --- net/third_party/nss/ssl/ssldef.c (revision 127709)
282 +++ net/third_party/nss/ssl/ssldef.c (working copy)
283 @@ -138,6 +138,11 @@
284 return rv;
285 }
286 sent += rv;
287 +
288 + if (IS_DTLS(ss) && (len > sent)) {
289 + /* We got a partial write so just return it */
290 + return sent;
291 + }
292 } while (len > sent);
293 ss->lastWriteBlocked = 0;
294 return sent;
295 Index: net/third_party/nss/ssl/sslimpl.h
296 ===================================================================
297 --- net/third_party/nss/ssl/sslimpl.h (revision 127709)
298 +++ net/third_party/nss/ssl/sslimpl.h (working copy)
299 @@ -62,6 +62,7 @@
300 #endif
301 #include "nssrwlk.h"
302 #include "prthread.h"
303 +#include "prclist.h"
304
305 #include "sslt.h" /* for some formerly private types, now public */
306
307 @@ -195,6 +196,10 @@
308
309 #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
310
311 +#define INITIAL_DTLS_TIMEOUT_MS 1000 /* Default value from RFC 4347 = 1s*/
312 +#define MAX_DTLS_TIMEOUT_MS 60000 /* 1 minute */
313 +#define DTLS_FINISHED_TIMER_MS 120000 /* Time to wait in FINISHED state */
314 +
315 typedef struct sslBufferStr sslBuffer;
316 typedef struct sslConnectInfoStr sslConnectInfo;
317 typedef struct sslGatherStr sslGather;
318 @@ -287,6 +292,8 @@
319 /* Flags interpreted by ssl send functions. */
320 #define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000
321 #define ssl_SEND_FLAG_NO_BUFFER 0x20000000
322 +#define ssl_SEND_FLAG_USE_EPOCH 0x10000000 /* DTLS only */
323 +#define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
324 #define ssl_SEND_FLAG_MASK 0x7f000000
325
326 /*
327 @@ -448,8 +455,15 @@
328 ** The portion of the SSL record header put here always comes off the wire
329 ** as plaintext, never ciphertext.
330 ** For SSL2, the plaintext portion is two bytes long. For SSl3 it is 5.
331 + ** For DTLS it is 13.
332 */
333 - unsigned char hdr[5]; /* ssl 2 & 3 */
334 + unsigned char hdr[13]; /* ssl 2 & 3 or dtls */
335 +
336 + /* Buffer for DTLS data read off the wire as a single datagram */
337 + sslBuffer dtlsPacket;
338 +
339 + /* the start of the buffered DTLS record in dtlsPacket */
340 + unsigned int dtlsPacketOffset;
341 };
342
343 /* sslGather.state */
344 @@ -521,6 +535,10 @@
345 PRUint32 low;
346 } SSL3SequenceNumber;
347
348 +typedef PRUint16 DTLSEpoch;
349 +
350 +typedef void (*DTLSTimerCb)(sslSocket *);
351 +
352 #define MAX_MAC_CONTEXT_BYTES 400
353 #define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8)
354
355 @@ -547,6 +565,20 @@
356 PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS];
357 } ssl3KeyMaterial;
358
359 +/* The DTLS anti-replay window. Defined here because we need it in
360 + * the cipher spec. Note that this is a ring buffer but left and
361 + * right represent the true window, with modular arithmetic used to
362 + * map them onto the buffer.
363 + */
364 +#define DTLS_RECVD_RECORDS_WINDOW 1024 /* Packets; approximate
365 + * Must be divisible by 8
366 + */
367 +typedef struct DTLSRecvdRecordsStr {
368 + unsigned char data[DTLS_RECVD_RECORDS_WINDOW/8];
369 + PRUint64 left;
370 + PRUint64 right;
371 +} DTLSRecvdRecords;
372 +
373 /*
374 ** These are the "specs" in the "ssl3" struct.
375 ** Access to the pointers to these specs, and all the specs' contents
376 @@ -582,6 +614,8 @@
377 SECItem srvVirtName; /* for server: name that was negotiated
378 * with a client. For client - is
379 * always set to NULL.*/
380 + DTLSEpoch epoch;
381 + DTLSRecvdRecords recvdRecords;
382 } ssl3CipherSpec;
383
384 typedef enum { never_cached,
385 @@ -777,6 +811,17 @@
386 typedef SECStatus (*sslRestartTarget)(sslSocket *);
387
388 /*
389 +** A DTLS queued message (potentially to be retransmitted)
390 +*/
391 +typedef struct DTLSQueuedMessageStr {
392 + PRCList link; /* The linked list link */
393 + DTLSEpoch epoch; /* The epoch to use */
394 + SSL3ContentType type; /* The message type */
395 + unsigned char *data; /* The data */
396 + PRUint16 len; /* The data length */
397 +} DTLSQueuedMessage;
398 +
399 +/*
400 ** This is the "hs" member of the "ssl3" struct.
401 ** This entire struct is protected by ssl3HandshakeLock
402 */
403 @@ -831,6 +876,30 @@
404 sslRestartTarget restartTarget;
405 /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
406 PRBool cacheSID;
407 +
408 + /* This group of values is used for DTLS */
409 + PRUint16 sendMessageSeq; /* The sending message sequence
410 + * number */
411 + PRCList * lastMessageFlight; /* The last message flight we sent .
412 + * This is a pointer because
413 + * ssl_FreeSocket relocates the
414 + * structure in DEBUG mode, which
415 + * messes up the list macros */
416 + PRUint16 maxMessageSent; /* The largest message we sent */
417 + PRUint16 recvMessageSeq; /* The receiving message sequence
418 + * number */
419 + sslBuffer recvdFragments; /* The fragments we have received in
420 + * a bitmask */
421 + PRInt32 recvdHighWater; /* The high water mark for fragments
422 + * received. -1 means no reassembly
423 + * in progress. */
424 + unsigned char cookie[32]; /* The cookie */
425 + unsigned char cookieLen; /* The length of the cookie */
426 + PRIntervalTime rtTimerStarted; /* When the timer was started */
427 + DTLSTimerCb rtTimerCb; /* The function to call on expiry */
428 + PRUint32 rtTimeoutMs; /* The length of the current timeout
429 + * used for backoff (in ms) */
430 + PRUint32 rtRetries; /* The retry counter */
431 } SSL3HandshakeState;
432
433
434 @@ -882,11 +951,18 @@
435 */
436 SECItem nextProto;
437 SSLNextProtoState nextProtoState;
438 +
439 + PRUint16 mtu; /* Our estimate of the MTU */
440 };
441
442 +#define DTLS_MAX_MTU 1500 /* Ethernet MTU but without subtracting the
443 + * headers, so slightly larger than expected */
444 +#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
445 +
446 typedef struct {
447 SSL3ContentType type;
448 SSL3ProtocolVersion version;
449 + SSL3SequenceNumber seq_num; /* DTLS only */
450 sslBuffer * buf;
451 } SSL3Ciphertext;
452
453 @@ -1188,6 +1264,9 @@
454 /* True when the current session is a stateless resume. */
455 PRBool statelessResume;
456 TLSExtensionData xtnData;
457 +
458 + /* Whether we are doing stream or datagram mode */
459 + SSLProtocolVariant protocolVariant;
460 };
461
462
463 @@ -1321,7 +1400,35 @@
464 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
465
466 extern PRBool ssl3_CanFalseStart(sslSocket *ss);
467 +extern SECStatus
468 +ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
469 + PRBool isServer,
470 + PRBool isDTLS,
471 + SSL3ContentType type,
472 + const SSL3Opaque * pIn,
473 + PRUint32 contentLen,
474 + sslBuffer * wrBuf);
475 +extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch,
476 + SSL3ContentType type,
477 + const SSL3Opaque* pIn, PRInt32 nIn,
478 + PRInt32 flags);
479
480 +#ifdef NSS_ENABLE_ZLIB
481 +/*
482 + * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a
483 + * maximum TLS record payload of 2**14 bytes, that's 29 bytes.
484 + */
485 +#define SSL3_COMPRESSION_MAX_EXPANSION 29
486 +#else /* !NSS_ENABLE_ZLIB */
487 +#define SSL3_COMPRESSION_MAX_EXPANSION 0
488 +#endif
489 +
490 +/*
491 + * make sure there is room in the write buffer for padding and
492 + * other compression and cryptographic expansions.
493 + */
494 +#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION
495 +
496 #define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock)
497 #define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock )
498 #define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock)
499 @@ -1417,6 +1524,7 @@
500 extern void ssl_FreeSocket(struct sslSocketStr *ssl);
501 extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
502 SSL3AlertDescription desc);
503 +extern SECStatus ssl3_DecodeError(sslSocket *ss);
504
505 extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
506 CERTCertificate * cert,
507 @@ -1436,7 +1544,7 @@
508 /*
509 * SSL3 specific routines
510 */
511 -SECStatus ssl3_SendClientHello(sslSocket *ss);
512 +SECStatus ssl3_SendClientHello(sslSocket *ss, PRBool resending);
513
514 /*
515 * input into the SSL3 machinery from the actualy network reading code
516 @@ -1531,6 +1639,8 @@
517 unsigned char *cs, int *size);
518
519 extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
520 +extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
521 + PRUint32 length);
522
523 extern void ssl3_DestroySSL3Info(sslSocket *ss);
524
525 @@ -1556,6 +1666,7 @@
526 extern SECStatus ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf,
527 unsigned int bufLen, SSL3Hashes *hashes,
528 PRBool bypassPKCS11);
529 +extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName);
530 extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms);
531 extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src,
532 PRInt32 bytes);
533 @@ -1724,6 +1835,42 @@
534 CERTCertList* list);
535 #endif /* NSS_PLATFORM_CLIENT_AUTH */
536
537 +/**************** DTLS-specific functions **************/
538 +extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
539 +extern void dtls_FreeQueuedMessages(PRCList *lst);
540 +extern void dtls_FreeHandshakeMessages(PRCList *lst);
541 +
542 +extern SECStatus dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf);
543 +extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss,
544 + SSL3Opaque *b, PRUint32 length);
545 +extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss);
546 +extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
547 + const SSL3Opaque *pIn, PRInt32 nIn);
548 +extern SECStatus dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
549 +extern SECStatus dtls_CompressMACEncryptRecord(sslSocket *ss,
550 + DTLSEpoch epoch,
551 + PRBool use_epoch,
552 + SSL3ContentType type,
553 + const SSL3Opaque *pIn,
554 + PRUint32 contentLen,
555 + sslBuffer *wrBuf);
556 +SECStatus ssl3_DisableNonDTLSSuites(sslSocket * ss);
557 +extern SECStatus dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb);
558 +extern SECStatus dtls_RestartTimer(sslSocket *ss, PRBool backoff,
559 + DTLSTimerCb cb);
560 +extern void dtls_CheckTimer(sslSocket *ss);
561 +extern void dtls_CancelTimer(sslSocket *ss);
562 +extern void dtls_FinishedTimerCb(sslSocket *ss);
563 +extern void dtls_SetMTU(sslSocket *ss, PRUint16 advertised);
564 +extern void dtls_InitRecvdRecords(DTLSRecvdRecords *records);
565 +extern int dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq);
566 +extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq);
567 +extern void dtls_RehandshakeCleanup(sslSocket *ss);
568 +extern SSL3ProtocolVersion
569 +dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv);
570 +extern SSL3ProtocolVersion
571 +dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv);
572 +
573 /********************** misc calls *********************/
574
575 extern int ssl_MapLowLevelError(int hiLevelError);
576 Index: net/third_party/nss/ssl/manifest.mn
577 ===================================================================
578 --- net/third_party/nss/ssl/manifest.mn (revision 127709)
579 +++ net/third_party/nss/ssl/manifest.mn (working copy)
580 @@ -51,6 +51,7 @@
581
582 CSRCS = \
583 derive.c \
584 + dtls1con.c \
585 prelib.c \
586 ssl3con.c \
587 ssl3gthr.c \
588 Index: net/third_party/nss/ssl/ssl3prot.h
589 ===================================================================
590 --- net/third_party/nss/ssl/ssl3prot.h (revision 127709)
591 +++ net/third_party/nss/ssl/ssl3prot.h (working copy)
592 @@ -61,6 +61,9 @@
593
594 #define SSL3_RECORD_HEADER_LENGTH 5
595
596 +/* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
597 +#define DTLS_RECORD_HEADER_LENGTH 13
598 +
599 #define MAX_FRAGMENT_LENGTH 16384
600
601 typedef enum {
602 @@ -150,6 +153,7 @@
603 hello_request = 0,
604 client_hello = 1,
605 server_hello = 2,
606 + hello_verify_request = 3,
607 new_session_ticket = 4,
608 certificate = 11,
609 server_key_exchange = 12,
610 Index: net/third_party/nss/ssl/sslcon.c
611 ===================================================================
612 --- net/third_party/nss/ssl/sslcon.c (revision 127709)
613 +++ net/third_party/nss/ssl/sslcon.c (working copy)
614 @@ -1249,7 +1249,12 @@
615
616 ssl_GetRecvBufLock(ss);
617
618 - if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
619 + /* The special case DTLS logic is needed here because the SSL/TLS
620 + * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake
621 + * (ss->version == 0) but with DTLS it gets confused, so we force the
622 + * SSL3 version.
623 + */
624 + if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) {
625 /* Wait for handshake to complete, or application data to arrive. */
626 rv = ssl3_GatherCompleteHandshake(ss, 0);
627 } else {
628 @@ -3120,7 +3125,7 @@
629
630 ssl_GetSSL3HandshakeLock(ss);
631 ssl_GetXmitBufLock(ss);
632 - rv = ssl3_SendClientHello(ss);
633 + rv = ssl3_SendClientHello(ss, PR_FALSE);
634 ssl_ReleaseXmitBufLock(ss);
635 ssl_ReleaseSSL3HandshakeLock(ss);
636
637 Index: net/third_party/nss/ssl/sslsecur.c
638 ===================================================================
639 --- net/third_party/nss/ssl/sslsecur.c (revision 127709)
640 +++ net/third_party/nss/ssl/sslsecur.c (working copy)
641 @@ -615,6 +615,7 @@
642 if (!(flags & PR_MSG_PEEK)) {
643 ss->gs.readOffset += amount;
644 }
645 + PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset);
646 rv = amount;
647
648 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
649 Index: net/third_party/nss/ssl/sslsock.c
650 ===================================================================
651 --- net/third_party/nss/ssl/sslsock.c (revision 127709)
652 +++ net/third_party/nss/ssl/sslsock.c (working copy)
653 @@ -194,11 +194,20 @@
654 /*
655 * default range of enabled SSL/TLS protocols
656 */
657 -static SSLVersionRange versions_defaults = {
658 +static SSLVersionRange versions_defaults_stream = {
659 SSL_LIBRARY_VERSION_3_0,
660 SSL_LIBRARY_VERSION_TLS_1_0
661 };
662
663 +static SSLVersionRange versions_defaults_datagram = {
664 + SSL_LIBRARY_VERSION_TLS_1_1,
665 + SSL_LIBRARY_VERSION_TLS_1_1
666 +};
667 +
668 +#define VERSIONS_DEFAULTS(variant) \
669 + (variant == ssl_variant_stream ? &versions_defaults_stream : \
670 + &versions_defaults_datagram)
671 +
672 sslSessionIDLookupFunc ssl_sid_lookup;
673 sslSessionIDCacheFunc ssl_sid_cache;
674 sslSessionIDUncacheFunc ssl_sid_uncache;
675 @@ -217,7 +226,7 @@
676 #define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
677
678 /* forward declarations. */
679 -static sslSocket *ssl_NewSocket(PRBool makeLocks);
680 +static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
681 static SECStatus ssl_MakeLocks(sslSocket *ss);
682 static void ssl_SetDefaultsFromEnvironment(void);
683 static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
684 @@ -281,7 +290,13 @@
685 sslSocket *ss;
686 SECStatus rv;
687
688 - ss = ssl_NewSocket((PRBool)(!os->opt.noLocks));
689 + /* Not implemented for datagram */
690 + if (IS_DTLS(os)) {
691 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
692 + return NULL;
693 + }
694 +
695 + ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
696 if (ss) {
697 ss->opt = os->opt;
698 ss->opt.useSocks = PR_FALSE;
699 @@ -698,6 +713,13 @@
700 break;
701
702 case SSL_ENABLE_TLS:
703 + if (IS_DTLS(ss)) {
704 + if (on) {
705 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
706 + rv = SECFailure; /* not allowed */
707 + }
708 + break;
709 + }
710 ssl_EnableTLS(&ss->vrange, on);
711 ss->preferredCipher = NULL;
712 if (ss->cipherSpecs) {
713 @@ -708,6 +730,13 @@
714 break;
715
716 case SSL_ENABLE_SSL3:
717 + if (IS_DTLS(ss)) {
718 + if (on) {
719 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
720 + rv = SECFailure; /* not allowed */
721 + }
722 + break;
723 + }
724 ssl_EnableSSL3(&ss->vrange, on);
725 ss->preferredCipher = NULL;
726 if (ss->cipherSpecs) {
727 @@ -718,6 +747,13 @@
728 break;
729
730 case SSL_ENABLE_SSL2:
731 + if (IS_DTLS(ss)) {
732 + if (on) {
733 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
734 + rv = SECFailure; /* not allowed */
735 + }
736 + break;
737 + }
738 ss->opt.enableSSL2 = on;
739 if (on) {
740 ss->opt.v2CompatibleHello = on;
741 @@ -743,6 +779,13 @@
742 break;
743
744 case SSL_V2_COMPATIBLE_HELLO:
745 + if (IS_DTLS(ss)) {
746 + if (on) {
747 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
748 + rv = SECFailure; /* not allowed */
749 + }
750 + break;
751 + }
752 ss->opt.v2CompatibleHello = on;
753 if (!on) {
754 ss->opt.enableSSL2 = on;
755 @@ -938,10 +981,10 @@
756 case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient; break;
757 case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer; break;
758 case SSL_ENABLE_TLS:
759 - on = versions_defaults.max >= SSL_LIBRARY_VERSION_TLS_1_0;
760 + on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
761 break;
762 case SSL_ENABLE_SSL3:
763 - on = versions_defaults.min == SSL_LIBRARY_VERSION_3_0;
764 + on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
765 break;
766 case SSL_ENABLE_SSL2: on = ssl_defaults.enableSSL2; break;
767 case SSL_NO_CACHE: on = ssl_defaults.noCache; break;
768 @@ -1034,11 +1077,11 @@
769 break;
770
771 case SSL_ENABLE_TLS:
772 - ssl_EnableTLS(&versions_defaults, on);
773 + ssl_EnableTLS(&versions_defaults_stream, on);
774 break;
775
776 case SSL_ENABLE_SSL3:
777 - ssl_EnableSSL3(&versions_defaults, on);
778 + ssl_EnableSSL3(&versions_defaults_stream, on);
779 break;
780
781 case SSL_ENABLE_SSL2:
782 @@ -1360,8 +1403,8 @@
783
784
785 /* LOCKS ??? XXX */
786 -PRFileDesc *
787 -SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
788 +static PRFileDesc *
789 +ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
790 {
791 sslSocket * ns = NULL;
792 PRStatus rv;
793 @@ -1374,10 +1417,10 @@
794
795 if (model == NULL) {
796 /* Just create a default socket if we're given NULL for the model */
797 - ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks));
798 + ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
799 } else {
800 sslSocket * ss = ssl_FindSocket(model);
801 - if (ss == NULL) {
802 + if (ss == NULL || ss->protocolVariant != variant) {
803 SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
804 SSL_GETPID(), model));
805 return NULL;
806 @@ -1403,6 +1446,18 @@
807 return fd;
808 }
809
810 +PRFileDesc *
811 +SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
812 +{
813 + return ssl_ImportFD(model, fd, ssl_variant_stream);
814 +}
815 +
816 +PRFileDesc *
817 +DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
818 +{
819 + return ssl_ImportFD(model, fd, ssl_variant_datagram);
820 +}
821 +
822 SECStatus
823 SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
824 void *arg)
825 @@ -1667,9 +1722,18 @@
826 ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
827 SSL3ProtocolVersion version)
828 {
829 - return protocolVariant == ssl_variant_stream &&
830 - version >= SSL_LIBRARY_VERSION_3_0 &&
831 - version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED;
832 + switch (protocolVariant) {
833 + case ssl_variant_stream:
834 + return (version >= SSL_LIBRARY_VERSION_3_0 &&
835 + version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
836 + case ssl_variant_datagram:
837 + return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
838 + version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
839 + default:
840 + /* Can't get here */
841 + PORT_Assert(PR_FALSE);
842 + return PR_FALSE;
843 + }
844 }
845
846 /* Returns PR_TRUE if the given version range is valid and
847 @@ -1689,13 +1753,24 @@
848 SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
849 SSLVersionRange *vrange)
850 {
851 - if (protocolVariant != ssl_variant_stream || !vrange) {
852 + if (!vrange) {
853 PORT_SetError(SEC_ERROR_INVALID_ARGS);
854 return SECFailure;
855 }
856
857 - vrange->min = SSL_LIBRARY_VERSION_3_0;
858 - vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
859 + switch (protocolVariant) {
860 + case ssl_variant_stream:
861 + vrange->min = SSL_LIBRARY_VERSION_3_0;
862 + vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
863 + break;
864 + case ssl_variant_datagram:
865 + vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
866 + vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
867 + break;
868 + default:
869 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
870 + return SECFailure;
871 + }
872
873 return SECSuccess;
874 }
875 @@ -1704,12 +1779,13 @@
876 SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
877 SSLVersionRange *vrange)
878 {
879 - if (protocolVariant != ssl_variant_stream || !vrange) {
880 + if ((protocolVariant != ssl_variant_stream &&
881 + protocolVariant != ssl_variant_datagram) || !vrange) {
882 PORT_SetError(SEC_ERROR_INVALID_ARGS);
883 return SECFailure;
884 }
885
886 - *vrange = versions_defaults;
887 + *vrange = *VERSIONS_DEFAULTS(protocolVariant);
888
889 return SECSuccess;
890 }
891 @@ -1723,7 +1799,7 @@
892 return SECFailure;
893 }
894
895 - versions_defaults = *vrange;
896 + *VERSIONS_DEFAULTS(protocolVariant) = *vrange;
897
898 return SECSuccess;
899 }
900 @@ -2830,7 +2906,7 @@
901 ** Create a newsocket structure for a file descriptor.
902 */
903 static sslSocket *
904 -ssl_NewSocket(PRBool makeLocks)
905 +ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
906 {
907 sslSocket *ss;
908
909 @@ -2851,7 +2927,7 @@
910 ss->opt = ssl_defaults;
911 ss->opt.useSocks = PR_FALSE;
912 ss->opt.noLocks = !makeLocks;
913 - ss->vrange = versions_defaults;
914 + ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
915
916 ss->peerID = NULL;
917 ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
918 @@ -2907,6 +2983,7 @@
919 PORT_Free(ss);
920 ss = NULL;
921 }
922 + ss->protocolVariant = protocolVariant;
923 }
924 return ss;
925 }
926 Index: net/third_party/nss/ssl/ssl3con.c
927 ===================================================================
928 --- net/third_party/nss/ssl/ssl3con.c (revision 127709)
929 +++ net/third_party/nss/ssl/ssl3con.c (working copy)
930 @@ -42,6 +42,8 @@
931 * ***** END LICENSE BLOCK ***** */
932 /* $Id: ssl3con.c,v 1.173 2012/03/18 00:31:19 wtc%google.com Exp $ */
933
934 +/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
935 +
936 #include "cert.h"
937 #include "ssl.h"
938 #include "cryptohi.h" /* for DSAU_ stuff */
939 @@ -92,6 +94,7 @@
940 static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
941 const unsigned char *b,
942 unsigned int l);
943 +static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
944
945 static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
946 int maxOutputLen, const unsigned char *input,
947 @@ -221,22 +224,6 @@
948 #endif /* NSS_ENABLE_ECC */
949 };
950
951 -#ifdef NSS_ENABLE_ZLIB
952 -/*
953 - * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a
954 - * maximum TLS record payload of 2**14 bytes, that's 29 bytes.
955 - */
956 -#define SSL3_COMPRESSION_MAX_EXPANSION 29
957 -#else /* !NSS_ENABLE_ZLIB */
958 -#define SSL3_COMPRESSION_MAX_EXPANSION 0
959 -#endif
960 -
961 -/*
962 - * make sure there is room in the write buffer for padding and
963 - * other compression and cryptographic expansions.
964 - */
965 -#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION
966 -
967 #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
968
969
970 @@ -517,6 +504,7 @@
971 case hello_request: rv = "hello_request (0)"; break;
972 case client_hello: rv = "client_hello (1)"; break;
973 case server_hello: rv = "server_hello (2)"; break;
974 + case hello_verify_request: rv = "hello_verify_request (3)"; break;
975 case certificate: rv = "certificate (11)"; break;
976 case server_key_exchange: rv = "server_key_exchange (12)"; break;
977 case certificate_request: rv = "certificate_request (13)"; break;
978 @@ -656,7 +644,7 @@
979 suite->isPresent = PR_FALSE;
980 continue;
981 }
982 - cipher_alg=bulk_cipher_defs[cipher_def->bulk_cipher_alg ].calg;
983 + cipher_alg = bulk_cipher_defs[cipher_def->bulk_cipher_alg].calg;
984 PORT_Assert( alg2Mech[cipher_alg].calg == cipher_alg);
985 cipher_mech = alg2Mech[cipher_alg].cmech;
986 exchKeyType =
987 @@ -1148,7 +1136,7 @@
988 ** ssl3_DestroySSL3Info
989 ** Caller must hold SpecWriteLock.
990 */
991 -static void
992 +void
993 ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
994 {
995 PRBool freeit = (PRBool)(!spec->bypassCiphers);
996 @@ -1228,6 +1216,12 @@
997 return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */
998 }
999
1000 + if (IS_DTLS(ss)) {
1001 + /* Double-check that we did not pick an RC4 suite */
1002 + PORT_Assert((suite_def->bulk_cipher_alg != cipher_rc4) &&
1003 + (suite_def->bulk_cipher_alg != cipher_rc4_40) &&
1004 + (suite_def->bulk_cipher_alg != cipher_rc4_56));
1005 + }
1006
1007 cipher = suite_def->bulk_cipher_alg;
1008 kea = suite_def->key_exchange_alg;
1009 @@ -1754,6 +1748,7 @@
1010 ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
1011 {
1012 ssl3CipherSpec * pwSpec;
1013 + ssl3CipherSpec * cwSpec;
1014 SECStatus rv;
1015
1016 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
1017 @@ -1763,6 +1758,7 @@
1018 PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
1019
1020 pwSpec = ss->ssl3.pwSpec;
1021 + cwSpec = ss->ssl3.cwSpec;
1022
1023 if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) {
1024 rv = ssl3_DeriveMasterSecret(ss, pms);
1025 @@ -1794,7 +1790,32 @@
1026 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1027 rv = SECFailure;
1028 }
1029 + if (rv != SECSuccess) {
1030 + goto done;
1031 + }
1032
1033 + /* Generic behaviors -- common to all crypto methods */
1034 + if (!IS_DTLS(ss)) {
1035 + pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = 0;
1036 + } else {
1037 + if (cwSpec->epoch == PR_UINT16_MAX) {
1038 + /* The problem here is that we have rehandshaked too many
1039 + * times (you are not allowed to wrap the epoch). The
1040 + * spec says you should be discarding the connection
1041 + * and start over, so not much we can do here. */
1042 + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1043 + rv = SECFailure;
1044 + goto done;
1045 + }
1046 + /* The sequence number has the high 16 bits as the epoch. */
1047 + pwSpec->epoch = cwSpec->epoch + 1;
1048 + pwSpec->read_seq_num.high = pwSpec->write_seq_num.high =
1049 + pwSpec->epoch << 16;
1050 +
1051 + dtls_InitRecvdRecords(&pwSpec->recvdRecords);
1052 + }
1053 + pwSpec->read_seq_num.low = pwSpec->write_seq_num.low = 0;
1054 +
1055 done:
1056 ssl_ReleaseSpecWriteLock(ss); /******************************/
1057 if (rv != SECSuccess)
1058 @@ -1834,6 +1855,7 @@
1059 ssl3_ComputeRecordMAC(
1060 ssl3CipherSpec * spec,
1061 PRBool useServerMacKey,
1062 + PRBool isDTLS,
1063 SSL3ContentType type,
1064 SSL3ProtocolVersion version,
1065 SSL3SequenceNumber seq_num,
1066 @@ -1871,8 +1893,16 @@
1067 isTLS = PR_FALSE;
1068 } else {
1069 /* New TLS hash includes version. */
1070 - temp[9] = MSB(version);
1071 - temp[10] = LSB(version);
1072 + if (isDTLS) {
1073 + SSL3ProtocolVersion dtls_version;
1074 +
1075 + dtls_version = dtls_TLSVersionToDTLSVersion(version);
1076 + temp[9] = MSB(dtls_version);
1077 + temp[10] = LSB(dtls_version);
1078 + } else {
1079 + temp[9] = MSB(version);
1080 + temp[10] = LSB(version);
1081 + }
1082 temp[11] = MSB(inputLength);
1083 temp[12] = LSB(inputLength);
1084 tempLen = 13;
1085 @@ -2022,9 +2052,10 @@
1086 }
1087
1088 /* Caller must hold the spec read lock. */
1089 -static SECStatus
1090 +SECStatus
1091 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
1092 PRBool isServer,
1093 + PRBool isDTLS,
1094 SSL3ContentType type,
1095 const SSL3Opaque * pIn,
1096 PRUint32 contentLen,
1097 @@ -2035,10 +2066,12 @@
1098 PRUint32 macLen = 0;
1099 PRUint32 fragLen;
1100 PRUint32 p1Len, p2Len, oddLen = 0;
1101 + PRUint16 headerLen;
1102 int ivLen = 0;
1103 int cipherBytes = 0;
1104
1105 cipher_def = cwSpec->cipher_def;
1106 + headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
1107
1108 if (cipher_def->type == type_block &&
1109 cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
1110 @@ -2048,20 +2081,20 @@
1111 * record.
1112 */
1113 ivLen = cipher_def->iv_size;
1114 - if (ivLen > wrBuf->space - SSL3_RECORD_HEADER_LENGTH) {
1115 + if (ivLen > wrBuf->space - headerLen) {
1116 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1117 return SECFailure;
1118 }
1119 - rv = PK11_GenerateRandom(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, ivLen);
1120 + rv = PK11_GenerateRandom(wrBuf->buf + headerLen, ivLen);
1121 if (rv != SECSuccess) {
1122 ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
1123 return rv;
1124 }
1125 rv = cwSpec->encode( cwSpec->encodeContext,
1126 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH,
1127 + wrBuf->buf + headerLen,
1128 &cipherBytes, /* output and actual outLen */
1129 ivLen, /* max outlen */
1130 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH,
1131 + wrBuf->buf + headerLen,
1132 ivLen); /* input and inputLen*/
1133 if (rv != SECSuccess || cipherBytes != ivLen) {
1134 PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
1135 @@ -2073,20 +2106,20 @@
1136 int outlen;
1137 rv = cwSpec->compressor(
1138 cwSpec->compressContext,
1139 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen, &outlen,
1140 - wrBuf->space - SSL3_RECORD_HEADER_LENGTH - ivLen, pIn, contentLen);
1141 + wrBuf->buf + headerLen + ivLen, &outlen,
1142 + wrBuf->space - headerLen - ivLen, pIn, contentLen);
1143 if (rv != SECSuccess)
1144 return rv;
1145 - pIn = wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen;
1146 + pIn = wrBuf->buf + headerLen + ivLen;
1147 contentLen = outlen;
1148 }
1149
1150 /*
1151 * Add the MAC
1152 */
1153 - rv = ssl3_ComputeRecordMAC( cwSpec, isServer,
1154 + rv = ssl3_ComputeRecordMAC( cwSpec, isServer, isDTLS,
1155 type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
1156 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + contentLen, &macLen);
1157 + wrBuf->buf + headerLen + ivLen + contentLen, &macLen);
1158 if (rv != SECSuccess) {
1159 ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
1160 return SECFailure;
1161 @@ -2113,7 +2146,7 @@
1162 PORT_Assert((fragLen % cipher_def->block_size) == 0);
1163
1164 /* Pad according to TLS rules (also acceptable to SSL3). */
1165 - pBuf = &wrBuf->buf[SSL3_RECORD_HEADER_LENGTH + ivLen + fragLen - 1];
1166 + pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1];
1167 for (i = padding_length + 1; i > 0; --i) {
1168 *pBuf-- = padding_length;
1169 }
1170 @@ -2130,13 +2163,12 @@
1171 p2Len += oddLen;
1172 PORT_Assert( (cipher_def->block_size < 2) || \
1173 (p2Len % cipher_def->block_size) == 0);
1174 - memmove(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + p1Len,
1175 - pIn + p1Len, oddLen);
1176 + memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len, oddLen);
1177 }
1178 if (p1Len > 0) {
1179 int cipherBytesPart1 = -1;
1180 rv = cwSpec->encode( cwSpec->encodeContext,
1181 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen, /* output */
1182 + wrBuf->buf + headerLen + ivLen, /* output */
1183 &cipherBytesPart1, /* actual outlen */
1184 p1Len, /* max outlen */
1185 pIn, p1Len); /* input, and inputlen */
1186 @@ -2150,10 +2182,10 @@
1187 if (p2Len > 0) {
1188 int cipherBytesPart2 = -1;
1189 rv = cwSpec->encode( cwSpec->encodeContext,
1190 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + p1Len,
1191 + wrBuf->buf + headerLen + ivLen + p1Len,
1192 &cipherBytesPart2, /* output and actual outLen */
1193 p2Len, /* max outlen */
1194 - wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + ivLen + p1Len,
1195 + wrBuf->buf + headerLen + ivLen + p1Len,
1196 p2Len); /* input and inputLen*/
1197 PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len);
1198 if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) {
1199 @@ -2164,15 +2196,33 @@
1200 }
1201 PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
1202
1203 + wrBuf->len = cipherBytes + headerLen;
1204 + wrBuf->buf[0] = type;
1205 + if (isDTLS) {
1206 + SSL3ProtocolVersion version;
1207 +
1208 + version = dtls_TLSVersionToDTLSVersion(cwSpec->version);
1209 + wrBuf->buf[1] = MSB(version);
1210 + wrBuf->buf[2] = LSB(version);
1211 + wrBuf->buf[3] = (unsigned char)(cwSpec->write_seq_num.high >> 24);
1212 + wrBuf->buf[4] = (unsigned char)(cwSpec->write_seq_num.high >> 16);
1213 + wrBuf->buf[5] = (unsigned char)(cwSpec->write_seq_num.high >> 8);
1214 + wrBuf->buf[6] = (unsigned char)(cwSpec->write_seq_num.high >> 0);
1215 + wrBuf->buf[7] = (unsigned char)(cwSpec->write_seq_num.low >> 24);
1216 + wrBuf->buf[8] = (unsigned char)(cwSpec->write_seq_num.low >> 16);
1217 + wrBuf->buf[9] = (unsigned char)(cwSpec->write_seq_num.low >> 8);
1218 + wrBuf->buf[10] = (unsigned char)(cwSpec->write_seq_num.low >> 0);
1219 + wrBuf->buf[11] = MSB(cipherBytes);
1220 + wrBuf->buf[12] = LSB(cipherBytes);
1221 + } else {
1222 + wrBuf->buf[1] = MSB(cwSpec->version);
1223 + wrBuf->buf[2] = LSB(cwSpec->version);
1224 + wrBuf->buf[3] = MSB(cipherBytes);
1225 + wrBuf->buf[4] = LSB(cipherBytes);
1226 + }
1227 +
1228 ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
1229
1230 - wrBuf->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
1231 - wrBuf->buf[0] = type;
1232 - wrBuf->buf[1] = MSB(cwSpec->version);
1233 - wrBuf->buf[2] = LSB(cwSpec->version);
1234 - wrBuf->buf[3] = MSB(cipherBytes);
1235 - wrBuf->buf[4] = LSB(cipherBytes);
1236 -
1237 return SECSuccess;
1238 }
1239
1240 @@ -2194,10 +2244,13 @@
1241 * ssl_SEND_FLAG_FORCE_INTO_BUFFER
1242 * As above, except this suppresses all write attempts, and forces
1243 * all ciphertext into the pending ciphertext buffer.
1244 + * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
1245 + * Forces the use of the provided epoch
1246 *
1247 */
1248 -static PRInt32
1249 +PRInt32
1250 ssl3_SendRecord( sslSocket * ss,
1251 + DTLSEpoch epoch, /* DTLS only */
1252 SSL3ContentType type,
1253 const SSL3Opaque * pIn, /* input buffer */
1254 PRInt32 nIn, /* bytes of input */
1255 @@ -2269,8 +2322,8 @@
1256 sslBuffer secondRecord;
1257
1258 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
1259 - ss->sec.isServer, type, pIn, 1,
1260 - wrBuf);
1261 + ss->sec.isServer, IS_DTLS(ss),
1262 + type, pIn, 1, wrBuf);
1263 if (rv != SECSuccess)
1264 goto spec_locked_loser;
1265
1266 @@ -2282,17 +2335,28 @@
1267 secondRecord.space = wrBuf->space - wrBuf->len;
1268
1269 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
1270 - ss->sec.isServer, type, pIn + 1,
1271 - contentLen - 1, &secondRecord);
1272 + ss->sec.isServer, IS_DTLS(ss),
1273 + type, pIn + 1, contentLen - 1,
1274 + &secondRecord);
1275 if (rv == SECSuccess) {
1276 PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
1277 secondRecord.buf, secondRecord.len));
1278 wrBuf->len += secondRecord.len;
1279 }
1280 } else {
1281 - rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
1282 - ss->sec.isServer, type, pIn,
1283 - contentLen, wrBuf);
1284 + if (!IS_DTLS(ss)) {
1285 + rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
1286 + ss->sec.isServer,
1287 + IS_DTLS(ss),
1288 + type, pIn,
1289 + contentLen, wrBuf);
1290 + } else {
1291 + rv = dtls_CompressMACEncryptRecord(ss, epoch,
1292 + !!(flags & ssl_SEND_FLAG_USE_ EPOCH),
1293 + type, pIn,
1294 + contentLen, wrBuf);
1295 + }
1296 +
1297 if (rv == SECSuccess) {
1298 PRINT_BUF(50, (ss, "send (encrypted) record data:",
1299 wrBuf->buf, wrBuf->len));
1300 @@ -2350,6 +2414,11 @@
1301 }
1302 wrBuf->len -= sent;
1303 if (wrBuf->len) {
1304 + if (IS_DTLS(ss)) {
1305 + /* DTLS just says no in this case. No buffering */
1306 + PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
1307 + return SECFailure;
1308 + }
1309 /* now take all the remaining unsent new ciphertext and
1310 * append it to the buffer of previously unsent ciphertext.
1311 */
1312 @@ -2378,6 +2447,9 @@
1313 PRInt32 discarded = 0;
1314
1315 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
1316 + /* These flags for internal use only */
1317 + PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH |
1318 + ssl_SEND_FLAG_NO_RETRANSMIT)));
1319 if (len < 0 || !in) {
1320 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
1321 return SECFailure;
1322 @@ -2415,7 +2487,11 @@
1323 ssl_GetXmitBufLock(ss);
1324 }
1325 toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
1326 - sent = ssl3_SendRecord(ss, content_application_data,
1327 + /*
1328 + * Note that the 0 epoch is OK because flags will never require
1329 + * its use, as guaranteed by the PORT_Assert above.
1330 + */
1331 + sent = ssl3_SendRecord(ss, 0, content_application_data,
1332 in + totalSent, toSend, flags);
1333 if (sent < 0) {
1334 if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) {
1335 @@ -2450,10 +2526,15 @@
1336 return totalSent + discarded;
1337 }
1338
1339 -/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
1340 +/* Attempt to send buffered handshake messages.
1341 * This function returns SECSuccess or SECFailure, never SECWouldBlock.
1342 * Always set sendBuf.len to 0, even when returning SECFailure.
1343 *
1344 + * Depending on whether we are doing DTLS or not, this either calls
1345 + *
1346 + * - ssl3_FlushHandshakeMessages if non-DTLS
1347 + * - dtls_FlushHandshakeMessages if DTLS
1348 + *
1349 * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(),
1350 * ssl3_AppendHandshake(), ssl3_SendClientHello(),
1351 * ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
1352 @@ -2462,6 +2543,22 @@
1353 static SECStatus
1354 ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
1355 {
1356 + if (IS_DTLS(ss)) {
1357 + return dtls_FlushHandshakeMessages(ss, flags);
1358 + } else {
1359 + return ssl3_FlushHandshakeMessages(ss, flags);
1360 + }
1361 +}
1362 +
1363 +/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
1364 + * This function returns SECSuccess or SECFailure, never SECWouldBlock.
1365 + * Always set sendBuf.len to 0, even when returning SECFailure.
1366 + *
1367 + * Called from ssl3_FlushHandshake
1368 + */
1369 +static SECStatus
1370 +ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
1371 +{
1372 PRInt32 rv = SECSuccess;
1373
1374 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
1375 @@ -2476,7 +2573,7 @@
1376 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1377 rv = SECFailure;
1378 } else {
1379 - rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf,
1380 + rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
1381 ss->sec.ci.sendBuf.len, flags);
1382 }
1383 if (rv < 0) {
1384 @@ -2593,7 +2690,7 @@
1385 rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
1386 if (rv == SECSuccess) {
1387 PRInt32 sent;
1388 - sent = ssl3_SendRecord(ss, content_alert, bytes, 2,
1389 + sent = ssl3_SendRecord(ss, 0, content_alert, bytes, 2,
1390 desc == no_certificate
1391 ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
1392 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
1393 @@ -2667,7 +2764,7 @@
1394 /*
1395 * Send handshake_Failure alert. Set generic error number.
1396 */
1397 -static SECStatus
1398 +SECStatus
1399 ssl3_DecodeError(sslSocket *ss)
1400 {
1401 (void)SSL3_SendAlert(ss, alert_fatal,
1402 @@ -2755,7 +2852,8 @@
1403 default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
1404 }
1405 if (level == alert_fatal) {
1406 - ss->sec.uncache(ss->sec.ci.sid);
1407 + if (!ss->opt.noCache)
1408 + ss->sec.uncache(ss->sec.ci.sid);
1409 if ((ss->ssl3.hs.ws == wait_server_hello) &&
1410 (desc == handshake_failure)) {
1411 /* XXX This is a hack. We're assuming that any handshake failure
1412 @@ -2806,17 +2904,22 @@
1413 if (rv != SECSuccess) {
1414 return rv; /* error code set by ssl3_FlushHandshake */
1415 }
1416 - sent = ssl3_SendRecord(ss, content_change_cipher_spec, &change, 1,
1417 - ssl_SEND_FLAG_FORCE_INTO_BUFFER);
1418 - if (sent < 0) {
1419 - return (SECStatus)sent; /* error code set by ssl3_SendRecord */
1420 + if (!IS_DTLS(ss)) {
1421 + sent = ssl3_SendRecord(ss, 0, content_change_cipher_spec, &change, 1,
1422 + ssl_SEND_FLAG_FORCE_INTO_BUFFER);
1423 + if (sent < 0) {
1424 + return (SECStatus)sent; /* error code set by ssl3_SendRecord */
1425 + }
1426 + } else {
1427 + rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1);
1428 + if (rv != SECSuccess) {
1429 + return rv;
1430 + }
1431 }
1432
1433 /* swap the pending and current write specs. */
1434 ssl_GetSpecWriteLock(ss); /**************************************/
1435 pwSpec = ss->ssl3.pwSpec;
1436 - pwSpec->write_seq_num.high = 0;
1437 - pwSpec->write_seq_num.low = 0;
1438
1439 ss->ssl3.pwSpec = ss->ssl3.cwSpec;
1440 ss->ssl3.cwSpec = pwSpec;
1441 @@ -2829,7 +2932,14 @@
1442 * (Both the read and write sides have changed) destroy it.
1443 */
1444 if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
1445 - ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE/*freeSrvName*/);
1446 + if (!IS_DTLS(ss)) {
1447 + ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE/*freeSrvName*/);
1448 + } else {
1449 + /* With DTLS, we need to set a holddown timer in case the final
1450 + * message got lost */
1451 + ss->ssl3.hs.rtTimeoutMs = DTLS_FINISHED_TIMER_MS;
1452 + dtls_StartTimer(ss, dtls_FinishedTimerCb);
1453 + }
1454 }
1455 ssl_ReleaseSpecWriteLock(ss); /**************************************/
1456
1457 @@ -2878,7 +2988,6 @@
1458 /* Swap the pending and current read specs. */
1459 ssl_GetSpecWriteLock(ss); /*************************************/
1460 prSpec = ss->ssl3.prSpec;
1461 - prSpec->read_seq_num.high = prSpec->read_seq_num.low = 0;
1462
1463 ss->ssl3.prSpec = ss->ssl3.crSpec;
1464 ss->ssl3.crSpec = prSpec;
1465 @@ -2981,6 +3090,11 @@
1466 if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
1467 SSL3ProtocolVersion client_version;
1468 client_version = pms_version.major << 8 | pms_version.minor;
1469 +
1470 + if (IS_DTLS(ss)) {
1471 + client_version = dtls_DTLSVersionToTLSVersion(client_version);
1472 + }
1473 +
1474 if (client_version != ss->clientHelloVersion) {
1475 /* Destroy it. Version roll-back detected. */
1476 PK11_FreeSymKey(pwSpec->master_secret);
1477 @@ -3405,6 +3519,17 @@
1478 {
1479 SECStatus rv;
1480
1481 + /* If we already have a message in place, we need to enqueue it.
1482 + * This empties the buffer. This is a convenient place to call
1483 + * dtls_StageHandshakeMessage to mark the message boundary.
1484 + */
1485 + if (IS_DTLS(ss)) {
1486 + rv = dtls_StageHandshakeMessage(ss);
1487 + if (rv != SECSuccess) {
1488 + return rv;
1489 + }
1490 + }
1491 +
1492 SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
1493 SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
1494 PRINT_BUF(60, (ss, "MD5 handshake hash:",
1495 @@ -3417,6 +3542,32 @@
1496 return rv; /* error code set by AppendHandshake, if applicable. */
1497 }
1498 rv = ssl3_AppendHandshakeNumber(ss, length, 3);
1499 + if (rv != SECSuccess) {
1500 + return rv; /* error code set by AppendHandshake, if applicable. */
1501 + }
1502 +
1503 + if (IS_DTLS(ss)) {
1504 + /* Note that we make an unfragmented message here. We fragment in the
1505 + * transmission code, if necessary */
1506 + rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.sendMessageSeq, 2);
1507 + if (rv != SECSuccess) {
1508 + return rv; /* error code set by AppendHandshake, if applicable. */
1509 + }
1510 + ss->ssl3.hs.sendMessageSeq++;
1511 +
1512 + /* 0 is the fragment offset, because it's not fragmented yet */
1513 + rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
1514 + if (rv != SECSuccess) {
1515 + return rv; /* error code set by AppendHandshake, if applicable. */
1516 + }
1517 +
1518 + /* Fragment length -- set to the packet length because not fragmented */
1519 + rv = ssl3_AppendHandshakeNumber(ss, length, 3);
1520 + if (rv != SECSuccess) {
1521 + return rv; /* error code set by AppendHandshake, if applicable. */
1522 + }
1523 + }
1524 +
1525 return rv; /* error code set by AppendHandshake, if applicable. */
1526 }
1527
1528 @@ -3823,9 +3974,10 @@
1529 /* Called from ssl3_HandleHelloRequest(),
1530 * ssl3_RedoHandshake()
1531 * ssl2_BeginClientHandshake (when resuming ssl3 session)
1532 + * dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
1533 */
1534 SECStatus
1535 -ssl3_SendClientHello(sslSocket *ss)
1536 +ssl3_SendClientHello(sslSocket *ss, PRBool resending)
1537 {
1538 sslSessionID * sid;
1539 ssl3CipherSpec * cwSpec;
1540 @@ -3849,6 +4001,7 @@
1541 return rv; /* ssl3_InitState has set the error code. */
1542 }
1543 ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
1544 + PORT_Assert(IS_DTLS(ss) || !resending);
1545
1546 /* We might be starting a session renegotiation in which case we should
1547 * clear previous state.
1548 @@ -4008,6 +4161,10 @@
1549 }
1550 #endif
1551
1552 + if (IS_DTLS(ss)) {
1553 + ssl3_DisableNonDTLSSuites(ss);
1554 + }
1555 +
1556 /* how many suites are permitted by policy and user preference? */
1557 num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
1558 if (!num_suites)
1559 @@ -4027,6 +4184,9 @@
1560 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
1561 2 + num_suites*sizeof(ssl3CipherSuite) +
1562 1 + numCompressionMethods + total_exten_len;
1563 + if (IS_DTLS(ss)) {
1564 + length += 1 + ss->ssl3.hs.cookieLen;
1565 + }
1566
1567 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
1568 if (rv != SECSuccess) {
1569 @@ -4034,13 +4194,23 @@
1570 }
1571
1572 ss->clientHelloVersion = ss->version;
1573 - rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
1574 + if (IS_DTLS(ss)) {
1575 + PRUint16 version;
1576 +
1577 + version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
1578 + rv = ssl3_AppendHandshakeNumber(ss, version, 2);
1579 + } else {
1580 + rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
1581 + }
1582 if (rv != SECSuccess) {
1583 return rv; /* err set by ssl3_AppendHandshake* */
1584 }
1585 - rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
1586 - if (rv != SECSuccess) {
1587 - return rv; /* err set by GetNewRandom. */
1588 +
1589 + if (!resending) { /* Don't re-generate if we are in DTLS re-sending mode */
1590 + rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
1591 + if (rv != SECSuccess) {
1592 + return rv; /* err set by GetNewRandom. */
1593 + }
1594 }
1595 rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
1596 SSL3_RANDOM_LENGTH);
1597 @@ -4057,6 +4227,14 @@
1598 return rv; /* err set by ssl3_AppendHandshake* */
1599 }
1600
1601 + if (IS_DTLS(ss)) {
1602 + rv = ssl3_AppendHandshakeVariable(
1603 + ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1);
1604 + if (rv != SECSuccess) {
1605 + return rv; /* err set by ssl3_AppendHandshake* */
1606 + }
1607 + }
1608 +
1609 rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
1610 if (rv != SECSuccess) {
1611 return rv; /* err set by ssl3_AppendHandshake* */
1612 @@ -4180,8 +4358,12 @@
1613 ss->sec.ci.sid = NULL;
1614 }
1615
1616 + if (IS_DTLS(ss)) {
1617 + dtls_RehandshakeCleanup(ss);
1618 + }
1619 +
1620 ssl_GetXmitBufLock(ss);
1621 - rv = ssl3_SendClientHello(ss);
1622 + rv = ssl3_SendClientHello(ss, PR_FALSE);
1623 ssl_ReleaseXmitBufLock(ss);
1624
1625 return rv;
1626 @@ -5036,6 +5218,23 @@
1627 }
1628 version = (SSL3ProtocolVersion)temp;
1629
1630 + if (IS_DTLS(ss)) {
1631 + /* RFC 4347 required that you verify that the server versions
1632 + * match (Section 4.2.1) in the HelloVerifyRequest and the
1633 + * ServerHello.
1634 + *
1635 + * RFC 6347 suggests (SHOULD) that servers always use 1.0
1636 + * in HelloVerifyRequest and allows the versions not to match,
1637 + * especially when 1.2 is being negotiated.
1638 + *
1639 + * Therefore we do not check for matching here.
1640 + */
1641 + version = dtls_DTLSVersionToTLSVersion(version);
1642 + if (version == 0) { /* Insane version number */
1643 + goto alert_loser;
1644 + }
1645 + }
1646 +
1647 rv = ssl3_NegotiateVersion(ss, version, PR_FALSE);
1648 if (rv != SECSuccess) {
1649 desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
1650 @@ -6264,6 +6463,7 @@
1651 SSL3AlertLevel level = alert_fatal;
1652 SSL3ProtocolVersion version;
1653 SECItem sidBytes = {siBuffer, NULL, 0};
1654 + SECItem cookieBytes = {siBuffer, NULL, 0};
1655 SECItem suites = {siBuffer, NULL, 0};
1656 SECItem comps = {siBuffer, NULL, 0};
1657 PRBool haveSpecWriteLock = PR_FALSE;
1658 @@ -6281,6 +6481,20 @@
1659 return rv; /* error code is set. */
1660 }
1661
1662 + /* Clearing the handshake pointers so that ssl_Do1stHandshake won't
1663 + * call ssl2_HandleMessage.
1664 + *
1665 + * The issue here is that TLS ordinarily starts out in
1666 + * ssl2_HandleV3HandshakeRecord() because of the backward-compatibility
1667 + * code paths. That function zeroes these next pointers. But with DTLS,
1668 + * we don't even try to do the v2 ClientHello so we skip that function
1669 + * and need to reset these values here.
1670 + */
1671 + if (IS_DTLS(ss)) {
1672 + ss->nextHandshake = 0;
1673 + ss->securityHandshake = 0;
1674 + }
1675 +
1676 /* We might be starting session renegotiation in which case we should
1677 * clear previous state.
1678 */
1679 @@ -6306,10 +6520,22 @@
1680 goto alert_loser;
1681 }
1682
1683 + if (IS_DTLS(ss)) {
1684 + dtls_RehandshakeCleanup(ss);
1685 + }
1686 +
1687 tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
1688 if (tmp < 0)
1689 goto loser; /* malformed, alert already sent */
1690 - ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
1691 +
1692 + /* Translate the version */
1693 + if (IS_DTLS(ss)) {
1694 + ss->clientHelloVersion = version =
1695 + dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
1696 + } else {
1697 + ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
1698 + }
1699 +
1700 rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
1701 if (rv != SECSuccess) {
1702 desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
1703 @@ -6331,6 +6557,14 @@
1704 goto loser; /* malformed */
1705 }
1706
1707 + /* grab the client's cookie, if present. */
1708 + if (IS_DTLS(ss)) {
1709 + rv = ssl3_ConsumeHandshakeVariable(ss, &cookieBytes, 1, &b, &length);
1710 + if (rv != SECSuccess) {
1711 + goto loser; /* malformed */
1712 + }
1713 + }
1714 +
1715 /* grab the list of cipher suites. */
1716 rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
1717 if (rv != SECSuccess) {
1718 @@ -6479,6 +6713,10 @@
1719 ssl3_FilterECCipherSuitesByServerCerts(ss);
1720 #endif
1721
1722 + if (IS_DTLS(ss)) {
1723 + ssl3_DisableNonDTLSSuites(ss);
1724 + }
1725 +
1726 #ifdef PARANOID
1727 /* Look for a matching cipher suite. */
1728 j = ssl3_config_match_init(ss);
1729 @@ -7166,17 +7404,28 @@
1730 PRUint32 maxBytes = 65535;
1731 PRUint32 length;
1732 PRInt32 extensions_len = 0;
1733 + SSL3ProtocolVersion version;
1734
1735 SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
1736 ss->fd));
1737
1738 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
1739 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
1740 - PORT_Assert( MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
1741
1742 - if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
1743 - PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
1744 - return SECFailure;
1745 + if (!IS_DTLS(ss)) {
1746 + PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
1747 +
1748 + if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
1749 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
1750 + return SECFailure;
1751 + }
1752 + } else {
1753 + PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_DTLS_1_0));
1754 +
1755 + if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_DTLS_1_0)) {
1756 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
1757 + return SECFailure;
1758 + }
1759 }
1760
1761 sid = ss->sec.ci.sid;
1762 @@ -7194,7 +7443,13 @@
1763 return rv; /* err set by AppendHandshake. */
1764 }
1765
1766 - rv = ssl3_AppendHandshakeNumber(ss, ss->version, 2);
1767 + if (IS_DTLS(ss)) {
1768 + version = dtls_TLSVersionToDTLSVersion(ss->version);
1769 + } else {
1770 + version = ss->version;
1771 + }
1772 +
1773 + rv = ssl3_AppendHandshakeNumber(ss, version, 2);
1774 if (rv != SECSuccess) {
1775 return rv; /* err set by AppendHandshake. */
1776 }
1777 @@ -7379,11 +7634,8 @@
1778 nnames = ca_list->nnames;
1779 }
1780
1781 - if (!nnames) {
1782 - PORT_SetError(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA);
1783 - return SECFailure;
1784 - }
1785 -
1786 + /* There used to be a test here to require a CA, but there
1787 + * are cases where you want to have no CAs offered. */
1788 for (i = 0, name = names; i < nnames; i++, name++) {
1789 calen += 2 + name->len;
1790 }
1791 @@ -7551,9 +7803,17 @@
1792 }
1793
1794 /* Generate the pre-master secret ... */
1795 - version.major = MSB(ss->clientHelloVersion);
1796 - version.minor = LSB(ss->clientHelloVersion);
1797 + if (IS_DTLS(ss)) {
1798 + SSL3ProtocolVersion temp;
1799
1800 + temp = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
1801 + version.major = MSB(temp);
1802 + version.minor = LSB(temp);
1803 + } else {
1804 + version.major = MSB(ss->clientHelloVersion);
1805 + version.minor = LSB(ss->clientHelloVersion);
1806 + }
1807 +
1808 param.data = (unsigned char *)&version;
1809 param.len = sizeof version;
1810
1811 @@ -7635,6 +7895,11 @@
1812 } else if (ss->opt.detectRollBack) {
1813 SSL3ProtocolVersion client_version =
1814 (rsaPmsBuf[0] << 8) | rsaPmsBuf[1];
1815 +
1816 + if (IS_DTLS(ss)) {
1817 + client_version = dtls_DTLSVersionToTLSVersion(client_version);
1818 + }
1819 +
1820 if (client_version != ss->clientHelloVersion) {
1821 /* Version roll-back detected. ensure failure. */
1822 rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
1823 @@ -8851,6 +9116,10 @@
1824 }
1825 }
1826
1827 + if (IS_DTLS(ss)) {
1828 + flags |= ssl_SEND_FLAG_NO_RETRANSMIT;
1829 + }
1830 +
1831 rv = ssl3_SendFinished(ss, flags);
1832 if (rv != SECSuccess) {
1833 goto xmit_loser; /* err is set. */
1834 @@ -8980,13 +9249,14 @@
1835 * hanshake message.
1836 * Caller must hold Handshake and RecvBuf locks.
1837 */
1838 -static SECStatus
1839 +SECStatus
1840 ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
1841 {
1842 SECStatus rv = SECSuccess;
1843 SSL3HandshakeType type = ss->ssl3.hs.msg_type;
1844 SSL3Hashes hashes; /* computed hashes are put here. */
1845 PRUint8 hdr[4];
1846 + PRUint8 dtlsData[8];
1847
1848 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
1849 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
1850 @@ -9032,10 +9302,35 @@
1851 return rv;
1852 }
1853 }
1854 - /* We should not include hello_request messages in the handshake hashes */
1855 - if (ss->ssl3.hs.msg_type != hello_request) {
1856 + /* We should not include hello_request and hello_verify_request messages
1857 + * in the handshake hashes */
1858 + if ((ss->ssl3.hs.msg_type != hello_request) &&
1859 + (ss->ssl3.hs.msg_type != hello_verify_request)) {
1860 rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
1861 if (rv != SECSuccess) return rv; /* err code already set. */
1862 +
1863 + /* Extra data to simulate a complete DTLS handshake fragment */
1864 + if (IS_DTLS(ss)) {
1865 + /* Sequence number */
1866 + dtlsData[0] = MSB(ss->ssl3.hs.recvMessageSeq);
1867 + dtlsData[1] = LSB(ss->ssl3.hs.recvMessageSeq);
1868 +
1869 + /* Fragment offset */
1870 + dtlsData[2] = 0;
1871 + dtlsData[3] = 0;
1872 + dtlsData[4] = 0;
1873 +
1874 + /* Fragment length */
1875 + dtlsData[5] = (PRUint8)(length >> 16);
1876 + dtlsData[6] = (PRUint8)(length >> 8);
1877 + dtlsData[7] = (PRUint8)(length );
1878 +
1879 + rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) dtlsData,
1880 + sizeof(dtlsData));
1881 + if (rv != SECSuccess) return rv; /* err code already set. */
1882 + }
1883 +
1884 + /* The message body */
1885 rv = ssl3_UpdateHandshakeHashes(ss, b, length);
1886 if (rv != SECSuccess) return rv; /* err code already set. */
1887 }
1888 @@ -9071,6 +9366,14 @@
1889 }
1890 rv = ssl3_HandleServerHello(ss, b, length);
1891 break;
1892 + case hello_verify_request:
1893 + if (!IS_DTLS(ss) || ss->sec.isServer) {
1894 + (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
1895 + PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST);
1896 + return SECFailure;
1897 + }
1898 + rv = dtls_HandleHelloVerifyRequest(ss, b, length);
1899 + break;
1900 case certificate:
1901 if (ss->ssl3.hs.may_get_cert_status) {
1902 /* If we might get a CertificateStatus then we want to postpone the
1903 @@ -9169,6 +9472,12 @@
1904 PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
1905 rv = SECFailure;
1906 }
1907 +
1908 + if (IS_DTLS(ss) && (rv == SECSuccess)) {
1909 + /* Increment the expected sequence number */
1910 + ss->ssl3.hs.recvMessageSeq++;
1911 + }
1912 +
1913 return rv;
1914 }
1915
1916 @@ -9331,6 +9640,7 @@
1917 SSL3Opaque hash[MAX_MAC_LENGTH];
1918 sslBuffer *plaintext;
1919 sslBuffer temp_buf;
1920 + PRUint64 dtls_seq_num;
1921 unsigned int ivLen = 0;
1922
1923 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
1924 @@ -9366,6 +9676,39 @@
1925 crSpec = ss->ssl3.crSpec;
1926 cipher_def = crSpec->cipher_def;
1927
1928 + /*
1929 + * DTLS relevance checks:
1930 + * Note that this code currently ignores all out-of-epoch packets,
1931 + * which means we lose some in the case of rehandshake +
1932 + * loss/reordering. Since DTLS is explicitly unreliable, this
1933 + * seems like a good tradeoff for implementation effort and is
1934 + * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1
1935 + */
1936 + if (IS_DTLS(ss)) {
1937 + DTLSEpoch epoch = (cText->seq_num.high >> 16) & 0xffff;
1938 +
1939 + if (crSpec->epoch != epoch) {
1940 + ssl_ReleaseSpecReadLock(ss);
1941 + SSL_DBG(("%d: SSL3[%d]: HandleRecord, received packet "
1942 + "from irrelevant epoch %d", SSL_GETPID(), ss->fd, epoch));
1943 + /* Silently drop the packet */
1944 + databuf->len = 0; /* Needed to ensure data not left around */
1945 + return SECSuccess;
1946 + }
1947 +
1948 + dtls_seq_num = (((PRUint64)(cText->seq_num.high & 0xffff)) << 32) |
1949 + ((PRUint64)cText->seq_num.low);
1950 +
1951 + if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
1952 + ssl_ReleaseSpecReadLock(ss);
1953 + SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
1954 + "potentially replayed packet", SSL_GETPID(), ss->fd));
1955 + /* Silently drop the packet */
1956 + databuf->len = 0; /* Needed to ensure data not left around */
1957 + return SECSuccess;
1958 + }
1959 + }
1960 +
1961 if (cipher_def->type == type_block &&
1962 crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
1963 /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
1964 @@ -9487,7 +9830,8 @@
1965 /* compute the MAC */
1966 rType = cText->type;
1967 rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer),
1968 - rType, cText->version, crSpec->read_seq_num,
1969 + IS_DTLS(ss), rType, cText->version,
1970 + IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
1971 plaintext->buf, plaintext->len, hash, &hashBytes);
1972 if (rv != SECSuccess) {
1973 padIsBad = PR_TRUE; /* really macIsBad */
1974 @@ -9499,19 +9843,27 @@
1975 crSpec->mac_size) != 0) {
1976 /* must not hold spec lock when calling SSL3_SendAlert. */
1977 ssl_ReleaseSpecReadLock(ss);
1978 - SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
1979 - /* always log mac error, in case attacker can read server logs. */
1980 - PORT_SetError(SSL_ERROR_BAD_MAC_READ);
1981
1982 SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
1983
1984 - return SECFailure;
1985 + if (!IS_DTLS(ss)) {
1986 + SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
1987 + /* always log mac error, in case attacker can read server logs. */
1988 + PORT_SetError(SSL_ERROR_BAD_MAC_READ);
1989 + return SECFailure;
1990 + } else {
1991 + /* Silently drop the packet */
1992 + databuf->len = 0; /* Needed to ensure data not left around */
1993 + return SECSuccess;
1994 + }
1995 }
1996
1997 + if (!IS_DTLS(ss)) {
1998 + ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
1999 + } else {
2000 + dtls_RecordSetRecvd(&crSpec->recvdRecords, dtls_seq_num);
2001 + }
2002
2003 -
2004 - ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
2005 -
2006 ssl_ReleaseSpecReadLock(ss); /*****************************************/
2007
2008 /*
2009 @@ -9615,7 +9967,11 @@
2010 rv = ssl3_HandleAlert(ss, databuf);
2011 break;
2012 case content_handshake:
2013 - rv = ssl3_HandleHandshake(ss, databuf);
2014 + if (!IS_DTLS(ss)) {
2015 + rv = ssl3_HandleHandshake(ss, databuf);
2016 + } else {
2017 + rv = dtls_HandleHandshake(ss, databuf);
2018 + }
2019 break;
2020 /*
2021 case content_application_data is handled before this switch
2022 @@ -9675,6 +10031,9 @@
2023 spec->read_seq_num.high = 0;
2024 spec->read_seq_num.low = 0;
2025
2026 + spec->epoch = 0;
2027 + dtls_InitRecvdRecords(&spec->recvdRecords);
2028 +
2029 spec->version = ss->vrange.max;
2030 }
2031
2032 @@ -9716,6 +10075,21 @@
2033
2034 PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
2035
2036 + if (IS_DTLS(ss)) {
2037 + ss->ssl3.hs.sendMessageSeq = 0;
2038 + ss->ssl3.hs.recvMessageSeq = 0;
2039 + ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
2040 + ss->ssl3.hs.rtRetries = 0;
2041 +
2042 + /* Have to allocate this because ssl_FreeSocket relocates
2043 + * this structure in DEBUG mode */
2044 + if (!(ss->ssl3.hs.lastMessageFlight = PORT_New(PRCList)))
2045 + return SECFailure;
2046 + ss->ssl3.hs.recvdHighWater = -1;
2047 + PR_INIT_CLIST(ss->ssl3.hs.lastMessageFlight);
2048 + dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
2049 + }
2050 +
2051 rv = ssl3_NewHandshakeHashes(ss);
2052 if (rv == SECSuccess) {
2053 ss->ssl3.initialized = PR_TRUE;
2054 @@ -9968,6 +10342,11 @@
2055 PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
2056 return SECFailure;
2057 }
2058 +
2059 + if (IS_DTLS(ss)) {
2060 + dtls_RehandshakeCleanup(ss);
2061 + }
2062 +
2063 if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
2064 PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
2065 return SECFailure;
2066 @@ -9982,7 +10361,7 @@
2067
2068 /* start off a new handshake. */
2069 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss)
2070 - : ssl3_SendClientHello(ss);
2071 + : ssl3_SendClientHello(ss, PR_FALSE);
2072
2073 ssl_ReleaseXmitBufLock(ss); /**************************************/
2074 return rv;
2075 @@ -10042,6 +10421,17 @@
2076 ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/);
2077 ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
2078
2079 + /* Destroy the DTLS data */
2080 + if (IS_DTLS(ss)) {
2081 + if (ss->ssl3.hs.lastMessageFlight) {
2082 + dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
2083 + PORT_Free(ss->ssl3.hs.lastMessageFlight);
2084 + }
2085 + if (ss->ssl3.hs.recvdFragments.buf) {
2086 + PORT_Free(ss->ssl3.hs.recvdFragments.buf);
2087 + }
2088 + }
2089 +
2090 ss->ssl3.initialized = PR_FALSE;
2091
2092 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
2093 Index: net/third_party/nss/ssl/sslgathr.c
2094 ===================================================================
2095 --- net/third_party/nss/ssl/sslgathr.c (revision 127709)
2096 +++ net/third_party/nss/ssl/sslgathr.c (working copy)
2097 @@ -434,6 +434,8 @@
2098 gs->state = GS_INIT;
2099 gs->writeOffset = 0;
2100 gs->readOffset = 0;
2101 + gs->dtlsPacketOffset = 0;
2102 + gs->dtlsPacket.len = 0;
2103 status = sslBuffer_Grow(&gs->buf, 4096);
2104 return status;
2105 }
2106 @@ -445,6 +447,7 @@
2107 if (gs) { /* the PORT_*Free functions check for NULL pointers. */
2108 PORT_ZFree(gs->buf.buf, gs->buf.space);
2109 PORT_Free(gs->inbuf.buf);
2110 + PORT_Free(gs->dtlsPacket.buf);
2111 }
2112 }
2113
2114 Index: net/third_party/nss/ssl/dtls1con.c
2115 ===================================================================
2116 --- net/third_party/nss/ssl/dtls1con.c (revision 0)
2117 +++ net/third_party/nss/ssl/dtls1con.c (revision 0)
2118 @@ -0,0 +1,1163 @@
2119 +/*
2120 + * DTLS Protocol
2121 + *
2122 + * ***** BEGIN LICENSE BLOCK *****
2123 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
2124 + *
2125 + * The contents of this file are subject to the Mozilla Public License Version
2126 + * 1.1 (the "License"); you may not use this file except in compliance with
2127 + * the License. You may obtain a copy of the License at
2128 + * http://www.mozilla.org/MPL/
2129 + *
2130 + * Software distributed under the License is distributed on an "AS IS" basis,
2131 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
2132 + * for the specific language governing rights and limitations under the
2133 + * License.
2134 + *
2135 + * The Original Code is the Netscape security libraries.
2136 + *
2137 + * The Initial Developer of the Original Code is
2138 + * Netscape Communications Corporation.
2139 + * Portions created by the Initial Developer are Copyright (C) 1994-2000
2140 + * the Initial Developer. All Rights Reserved.
2141 + *
2142 + * Contributor(s):
2143 + * Eric Rescorla <ekr@rtfm.com>
2144 + *
2145 + * Alternatively, the contents of this file may be used under the terms of
2146 + * either the GNU General Public License Version 2 or later (the "GPL"), or
2147 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
2148 + * in which case the provisions of the GPL or the LGPL are applicable instead
2149 + * of those above. If you wish to allow use of your version of this file only
2150 + * under the terms of either the GPL or the LGPL, and not to allow others to
2151 + * use your version of this file under the terms of the MPL, indicate your
2152 + * decision by deleting the provisions above and replace them with the notice
2153 + * and other provisions required by the GPL or the LGPL. If you do not delete
2154 + * the provisions above, a recipient may use your version of this file under
2155 + * the terms of any one of the MPL, the GPL or the LGPL.
2156 + *
2157 + * ***** END LICENSE BLOCK ***** */
2158 +/* $Id: $ */
2159 +
2160 +#include "ssl.h"
2161 +#include "sslimpl.h"
2162 +#include "sslproto.h"
2163 +
2164 +#ifndef PR_ARRAY_SIZE
2165 +#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
2166 +#endif
2167 +
2168 +static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
2169 +static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
2170 +static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
2171 +
2172 +/* -28 adjusts for the IP/UDP header */
2173 +static const PRUint16 COMMON_MTU_VALUES[] = {
2174 + 1500 - 28, /* Ethernet MTU */
2175 + 1280 - 28, /* IPv6 minimum MTU */
2176 + 576 - 28, /* Common assumption */
2177 + 256 - 28 /* We're in serious trouble now */
2178 +};
2179 +
2180 +#define DTLS_COOKIE_BYTES 32
2181 +
2182 +/* List copied from ssl3con.c:cipherSuites */
2183 +static const ssl3CipherSuite nonDTLSSuites[] = {
2184 +#ifdef NSS_ENABLE_ECC
2185 + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
2186 + TLS_ECDHE_RSA_WITH_RC4_128_SHA,
2187 +#endif /* NSS_ENABLE_ECC */
2188 + TLS_DHE_DSS_WITH_RC4_128_SHA,
2189 +#ifdef NSS_ENABLE_ECC
2190 + TLS_ECDH_RSA_WITH_RC4_128_SHA,
2191 + TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
2192 +#endif /* NSS_ENABLE_ECC */
2193 + SSL_RSA_WITH_RC4_128_MD5,
2194 + SSL_RSA_WITH_RC4_128_SHA,
2195 + TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
2196 + SSL_RSA_EXPORT_WITH_RC4_40_MD5,
2197 + 0 /* End of list marker */
2198 +};
2199 +
2200 +/* Map back and forth between TLS and DTLS versions in wire format.
2201 + * Mapping table is:
2202 + *
2203 + * TLS DTLS
2204 + * 1.1 (0302) 1.0 (feff)
2205 + */
2206 +SSL3ProtocolVersion
2207 +dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
2208 +{
2209 + /* Anything other than TLS 1.1 is an error, so return
2210 + * the invalid version ffff. */
2211 + if (tlsv != SSL_LIBRARY_VERSION_TLS_1_1)
2212 + return 0xffff;
2213 +
2214 + return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
2215 +}
2216 +
2217 +/* Map known DTLS versions to known TLS versions.
2218 + * - Invalid versions (< 1.0) return a version of 0
2219 + * - Versions > known return a version one higher than we know of
2220 + * to accomodate a theoretically newer version */
2221 +SSL3ProtocolVersion
2222 +dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
2223 +{
2224 + if (MSB(dtlsv) == 0xff) {
2225 + return 0;
2226 + }
2227 +
2228 + if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE)
2229 + return SSL_LIBRARY_VERSION_TLS_1_1;
2230 +
2231 + /* Return a fictional higher version than we know of */
2232 + return SSL_LIBRARY_VERSION_TLS_1_1 + 1;
2233 +}
2234 +
2235 +/* On this socket, Disable non-DTLS cipher suites in the argument's list */
2236 +SECStatus
2237 +ssl3_DisableNonDTLSSuites(sslSocket * ss)
2238 +{
2239 + const ssl3CipherSuite * suite;
2240 +
2241 + for (suite = nonDTLSSuites; *suite; ++suite) {
2242 + SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
2243 +
2244 + PORT_Assert(rv == SECSuccess); /* else is coding error */
2245 + }
2246 + return SECSuccess;
2247 +}
2248 +
2249 +/* Allocate a DTLSQueuedMessage.
2250 + *
2251 + * Called from dtls_QueueMessage()
2252 + */
2253 +static DTLSQueuedMessage *
2254 +dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
2255 + const unsigned char *data, PRUint32 len)
2256 +{
2257 + DTLSQueuedMessage *msg = NULL;
2258 +
2259 + msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage));
2260 + if (!msg)
2261 + return NULL;
2262 +
2263 + msg->data = PORT_Alloc(len);
2264 + if (!msg->data) {
2265 + PORT_Free(msg);
2266 + return NULL;
2267 + }
2268 + PORT_Memcpy(msg->data, data, len);
2269 +
2270 + msg->len = len;
2271 + msg->epoch = epoch;
2272 + msg->type = type;
2273 +
2274 + return msg;
2275 +}
2276 +
2277 +/*
2278 + * Free a handshake message
2279 + *
2280 + * Called from dtls_FreeHandshakeMessages()
2281 + */
2282 +static void
2283 +dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
2284 +{
2285 + if (!msg)
2286 + return;
2287 +
2288 + PORT_ZFree(msg->data, msg->len);
2289 + PORT_Free(msg);
2290 +}
2291 +
2292 +/*
2293 + * Free a list of handshake messages
2294 + *
2295 + * Called from:
2296 + * dtls_HandleHandshake()
2297 + * ssl3_DestroySSL3Info()
2298 + */
2299 +void
2300 +dtls_FreeHandshakeMessages(PRCList *list)
2301 +{
2302 + PRCList *cur_p;
2303 +
2304 + while (!PR_CLIST_IS_EMPTY(list)) {
2305 + cur_p = PR_LIST_TAIL(list);
2306 + PR_REMOVE_LINK(cur_p);
2307 + dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
2308 + }
2309 +}
2310 +
2311 +/* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record.
2312 + * origBuf is the decrypted ssl record content and is expected to contain
2313 + * complete handshake records
2314 + * Caller must hold the handshake and RecvBuf locks.
2315 + *
2316 + * Note that this code uses msg_len for two purposes:
2317 + *
2318 + * (1) To pass the length to ssl3_HandleHandshakeMessage()
2319 + * (2) To carry the length of a message currently being reassembled
2320 + *
2321 + * However, unlike ssl3_HandleHandshake(), it is not used to carry
2322 + * the state of reassembly (i.e., whether one is in progress). That
2323 + * is carried in recvdHighWater and recvdFragments.
2324 + */
2325 +#define OFFSET_BYTE(o) (o/8)
2326 +#define OFFSET_MASK(o) (1 << (o%8))
2327 +
2328 +SECStatus
2329 +dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
2330 +{
2331 + /* XXX OK for now.
2332 + * This doesn't work properly with asynchronous certificate validation.
2333 + * because that returns a WOULDBLOCK error. The current DTLS
2334 + * applications do not need asynchronous validation, but in the
2335 + * future we will need to add this.
2336 + */
2337 + sslBuffer buf = *origBuf;
2338 + SECStatus rv = SECSuccess;
2339 +
2340 + PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
2341 + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
2342 +
2343 + while (buf.len > 0) {
2344 + PRUint8 type;
2345 + PRUint32 message_length;
2346 + PRUint16 message_seq;
2347 + PRUint32 fragment_offset;
2348 + PRUint32 fragment_length;
2349 + PRUint32 offset;
2350 +
2351 + if (buf.len < 12) {
2352 + PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
2353 + rv = SECFailure;
2354 + break;
2355 + }
2356 +
2357 + /* Parse the header */
2358 + type = buf.buf[0];
2359 + message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
2360 + message_seq = (buf.buf[4] << 8) | buf.buf[5];
2361 + fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
2362 + fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11] ;
2363 +
2364 +#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
2365 + if (message_length > MAX_HANDSHAKE_MSG_LEN) {
2366 + (void)ssl3_DecodeError(ss);
2367 + PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
2368 + return SECFailure;
2369 + }
2370 +#undef MAX_HANDSHAKE_MSG_LEN
2371 +
2372 + buf.buf += 12;
2373 + buf.len -= 12;
2374 +
2375 + /* This fragment must be complete */
2376 + if (buf.len < fragment_length) {
2377 + PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
2378 + rv = SECFailure;
2379 + break;
2380 + }
2381 +
2382 + /* Sanity check the packet contents */
2383 + if ((fragment_length + fragment_offset) > message_length) {
2384 + PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
2385 + rv = SECFailure;
2386 + break;
2387 + }
2388 +
2389 + /* There are three ways we could not be ready for this packet.
2390 + *
2391 + * 1. It's a partial next message.
2392 + * 2. It's a partial or complete message beyond the next
2393 + * 3. It's a message we've already seen
2394 + *
2395 + * If it's the complete next message we accept it right away.
2396 + * This is the common case for short messages
2397 + */
2398 + if ((message_seq == ss->ssl3.hs.recvMessageSeq)
2399 + && (fragment_offset == 0)
2400 + && (fragment_length == message_length)) {
2401 + /* Complete next message. Process immediately */
2402 + ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
2403 + ss->ssl3.hs.msg_len = message_length;
2404 +
2405 + /* At this point we are advancing our state machine, so
2406 + * we can free our last flight of messages */
2407 + dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
2408 + ss->ssl3.hs.recvdHighWater = -1;
2409 + dtls_CancelTimer(ss);
2410 +
2411 + /* Reset the timer to the initial value if the retry counter
2412 + * is 0, per Sec. 4.2.4.1 */
2413 + if (ss->ssl3.hs.rtRetries == 0) {
2414 + ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
2415 + }
2416 +
2417 + rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
2418 + if (rv == SECFailure) {
2419 + /* Do not attempt to process rest of messages in this record */
2420 + break;
2421 + }
2422 + } else {
2423 + if (message_seq < ss->ssl3.hs.recvMessageSeq) {
2424 + /* Case 3: we do an immediate retransmit if we're
2425 + * in a waiting state*/
2426 + if (ss->ssl3.hs.rtTimerCb == NULL) {
2427 + /* Ignore */
2428 + } else if (ss->ssl3.hs.rtTimerCb ==
2429 + dtls_RetransmitTimerExpiredCb) {
2430 + SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
2431 + SSL_GETPID(), ss->fd));
2432 + /* Check to see if we retransmitted recently. If so,
2433 + * suppress the triggered retransmit. This avoids
2434 + * retransmit wars after packet loss.
2435 + * This is not in RFC 5346 but should be
2436 + */
2437 + if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
2438 + (ss->ssl3.hs.rtTimeoutMs / 4)) {
2439 + SSL_TRC(30,
2440 + ("%d: SSL3[%d]: Shortcutting retransmit timer",
2441 + SSL_GETPID(), ss->fd));
2442 +
2443 + /* Cancel the timer and call the CB,
2444 + * which re-arms the timer */
2445 + dtls_CancelTimer(ss);
2446 + dtls_RetransmitTimerExpiredCb(ss);
2447 + rv = SECSuccess;
2448 + break;
2449 + } else {
2450 + SSL_TRC(30,
2451 + ("%d: SSL3[%d]: We just retransmitted. Ignoring.",
2452 + SSL_GETPID(), ss->fd));
2453 + rv = SECSuccess;
2454 + break;
2455 + }
2456 + } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
2457 + /* Retransmit the messages and re-arm the timer
2458 + * Note that we are not backing off the timer here.
2459 + * The spec isn't clear and my reasoning is that this
2460 + * may be a re-ordered packet rather than slowness,
2461 + * so let's be aggressive. */
2462 + dtls_CancelTimer(ss);
2463 + rv = dtls_TransmitMessageFlight(ss);
2464 + if (rv == SECSuccess) {
2465 + rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
2466 + }
2467 + if (rv != SECSuccess)
2468 + return rv;
2469 + break;
2470 + }
2471 + } else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
2472 + /* Case 2
2473 + *
2474 + * Ignore this message. This means we don't handle out of
2475 + * order complete messages that well, but we're still
2476 + * compliant and this probably does not happen often
2477 + *
2478 + * XXX OK for now. Maybe do something smarter at some point?
2479 + */
2480 + } else {
2481 + /* Case 1
2482 + *
2483 + * Buffer the fragment for reassembly
2484 + */
2485 + /* Make room for the message */
2486 + if (ss->ssl3.hs.recvdHighWater == -1) {
2487 + PRUint32 map_length = OFFSET_BYTE(message_length) + 1;
2488 +
2489 + rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length);
2490 + if (rv != SECSuccess)
2491 + break;
2492 + /* Make room for the fragment map */
2493 + rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
2494 + map_length);
2495 + if (rv != SECSuccess)
2496 + break;
2497 +
2498 + /* Reset the reassembly map */
2499 + ss->ssl3.hs.recvdHighWater = 0;
2500 + PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
2501 + ss->ssl3.hs.recvdFragments.space);
2502 + ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
2503 + ss->ssl3.hs.msg_len = message_length;
2504 + }
2505 +
2506 + /* If we have a message length mismatch, abandon the reassembly
2507 + * in progress and hope that the next retransmit will give us
2508 + * something sane
2509 + */
2510 + if (message_length != ss->ssl3.hs.msg_len) {
2511 + ss->ssl3.hs.recvdHighWater = -1;
2512 + PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
2513 + rv = SECFailure;
2514 + break;
2515 + }
2516 +
2517 + /* Now copy this fragment into the buffer */
2518 + PORT_Assert((fragment_offset + fragment_length) <=
2519 + ss->ssl3.hs.msg_body.space);
2520 + PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset,
2521 + buf.buf, fragment_length);
2522 +
2523 + /* This logic is a bit tricky. We have two values for
2524 + * reassembly state:
2525 + *
2526 + * - recvdHighWater contains the highest contiguous number of
2527 + * bytes received
2528 + * - recvdFragments contains a bitmask of packets received
2529 + * above recvdHighWater
2530 + *
2531 + * This avoids having to fill in the bitmask in the common
2532 + * case of adjacent fragments received in sequence
2533 + */
2534 + if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
2535 + /* Either this is the adjacent fragment or an overlapping
2536 + * fragment */
2537 + ss->ssl3.hs.recvdHighWater = fragment_offset +
2538 + fragment_length;
2539 + } else {
2540 + for (offset = fragment_offset;
2541 + offset < fragment_offset + fragment_length;
2542 + offset++) {
2543 + ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |=
2544 + OFFSET_MASK(offset);
2545 + }
2546 + }
2547 +
2548 + /* Now figure out the new high water mark if appropriate */
2549 + for (offset = ss->ssl3.hs.recvdHighWater;
2550 + offset < ss->ssl3.hs.msg_len; offset++) {
2551 + /* Note that this loop is not efficient, since it counts
2552 + * bit by bit. If we have a lot of out-of-order packets,
2553 + * we should optimize this */
2554 + if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
2555 + OFFSET_MASK(offset)) {
2556 + ss->ssl3.hs.recvdHighWater++;
2557 + } else {
2558 + break;
2559 + }
2560 + }
2561 +
2562 + /* If we have all the bytes, then we are good to go */
2563 + if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) {
2564 + ss->ssl3.hs.recvdHighWater = -1;
2565 +
2566 + rv = ssl3_HandleHandshakeMessage(ss,
2567 + ss->ssl3.hs.msg_body.buf,
2568 + ss->ssl3.hs.msg_len);
2569 + if (rv == SECFailure)
2570 + break; /* Skip rest of record */
2571 +
2572 + /* At this point we are advancing our state machine, so
2573 + * we can free our last flight of messages */
2574 + dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
2575 + dtls_CancelTimer(ss);
2576 +
2577 + /* If there have been no retries this time, reset the
2578 + * timer value to the default per Section 4.2.4.1 */
2579 + if (ss->ssl3.hs.rtRetries == 0) {
2580 + ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
2581 + }
2582 + }
2583 + }
2584 + }
2585 +
2586 + buf.buf += fragment_length;
2587 + buf.len -= fragment_length;
2588 + }
2589 +
2590 + origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
2591 +
2592 + /* XXX OK for now. In future handle rv == SECWouldBlock safely in order
2593 + * to deal with asynchronous certificate verification */
2594 + return rv;
2595 +}
2596 +
2597 +/* Enqueue a message (either handshake or CCS)
2598 + *
2599 + * Called from:
2600 + * dtls_StageHandshakeMessage()
2601 + * ssl3_SendChangeCipherSpecs()
2602 + */
2603 +SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
2604 + const SSL3Opaque *pIn, PRInt32 nIn)
2605 +{
2606 + SECStatus rv = SECSuccess;
2607 + DTLSQueuedMessage *msg = NULL;
2608 +
2609 + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
2610 + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
2611 +
2612 + msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn);
2613 +
2614 + if (!msg) {
2615 + PORT_SetError(SEC_ERROR_NO_MEMORY);
2616 + rv = SECFailure;
2617 + } else {
2618 + PR_APPEND_LINK(&msg->link, ss->ssl3.hs.lastMessageFlight);
2619 + }
2620 +
2621 + return rv;
2622 +}
2623 +
2624 +/* Add DTLS handshake message to the pending queue
2625 + * Empty the sendBuf buffer.
2626 + * This function returns SECSuccess or SECFailure, never SECWouldBlock.
2627 + * Always set sendBuf.len to 0, even when returning SECFailure.
2628 + *
2629 + * Called from:
2630 + * ssl3_AppendHandshakeHeader()
2631 + * dtls_FlushHandshake()
2632 + */
2633 +SECStatus
2634 +dtls_StageHandshakeMessage(sslSocket *ss)
2635 +{
2636 + SECStatus rv = SECSuccess;
2637 +
2638 + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
2639 + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
2640 +
2641 + /* This function is sometimes called when no data is actually to
2642 + * be staged, so just return SECSuccess. */
2643 + if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
2644 + return rv;
2645 +
2646 + rv = dtls_QueueMessage(ss, content_handshake,
2647 + ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);
2648 +
2649 + /* Whether we succeeded or failed, toss the old handshake data. */
2650 + ss->sec.ci.sendBuf.len = 0;
2651 + return rv;
2652 +}
2653 +
2654 +/* Enqueue the handshake message in sendBuf (if any) and then
2655 + * transmit the resulting flight of handshake messages.
2656 + *
2657 + * Called from:
2658 + * ssl3_FlushHandshake()
2659 + */
2660 +SECStatus
2661 +dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
2662 +{
2663 + SECStatus rv = SECSuccess;
2664 +
2665 + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
2666 + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
2667 +
2668 + rv = dtls_StageHandshakeMessage(ss);
2669 + if (rv != SECSuccess)
2670 + return rv;
2671 +
2672 + if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
2673 + rv = dtls_TransmitMessageFlight(ss);
2674 + if (rv != SECSuccess)
2675 + return rv;
2676 +
2677 + if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
2678 + ss->ssl3.hs.rtRetries = 0;
2679 + rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
2680 + }
2681 + }
2682 +
2683 + return rv;
2684 +}
2685 +
2686 +/* The callback for when the retransmit timer expires
2687 + *
2688 + * Called from:
2689 + * dtls_CheckTimer()
2690 + * dtls_HandleHandshake()
2691 + */
2692 +static void
2693 +dtls_RetransmitTimerExpiredCb(sslSocket *ss)
2694 +{
2695 + SECStatus rv = SECFailure;
2696 +
2697 + ss->ssl3.hs.rtRetries++;
2698 +
2699 + if (!(ss->ssl3.hs.rtRetries % 3)) {
2700 + /* If one of the messages was potentially greater than > MTU,
2701 + * then downgrade. Do this every time we have retransmitted a
2702 + * message twice, per RFC 6347 Sec. 4.1.1 */
2703 + dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
2704 + }
2705 +
2706 + rv = dtls_TransmitMessageFlight(ss);
2707 + if (rv == SECSuccess) {
2708 +
2709 + /* Re-arm the timer */
2710 + rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
2711 + }
2712 +
2713 + if (rv == SECFailure) {
2714 + /* XXX OK for now. In future maybe signal the stack that we couldn't
2715 + * transmit. For now, let the read handle any real network errors */
2716 + }
2717 +}
2718 +
2719 +/* Transmit a flight of handshake messages, stuffing them
2720 + * into as few records as seems reasonable
2721 + *
2722 + * Called from:
2723 + * dtls_FlushHandshake()
2724 + * dtls_RetransmitTimerExpiredCb()
2725 + */
2726 +static SECStatus
2727 +dtls_TransmitMessageFlight(sslSocket *ss)
2728 +{
2729 + SECStatus rv = SECSuccess;
2730 + PRCList *msg_p;
2731 + PRUint16 room_left = ss->ssl3.mtu;
2732 + PRInt32 sent;
2733 +
2734 + ssl_GetXmitBufLock(ss);
2735 + ssl_GetSpecReadLock(ss);
2736 +
2737 + /* DTLS does not buffer its handshake messages in
2738 + * ss->pendingBuf, but rather in the lastMessageFlight
2739 + * structure. This is just a sanity check that
2740 + * some programming error hasn't inadvertantly
2741 + * stuffed something in ss->pendingBuf
2742 + */
2743 + PORT_Assert(!ss->pendingBuf.len);
2744 + for (msg_p = PR_LIST_HEAD(ss->ssl3.hs.lastMessageFlight);
2745 + msg_p != ss->ssl3.hs.lastMessageFlight;
2746 + msg_p = PR_NEXT_LINK(msg_p)) {
2747 + DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;
2748 +
2749 + /* The logic here is:
2750 + *
2751 + * 1. If this is a message that will not fit into the remaining
2752 + * space, then flush.
2753 + * 2. If the message will now fit into the remaining space,
2754 + * encrypt, buffer, and loop.
2755 + * 3. If the message will not fit, then fragment.
2756 + *
2757 + * At the end of the function, flush.
2758 + */
2759 + if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
2760 + /* The message will not fit into the remaining space, so flush */
2761 + rv = dtls_SendSavedWriteData(ss);
2762 + if (rv != SECSuccess)
2763 + break;
2764 +
2765 + room_left = ss->ssl3.mtu;
2766 + }
2767 +
2768 + if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
2769 + /* The message will fit, so encrypt and then continue with the
2770 + * next packet */
2771 + sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
2772 + msg->data, msg->len,
2773 + ssl_SEND_FLAG_FORCE_INTO_BUFFER |
2774 + ssl_SEND_FLAG_USE_EPOCH);
2775 + if (sent != msg->len) {
2776 + rv = SECFailure;
2777 + if (sent != -1) {
2778 + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
2779 + }
2780 + break;
2781 + }
2782 +
2783 + room_left = ss->ssl3.mtu - ss->pendingBuf.len;
2784 + } else {
2785 + /* The message will not fit, so fragment.
2786 + *
2787 + * XXX OK for now. Arrange to coalesce the last fragment
2788 + * of this message with the next message if possible.
2789 + * That would be more efficient.
2790 + */
2791 + PRUint32 fragment_offset = 0;
2792 + unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
2793 + * plausible MTU */
2794 +
2795 + /* Assert that we have already flushed */
2796 + PORT_Assert(room_left == ss->ssl3.mtu);
2797 +
2798 + /* Case 3: We now need to fragment this message
2799 + * DTLS only supports fragmenting handshaking messages */
2800 + PORT_Assert(msg->type == content_handshake);
2801 +
2802 + /* The headers consume 12 bytes so the smalles possible
2803 + * message (i.e., an empty one) is 12 bytes
2804 + */
2805 + PORT_Assert(msg->len >= 12);
2806 +
2807 + while ((fragment_offset + 12) < msg->len) {
2808 + PRUint32 fragment_len;
2809 + const unsigned char *content = msg->data + 12;
2810 + PRUint32 content_len = msg->len - 12;
2811 +
2812 + /* The reason we use 8 here is that that's the length of
2813 + * the new DTLS data that we add to the header */
2814 + fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
2815 + content_len - fragment_offset);
2816 + PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
2817 + /* Make totally sure that we are within the buffer.
2818 + * Note that the only way that fragment len could get
2819 + * adjusted here is if
2820 + *
2821 + * (a) we are in release mode so the PORT_Assert is compiled out
2822 + * (b) either the MTU table is inconsistent with DTLS_MAX_MTU
2823 + * or ss->ssl3.mtu has become corrupt.
2824 + */
2825 + fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
2826 +
2827 + /* Construct an appropriate-sized fragment */
2828 + /* Type, length, sequence */
2829 + PORT_Memcpy(fragment, msg->data, 6);
2830 +
2831 + /* Offset */
2832 + fragment[6] = (fragment_offset >> 16) & 0xff;
2833 + fragment[7] = (fragment_offset >> 8) & 0xff;
2834 + fragment[8] = (fragment_offset) & 0xff;
2835 +
2836 + /* Fragment length */
2837 + fragment[9] = (fragment_len >> 16) & 0xff;
2838 + fragment[10] = (fragment_len >> 8) & 0xff;
2839 + fragment[11] = (fragment_len) & 0xff;
2840 +
2841 + PORT_Memcpy(fragment + 12, content + fragment_offset,
2842 + fragment_len);
2843 +
2844 + /*
2845 + * Send the record. We do this in two stages
2846 + * 1. Encrypt
2847 + */
2848 + sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
2849 + fragment, fragment_len + 12,
2850 + ssl_SEND_FLAG_FORCE_INTO_BUFFER |
2851 + ssl_SEND_FLAG_USE_EPOCH);
2852 + if (sent != (fragment_len + 12)) {
2853 + rv = SECFailure;
2854 + if (sent != -1) {
2855 + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
2856 + }
2857 + break;
2858 + }
2859 +
2860 + /* 2. Flush */
2861 + rv = dtls_SendSavedWriteData(ss);
2862 + if (rv != SECSuccess)
2863 + break;
2864 +
2865 + fragment_offset += fragment_len;
2866 + }
2867 + }
2868 + }
2869 +
2870 + /* Finally, we need to flush */
2871 + if (rv == SECSuccess)
2872 + rv = dtls_SendSavedWriteData(ss);
2873 +
2874 + /* Give up the locks */
2875 + ssl_ReleaseSpecReadLock(ss);
2876 + ssl_ReleaseXmitBufLock(ss);
2877 +
2878 + return rv;
2879 +}
2880 +
2881 +/* Flush the data in the pendingBuf and update the max message sent
2882 + * so we can adjust the MTU estimate if we need to.
2883 + * Wrapper for ssl_SendSavedWriteData.
2884 + *
2885 + * Called from dtls_TransmitMessageFlight()
2886 + */
2887 +static
2888 +SECStatus dtls_SendSavedWriteData(sslSocket *ss)
2889 +{
2890 + PRInt32 sent;
2891 +
2892 + sent = ssl_SendSavedWriteData(ss);
2893 + if (sent < 0)
2894 + return SECFailure;
2895 +
2896 + /* We should always have complete writes b/c datagram sockets
2897 + * don't really block */
2898 + if (ss->pendingBuf.len > 0) {
2899 + ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
2900 + return SECFailure;
2901 + }
2902 +
2903 + /* Update the largest message sent so we can adjust the MTU
2904 + * estimate if necessary */
2905 + if (sent > ss->ssl3.hs.maxMessageSent)
2906 + ss->ssl3.hs.maxMessageSent = sent;
2907 +
2908 + return SECSuccess;
2909 +}
2910 +
2911 +/* Compress, MAC, encrypt a DTLS record. Allows specification of
2912 + * the epoch using epoch value. If use_epoch is PR_TRUE then
2913 + * we use the provided epoch. If use_epoch is PR_FALSE then
2914 + * whatever the current value is in effect is used.
2915 + *
2916 + * Called from ssl3_SendRecord()
2917 + */
2918 +SECStatus
2919 +dtls_CompressMACEncryptRecord(sslSocket * ss,
2920 + DTLSEpoch epoch,
2921 + PRBool use_epoch,
2922 + SSL3ContentType type,
2923 + const SSL3Opaque * pIn,
2924 + PRUint32 contentLen,
2925 + sslBuffer * wrBuf)
2926 +{
2927 + SECStatus rv = SECFailure;
2928 + ssl3CipherSpec * cwSpec;
2929 +
2930 + ssl_GetSpecReadLock(ss); /********************************/
2931 +
2932 + /* The reason for this switch-hitting code is that we might have
2933 + * a flight of records spanning an epoch boundary, e.g.,
2934 + *
2935 + * ClientKeyExchange (epoch = 0)
2936 + * ChangeCipherSpec (epoch = 0)
2937 + * Finished (epoch = 1)
2938 + *
2939 + * Thus, each record needs a different cipher spec. The information
2940 + * about which epoch to use is carried with the record.
2941 + */
2942 + if (use_epoch) {
2943 + if (ss->ssl3.cwSpec->epoch == epoch)
2944 + cwSpec = ss->ssl3.cwSpec;
2945 + else if (ss->ssl3.pwSpec->epoch == epoch)
2946 + cwSpec = ss->ssl3.pwSpec;
2947 + else
2948 + cwSpec = NULL;
2949 + } else {
2950 + cwSpec = ss->ssl3.cwSpec;
2951 + }
2952 +
2953 + if (cwSpec) {
2954 + rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
2955 + type, pIn, contentLen, wrBuf);
2956 + } else {
2957 + PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
2958 + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
2959 + }
2960 + ssl_ReleaseSpecReadLock(ss); /************************************/
2961 +
2962 + return rv;
2963 +}
2964 +
2965 +/* Start a timer
2966 + *
2967 + * Called from:
2968 + * dtls_HandleHandshake()
2969 + * dtls_FlushHAndshake()
2970 + * dtls_RestartTimer()
2971 + */
2972 +SECStatus
2973 +dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb)
2974 +{
2975 + PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
2976 +
2977 + ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
2978 + ss->ssl3.hs.rtTimerCb = cb;
2979 +
2980 + return SECSuccess;
2981 +}
2982 +
2983 +/* Restart a timer with optional backoff
2984 + *
2985 + * Called from dtls_RetransmitTimerExpiredCb()
2986 + */
2987 +SECStatus
2988 +dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
2989 +{
2990 + if (backoff) {
2991 + ss->ssl3.hs.rtTimeoutMs *= 2;
2992 + if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
2993 + ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
2994 + }
2995 +
2996 + return dtls_StartTimer(ss, cb);
2997 +}
2998 +
2999 +/* Cancel a pending timer
3000 + *
3001 + * Called from:
3002 + * dtls_HandleHandshake()
3003 + * dtls_CheckTimer()
3004 + */
3005 +void
3006 +dtls_CancelTimer(sslSocket *ss)
3007 +{
3008 + PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
3009 +
3010 + ss->ssl3.hs.rtTimerCb = NULL;
3011 +}
3012 +
3013 +/* Check the pending timer and fire the callback if it expired
3014 + *
3015 + * Called from ssl3_GatherCompleteHandshake()
3016 + */
3017 +void
3018 +dtls_CheckTimer(sslSocket *ss)
3019 +{
3020 + if (!ss->ssl3.hs.rtTimerCb)
3021 + return;
3022 +
3023 + if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
3024 + PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
3025 + /* Timer has expired */
3026 + DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
3027 +
3028 + /* Cancel the timer so that we can call the CB safely */
3029 + dtls_CancelTimer(ss);
3030 +
3031 + /* Now call the CB */
3032 + cb(ss);
3033 + }
3034 +}
3035 +
3036 +/* The callback to fire when the holddown timer for the Finished
3037 + * message expires and we can delete it
3038 + *
3039 + * Called from dtls_CheckTimer()
3040 + */
3041 +void
3042 +dtls_FinishedTimerCb(sslSocket *ss)
3043 +{
3044 + ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
3045 +}
3046 +
3047 +/* Cancel the Finished hold-down timer and destroy the
3048 + * pending cipher spec. Note that this means that
3049 + * successive rehandshakes will fail if the Finished is
3050 + * lost.
3051 + *
3052 + * XXX OK for now. Figure out how to handle the combination
3053 + * of Finished lost and rehandshake
3054 + */
3055 +void
3056 +dtls_RehandshakeCleanup(sslSocket *ss)
3057 +{
3058 + dtls_CancelTimer(ss);
3059 + ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
3060 + ss->ssl3.hs.sendMessageSeq = 0;
3061 +}
3062 +
3063 +/* Set the MTU to the next step less than or equal to the
3064 + * advertised value. Also used to downgrade the MTU by
3065 + * doing dtls_SetMTU(ss, biggest packet set).
3066 + *
3067 + * Passing 0 means set this to the largest MTU known
3068 + * (effectively resetting the PMTU backoff value).
3069 + *
3070 + * Called by:
3071 + * ssl3_InitState()
3072 + * dtls_RetransmitTimerExpiredCb()
3073 + */
3074 +void
3075 +dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
3076 +{
3077 + int i;
3078 +
3079 + if (advertised == 0) {
3080 + ss->ssl3.mtu = COMMON_MTU_VALUES[0];
3081 + SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
3082 + return;
3083 + }
3084 +
3085 + for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
3086 + if (COMMON_MTU_VALUES[i] <= advertised) {
3087 + ss->ssl3.mtu = COMMON_MTU_VALUES[i];
3088 + SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
3089 + return;
3090 + }
3091 + }
3092 +
3093 + /* Fallback */
3094 + ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
3095 + SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
3096 +}
3097 +
3098 +/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a
3099 + * DTLS hello_verify_request
3100 + * Caller must hold Handshake and RecvBuf locks.
3101 + */
3102 +SECStatus
3103 +dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
3104 +{
3105 + int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_RE QUEST;
3106 + SECStatus rv;
3107 + PRInt32 temp;
3108 + SECItem cookie = {siBuffer, NULL, 0};
3109 + SSL3AlertDescription desc = illegal_parameter;
3110 +
3111 + SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
3112 + SSL_GETPID(), ss->fd));
3113 + PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
3114 + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
3115 +
3116 + if (ss->ssl3.hs.ws != wait_server_hello) {
3117 + errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
3118 + desc = unexpected_message;
3119 + goto alert_loser;
3120 + }
3121 +
3122 + /* The version */
3123 + temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
3124 + if (temp < 0) {
3125 + goto loser; /* alert has been sent */
3126 + }
3127 +
3128 + if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
3129 + /* Note: this will need adjustment for DTLS 1.2 per Section 4.2.1 */
3130 + goto alert_loser;
3131 + }
3132 +
3133 + /* The cookie */
3134 + rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
3135 + if (rv != SECSuccess) {
3136 + goto loser; /* alert has been sent */
3137 + }
3138 + if (cookie.len > DTLS_COOKIE_BYTES) {
3139 + desc = decode_error;
3140 + goto alert_loser; /* malformed. */
3141 + }
3142 +
3143 + PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
3144 + ss->ssl3.hs.cookieLen = cookie.len;
3145 +
3146 +
3147 + ssl_GetXmitBufLock(ss); /*******************************/
3148 +
3149 + /* Now re-send the client hello */
3150 + rv = ssl3_SendClientHello(ss, PR_TRUE);
3151 +
3152 + ssl_ReleaseXmitBufLock(ss); /******************************* /
3153 +
3154 + if (rv == SECSuccess)
3155 + return rv;
3156 +
3157 +alert_loser:
3158 + (void)SSL3_SendAlert(ss, alert_fatal, desc);
3159 +
3160 +loser:
3161 + errCode = ssl_MapLowLevelError(errCode);
3162 + return SECFailure;
3163 +}
3164 +
3165 +/* Initialize the DTLS anti-replay window
3166 + *
3167 + * Called from:
3168 + * ssl3_SetupPendingCipherSpec()
3169 + * ssl3_InitCipherSpec()
3170 + */
3171 +void
3172 +dtls_InitRecvdRecords(DTLSRecvdRecords *records)
3173 +{
3174 + PORT_Memset(records->data, 0, sizeof(records->data));
3175 + records->left = 0;
3176 + records->right = DTLS_RECVD_RECORDS_WINDOW - 1;
3177 +}
3178 +
3179 +/*
3180 + * Has this DTLS record been received? Return values are:
3181 + * -1 -- out of range to the left
3182 + * 0 -- not received yet
3183 + * 1 -- replay
3184 + *
3185 + * Called from: dtls_HandleRecord()
3186 + */
3187 +int
3188 +dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
3189 +{
3190 + PRUint64 offset;
3191 +
3192 + /* Out of range to the left */
3193 + if (seq < records->left) {
3194 + return -1;
3195 + }
3196 +
3197 + /* Out of range to the right; since we advance the window on
3198 + * receipt, that means that this packet has not been received
3199 + * yet */
3200 + if (seq > records->right)
3201 + return 0;
3202 +
3203 + offset = seq % DTLS_RECVD_RECORDS_WINDOW;
3204 +
3205 + return !!(records->data[offset / 8] & (1 << (offset % 8)));
3206 +}
3207 +
3208 +/* Update the DTLS anti-replay window
3209 + *
3210 + * Called from ssl3_HandleRecord()
3211 + */
3212 +void
3213 +dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
3214 +{
3215 + PRUint64 offset;
3216 +
3217 + if (seq < records->left)
3218 + return;
3219 +
3220 + if (seq > records->right) {
3221 + PRUint64 new_left;
3222 + PRUint64 new_right;
3223 + PRUint64 right;
3224 +
3225 + /* Slide to the right; this is the tricky part
3226 + *
3227 + * 1. new_top is set to have room for seq, on the
3228 + * next byte boundary by setting the right 8
3229 + * bits of seq
3230 + * 2. new_left is set to compensate.
3231 + * 3. Zero all bits between top and new_top. Since
3232 + * this is a ring, this zeroes everything as-yet
3233 + * unseen. Because we always operate on byte
3234 + * boundaries, we can zero one byte at a time
3235 + */
3236 + new_right = seq | 0x07;
3237 + new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
3238 +
3239 + for (right = records->right + 8; right <= new_right; right += 8) {
3240 + offset = right % DTLS_RECVD_RECORDS_WINDOW;
3241 + records->data[offset / 8] = 0;
3242 + }
3243 +
3244 + records->right = new_right;
3245 + records->left = new_left;
3246 + }
3247 +
3248 + offset = seq % DTLS_RECVD_RECORDS_WINDOW;
3249 +
3250 + records->data[offset / 8] |= (1 << (offset % 8));
3251 +}
3252 +
3253 +SECStatus
3254 +DTLS_GetTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
3255 +{
3256 + sslSocket * ss = NULL;
3257 + PRIntervalTime elapsed;
3258 + PRIntervalTime desired;
3259 +
3260 + ss = ssl_FindSocket(socket);
3261 +
3262 + if (!ss)
3263 + return SECFailure;
3264 +
3265 + if (!IS_DTLS(ss))
3266 + return SECFailure;
3267 +
3268 + if (!ss->ssl3.hs.rtTimerCb)
3269 + return SECFailure;
3270 +
3271 + elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted;
3272 + desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs);
3273 + if (elapsed > desired) {
3274 + /* Timer expired */
3275 + *timeout = PR_INTERVAL_NO_WAIT;
3276 + } else {
3277 + *timeout = desired - elapsed;
3278 + }
3279 +
3280 + return SECSuccess;
3281 +}
3282
3283 Property changes on: net/third_party/nss/ssl/dtls1con.c
3284 ___________________________________________________________________
3285 Added: svn:eol-style
3286 + LF
3287
3288 Index: net/third_party/nss/ssl/sslproto.h
3289 ===================================================================
3290 --- net/third_party/nss/ssl/sslproto.h (revision 127709)
3291 +++ net/third_party/nss/ssl/sslproto.h (working copy)
3292 @@ -49,10 +49,15 @@
3293 #define SSL_LIBRARY_VERSION_3_0 0x0300
3294 #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
3295 #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
3296 +/* Note: this is the internal format, not the wire format */
3297 +#define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302
3298
3299 /* deprecated old name */
3300 #define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
3301
3302 +/* The DTLS version used in the spec */
3303 +#define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE ((~0x0100) & 0xffff)
3304 +
3305 /* Header lengths of some of the messages */
3306 #define SSL_HL_ERROR_HBYTES 3
3307 #define SSL_HL_CLIENT_HELLO_HBYTES 9
3308 Index: net/third_party/nss/ssl/sslt.h
3309 ===================================================================
3310 --- net/third_party/nss/ssl/sslt.h (revision 127709)
3311 +++ net/third_party/nss/ssl/sslt.h (working copy)
3312 @@ -190,7 +190,8 @@
3313 } SSLCipherSuiteInfo;
3314
3315 typedef enum {
3316 - ssl_variant_stream = 0
3317 + ssl_variant_stream = 0,
3318 + ssl_variant_datagram = 1
3319 } SSLProtocolVariant;
3320
3321 typedef struct SSLVersionRangeStr {
OLDNEW
« no previous file with comments | « net/third_party/nss/patches/applypatches.sh ('k') | net/third_party/nss/ssl.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698