~ubuntu-branches/ubuntu/karmic/nss/karmic-updates

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/ssl/ssl3ext.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2010-03-31 02:23:43 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100331022343-ck07ylqk8q474x26
Tags: 3.12.6-0ubuntu0.9.10.1
* New upstream release 3.12.6 RTM (NSS_3_12_6_RTM)
  - fixes CVE-2009-3555 aka US-CERT VU#120541
* Adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
  - update debian/patches/38_mips64_build.patch
  - update debian/patches/85_security_load.patch
* Remove patches that are merged upstream
  - delete debian/patches/91_nonexec_stack.patch
  - update debian/patches/series
* Bump nspr dependency to 4.8
  - update debian/control
* Add new symbols for 3.12.6
  - update debian/libnss3-1d.symbols 
* Enable transitional scheme for SSL renegotiation
  - add 97_SSL_RENEGOTIATE_TRANSITIONAL.patch
  - update debian/patches/series

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
 * ***** END LICENSE BLOCK ***** */
42
42
 
43
43
/* TLS extension code moved here from ssl3ecc.c */
44
 
/* $Id: ssl3ext.c,v 1.3 2008/10/06 22:04:15 nelson%bolyard.com Exp $ */
 
44
/* $Id: ssl3ext.c,v 1.13 2010/03/01 20:03:45 alexei.volkov.bugs%sun.com Exp $ */
45
45
 
46
46
#include "nssrenam.h"
47
47
#include "nss.h"
48
48
#include "ssl.h"
 
49
#include "sslproto.h"
49
50
#include "sslimpl.h"
50
51
#include "pk11pub.h"
51
52
#include "blapi.h"
61
62
static PRBool         session_ticket_keys_initialized = PR_FALSE;
62
63
static PRCallOnceType generate_session_keys_once;
63
64
 
64
 
static PRInt32 ssl3_SendServerNameXtn(sslSocket * ss,
65
 
    PRBool append, PRUint32 maxBytes);
 
65
/* forward static function declarations */
66
66
static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
67
67
    SECItem *data, EncryptedSessionTicket *enc_session_ticket);
68
68
static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
74
74
static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
75
75
    PRUint32 *aes_key_length, const unsigned char **mac_key,
76
76
    PRUint32 *mac_key_length);
 
77
static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
 
78
    PRBool append, PRUint32 maxBytes);
 
79
static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, 
 
80
    PRUint16 ex_type, SECItem *data);
77
81
 
78
82
/*
79
83
 * Write bytes.  Using this function means the SECItem structure
222
226
 * In the second generation, this table will be dynamic, and functions
223
227
 * will be registered here.
224
228
 */
 
229
/* This table is used by the server, to handle client hello extensions. */
225
230
static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
226
 
    { server_name_xtn, &ssl3_HandleServerNameXtn },
 
231
    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
227
232
#ifdef NSS_ENABLE_ECC
228
 
    { elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
229
 
    { ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
 
233
    { ssl_elliptic_curves_xtn,    &ssl3_HandleSupportedCurvesXtn },
 
234
    { ssl_ec_point_formats_xtn,   &ssl3_HandleSupportedPointFormatsXtn },
230
235
#endif
231
 
    { session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
232
 
    { -1, NULL }
233
 
};
234
 
 
235
 
static const ssl3HelloExtensionHandler serverHelloHandlers[] = {
236
 
    { server_name_xtn, &ssl3_HandleServerNameXtn },
237
 
    /* TODO: add a handler for ec_point_formats_xtn */
238
 
    { session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
239
 
    { -1, NULL }
240
 
};
241
 
 
242
 
/* Table of functions to format TLS hello extensions, one per extension.
243
 
 * This static table is for the formatting of client hello extensions.
 
236
    { ssl_session_ticket_xtn,     &ssl3_ServerHandleSessionTicketXtn },
 
237
    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
 
238
    { -1, NULL }
 
239
};
 
240
 
 
241
/* These two tables are used by the client, to handle server hello
 
242
 * extensions. */
 
243
static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
 
244
    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
 
245
    /* TODO: add a handler for ssl_ec_point_formats_xtn */
 
246
    { ssl_session_ticket_xtn,     &ssl3_ClientHandleSessionTicketXtn },
 
247
    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
 
248
    { -1, NULL }
 
249
};
 
250
 
 
251
static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
 
252
    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
 
253
    { -1, NULL }
 
254
};
 
255
 
 
256
/* Tables of functions to format TLS hello extensions, one function per
 
257
 * extension.
 
258
 * These static tables are for the formatting of client hello extensions.
244
259
 * The server's table of hello senders is dynamic, in the socket struct,
245
260
 * and sender functions are registered there.
246
261
 */
247
262
static const 
248
 
ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSIONS] = {
249
 
    { server_name_xtn, &ssl3_SendServerNameXtn },
 
263
ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
 
264
    { ssl_server_name_xtn,        &ssl3_SendServerNameXtn        },
 
265
    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
250
266
#ifdef NSS_ENABLE_ECC
251
 
    { elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
252
 
    { ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
253
 
#else
254
 
    { -1, NULL },
255
 
    { -1, NULL },
 
267
    { ssl_elliptic_curves_xtn,    &ssl3_SendSupportedCurvesXtn },
 
268
    { ssl_ec_point_formats_xtn,   &ssl3_SendSupportedPointFormatsXtn },
256
269
#endif
257
 
    { session_ticket_xtn, ssl3_SendSessionTicketXtn }
 
270
    { ssl_session_ticket_xtn,     &ssl3_SendSessionTicketXtn }
 
271
    /* any extra entries will appear as { 0, NULL }    */
 
272
};
 
273
 
 
274
static const 
 
275
ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
 
276
    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
 
277
    /* any extra entries will appear as { 0, NULL }    */
258
278
};
259
279
 
260
280
static PRBool
284
304
 
285
305
/* Format an SNI extension, using the name from the socket's URL,
286
306
 * unless that name is a dotted decimal string.
 
307
 * Used by client and server.
287
308
 */
288
 
static PRInt32 
289
 
ssl3_SendServerNameXtn(
290
 
                        sslSocket * ss,
291
 
                        PRBool      append,
292
 
                        PRUint32    maxBytes)
 
309
PRInt32
 
310
ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
 
311
                       PRUint32 maxBytes)
293
312
{
294
 
    PRUint32 len;
295
 
    PRNetAddr netAddr;
296
 
 
297
 
    /* must have a hostname */
298
 
    if (!ss || !ss->url || !ss->url[0])
299
 
        return 0;
300
 
    /* must not be an IPv4 or IPv6 address */
301
 
    if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
302
 
        /* is an IP address (v4 or v6) */
303
 
        return 0;
304
 
    }
305
 
    len  = PORT_Strlen(ss->url);
306
 
    if (append && maxBytes >= len + 9) {
307
 
        SECStatus rv;
308
 
        /* extension_type */
309
 
        rv = ssl3_AppendHandshakeNumber(ss, server_name_xtn, 2); 
310
 
        if (rv != SECSuccess) return -1;
311
 
        /* length of extension_data */
312
 
        rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); 
313
 
        if (rv != SECSuccess) return -1;
314
 
        /* length of server_name_list */
315
 
        rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
316
 
        if (rv != SECSuccess) return -1;
317
 
        /* Name Type (host_name) */
318
 
        rv = ssl3_AppendHandshake(ss,       "\0",    1);
319
 
        if (rv != SECSuccess) return -1;
320
 
        /* HostName (length and value) */
321
 
        rv = ssl3_AppendHandshakeVariable(ss, (unsigned char *)ss->url, len, 2);
322
 
        if (rv != SECSuccess) return -1;
323
 
        if (!ss->sec.isServer) {
324
 
            TLSExtensionData *xtnData = &ss->xtnData;
325
 
            xtnData->advertised[xtnData->numAdvertised++] = server_name_xtn;
326
 
        }
327
 
    }
328
 
    return len + 9;
 
313
    SECStatus rv;
 
314
    if (!ss->sec.isServer) {
 
315
        PRUint32 len;
 
316
        PRNetAddr netAddr;
 
317
        
 
318
        /* must have a hostname */
 
319
        if (!ss || !ss->url || !ss->url[0])
 
320
            return 0;
 
321
        /* must not be an IPv4 or IPv6 address */
 
322
        if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
 
323
            /* is an IP address (v4 or v6) */
 
324
            return 0;
 
325
        }
 
326
        len  = PORT_Strlen(ss->url);
 
327
        if (append && maxBytes >= len + 9) {
 
328
            /* extension_type */
 
329
            rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); 
 
330
            if (rv != SECSuccess) return -1;
 
331
            /* length of extension_data */
 
332
            rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); 
 
333
            if (rv != SECSuccess) return -1;
 
334
            /* length of server_name_list */
 
335
            rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
 
336
            if (rv != SECSuccess) return -1;
 
337
            /* Name Type (sni_host_name) */
 
338
            rv = ssl3_AppendHandshake(ss,       "\0",    1);
 
339
            if (rv != SECSuccess) return -1;
 
340
            /* HostName (length and value) */
 
341
            rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
 
342
            if (rv != SECSuccess) return -1;
 
343
            if (!ss->sec.isServer) {
 
344
                TLSExtensionData *xtnData = &ss->xtnData;
 
345
                xtnData->advertised[xtnData->numAdvertised++] = 
 
346
                    ssl_server_name_xtn;
 
347
            }
 
348
        }
 
349
        return len + 9;
 
350
    }
 
351
    /* Server side */
 
352
    if (append && maxBytes >= 4) {
 
353
        rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
 
354
        if (rv != SECSuccess)  return -1;
 
355
        /* length of extension_data */
 
356
        rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
 
357
        if (rv != SECSuccess) return -1;
 
358
    }
 
359
    return 4;
329
360
}
330
361
 
331
362
/* handle an incoming SNI extension, by ignoring it. */
332
363
SECStatus
333
364
ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
334
365
{
335
 
    /* TODO: if client, should verify extension_data is empty. */
336
 
    /* TODO: if server, should send empty extension_data. */
337
 
    /* For now, we ignore this, as if we didn't understand it. :-)  */
 
366
    SECItem *names = NULL;
 
367
    PRUint32 listCount = 0, namesPos = 0, i;
 
368
    TLSExtensionData *xtnData = &ss->xtnData;
 
369
    SECItem  ldata;
 
370
    PRInt32  listLenBytes = 0;
 
371
 
 
372
    if (!ss->sec.isServer) {
 
373
        /* Verify extension_data is empty. */
 
374
        if (data->data || data->len ||
 
375
            !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
 
376
            /* malformed or was not initiated by the client.*/
 
377
            return SECFailure;
 
378
        }
 
379
        return SECSuccess;
 
380
    }
 
381
 
 
382
    /* Server side - consume client data and register server sender. */
 
383
    /* do not parse the data if don't have user extension handling function. */
 
384
    if (!ss->sniSocketConfig) {
 
385
        return SECSuccess;
 
386
    }
 
387
    /* length of server_name_list */
 
388
    listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); 
 
389
    if (listLenBytes == 0 || listLenBytes != data->len) {
 
390
        return SECFailure;
 
391
    }
 
392
    ldata = *data;
 
393
    /* Calculate the size of the array.*/
 
394
    while (listLenBytes > 0) {
 
395
        SECItem litem;
 
396
        SECStatus rv;
 
397
        PRInt32  type;
 
398
        /* Name Type (sni_host_name) */
 
399
        type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len); 
 
400
        if (!ldata.len) {
 
401
            return SECFailure;
 
402
        }
 
403
        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
 
404
        if (rv != SECSuccess) {
 
405
            return SECFailure;
 
406
        }
 
407
        /* Adjust total length for cunsumed item, item len and type.*/
 
408
        listLenBytes -= litem.len + 3;
 
409
        if (listLenBytes > 0 && !ldata.len) {
 
410
            return SECFailure;
 
411
        }
 
412
        listCount += 1;
 
413
    }
 
414
    if (!listCount) {
 
415
        return SECFailure;
 
416
    }
 
417
    names = PORT_ZNewArray(SECItem, listCount);
 
418
    if (!names) {
 
419
        return SECFailure;
 
420
    }
 
421
    for (i = 0;i < listCount;i++) {
 
422
        int j;
 
423
        PRInt32  type;
 
424
        SECStatus rv;
 
425
        PRBool nametypePresent = PR_FALSE;
 
426
        /* Name Type (sni_host_name) */
 
427
        type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len); 
 
428
        /* Check if we have such type in the list */
 
429
        for (j = 0;j < listCount && names[j].data;j++) {
 
430
            if (names[j].type == type) {
 
431
                nametypePresent = PR_TRUE;
 
432
                break;
 
433
            }
 
434
        }
 
435
        /* HostName (length and value) */
 
436
        rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2,
 
437
                                           &data->data, &data->len);
 
438
        if (rv != SECSuccess) {
 
439
            goto loser;
 
440
        }
 
441
        if (nametypePresent == PR_FALSE) {
 
442
            namesPos += 1;
 
443
        }
 
444
    }
 
445
    /* Free old and set the new data. */
 
446
    if (xtnData->sniNameArr) {
 
447
        PORT_Free(ss->xtnData.sniNameArr);
 
448
    }
 
449
    xtnData->sniNameArr = names;
 
450
    xtnData->sniNameArrSize = namesPos;
 
451
    xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
 
452
 
338
453
    return SECSuccess;
 
454
 
 
455
loser:
 
456
    PORT_Free(names);
 
457
    return SECFailure;
339
458
}
340
 
 
 
459
        
341
460
/* Called by both clients and servers.
342
461
 * Clients sends a filled in session ticket if one is available, and otherwise
343
462
 * sends an empty ticket.  Servers always send empty tickets.
383
502
    if (append && maxBytes >= extension_length) {
384
503
        SECStatus rv;
385
504
        /* extension_type */
386
 
        rv = ssl3_AppendHandshakeNumber(ss, session_ticket_xtn, 2);
 
505
        rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
387
506
        if (rv != SECSuccess)
388
507
            goto loser;
389
508
        if (session_ticket && session_ticket->ticket.data &&
399
518
 
400
519
        if (!ss->sec.isServer) {
401
520
            TLSExtensionData *xtnData = &ss->xtnData;
402
 
            xtnData->advertised[xtnData->numAdvertised++] = session_ticket_xtn;
 
521
            xtnData->advertised[xtnData->numAdvertised++] = 
 
522
                ssl_session_ticket_xtn;
403
523
        }
404
524
    } else if (maxBytes < extension_length) {
405
525
        PORT_Assert(0);
454
574
    unsigned int         computed_mac_length;
455
575
    unsigned char        iv[AES_BLOCK_SIZE];
456
576
    SECItem              ivItem;
 
577
    SECItem             *srvName = NULL;
 
578
    PRUint32             srvNameLen = 0;
457
579
    CK_MECHANISM_TYPE    msWrapMech = 0; /* dummy default value,
458
580
                                          * must be >= 0 */
459
581
 
514
636
        }
515
637
        ms_is_wrapped = PR_TRUE;
516
638
    }
 
639
    /* Prep to send negotiated name */
 
640
    srvName = &ss->ssl3.pwSpec->srvVirtName;
 
641
    if (srvName->data && srvName->len) {
 
642
        srvNameLen = 2 + srvName->len; /* len bytes + name len */
 
643
    }
517
644
 
518
645
    ciphertext_length = 
519
646
        sizeof(PRUint16)                     /* ticket_version */
528
655
        + ms_item.len                        /* master_secret */
529
656
        + 1                                  /* client_auth_type */
530
657
        + cert_length                        /* cert */
 
658
        + 1                                  /* server name type */
 
659
        + srvNameLen                         /* name len + length field */
531
660
        + sizeof(ticket.ticket_lifetime_hint);
532
661
    padding_length =  AES_BLOCK_SIZE -
533
662
        (ciphertext_length % AES_BLOCK_SIZE);
610
739
        sizeof(ticket.ticket_lifetime_hint));
611
740
    if (rv != SECSuccess) goto loser;
612
741
 
 
742
    if (srvNameLen) {
 
743
        /* Name Type (sni_host_name) */
 
744
        rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
 
745
        if (rv != SECSuccess) goto loser;
 
746
        /* HostName (length and value) */
 
747
        rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
 
748
        if (rv != SECSuccess) goto loser;
 
749
        rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
 
750
        if (rv != SECSuccess) goto loser;
 
751
    } else {
 
752
        /* No Name */
 
753
        rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
 
754
                                     1);
 
755
        if (rv != SECSuccess) goto loser;
 
756
    }
 
757
 
613
758
    PORT_Assert(plaintext.len == padding_length);
614
759
    for (i = 0; i < padding_length; i++)
615
760
        plaintext.data[i] = (unsigned char)padding_length;
782
927
        unsigned int           buffer_len;
783
928
        PRInt32                temp;
784
929
        SECItem                cert_item;
 
930
        PRInt8                 nameType = TLS_STE_NO_SERVER_NAME;
785
931
 
786
932
        /* Turn off stateless session resumption if the client sends a
787
933
         * SessionTicket extension, even if the extension turns out to be
867
1013
            if (rv != SECSuccess)
868
1014
                goto no_ticket;
869
1015
        }
870
 
        if (PORT_Memcmp(computed_mac, enc_session_ticket.mac,
 
1016
        if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
871
1017
                computed_mac_length) != 0) {
872
1018
            SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
873
1019
                        SSL_GETPID(), ss->fd));
963
1109
        /* Read compression_method. */
964
1110
        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
965
1111
        if (temp < 0) goto no_ticket;
966
 
        parsed_session_ticket->compression_method = (SSL3CompressionMethod)temp;
 
1112
        parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
967
1113
 
968
1114
        /* Read cipher spec parameters. */
969
1115
        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
1034
1180
            goto no_ticket;
1035
1181
        parsed_session_ticket->timestamp = (PRUint32)temp;
1036
1182
 
 
1183
        /* Read server name */
 
1184
        nameType =
 
1185
                ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 
 
1186
        if (nameType != TLS_STE_NO_SERVER_NAME) {
 
1187
            SECItem name_item;
 
1188
            rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer,
 
1189
                                               &buffer_len);
 
1190
            if (rv != SECSuccess) goto no_ticket;
 
1191
            rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
 
1192
                                  &name_item);
 
1193
            if (rv != SECSuccess) goto no_ticket;
 
1194
            parsed_session_ticket->srvName.type = nameType;
 
1195
        }
 
1196
 
1037
1197
        /* Done parsing.  Check that all bytes have been consumed. */
1038
1198
        if (buffer_len != padding_length)
1039
1199
            goto no_ticket;
1090
1250
                    goto loser;
1091
1251
                }
1092
1252
            }
 
1253
            if (parsed_session_ticket->srvName.data != NULL) {
 
1254
                sid->u.ssl3.srvName = parsed_session_ticket->srvName;
 
1255
            }
1093
1256
            ss->statelessResume = PR_TRUE;
1094
1257
            ss->sec.ci.sid = sid;
1095
1258
        }
1172
1335
SECStatus 
1173
1336
ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
1174
1337
{
1175
 
    const ssl3HelloExtensionHandler * handlers =
1176
 
        ss->sec.isServer ? clientHelloHandlers : serverHelloHandlers;
 
1338
    const ssl3HelloExtensionHandler * handlers;
 
1339
 
 
1340
    if (ss->sec.isServer) {
 
1341
        handlers = clientHelloHandlers;
 
1342
    } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
 
1343
        handlers = serverHelloHandlersTLS;
 
1344
    } else {
 
1345
        handlers = serverHelloHandlersSSL3;
 
1346
    }
1177
1347
 
1178
1348
    while (*length) {
1179
1349
        const ssl3HelloExtensionHandler * handler;
1226
1396
    int i;
1227
1397
    ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
1228
1398
 
1229
 
    for (i = 0; i < MAX_EXTENSIONS; ++i, ++sender) {
 
1399
    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
1230
1400
        if (!sender->ex_sender) {
1231
1401
            sender->ex_type   = ex_type;
1232
1402
            sender->ex_sender = cb;
1239
1409
            break;
1240
1410
        }
1241
1411
    }
1242
 
    PORT_Assert(i < MAX_EXTENSIONS); /* table needs to grow */
 
1412
    PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */
1243
1413
    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1244
1414
    return SECFailure;
1245
1415
}
1252
1422
    PRInt32 total_exten_len = 0;
1253
1423
    int i;
1254
1424
 
1255
 
    if (!sender)
1256
 
        sender = &clientHelloSenders[0];
 
1425
    if (!sender) {
 
1426
        sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
 
1427
                 &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
 
1428
    }
1257
1429
 
1258
 
    for (i = 0; i < MAX_EXTENSIONS; ++i, ++sender) {
 
1430
    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
1259
1431
        if (sender->ex_sender) {
1260
1432
            PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
1261
1433
            if (extLen < 0)
1266
1438
    }
1267
1439
    return total_exten_len;
1268
1440
}
 
1441
 
 
1442
 
 
1443
/* Extension format:
 
1444
 * Extension number:   2 bytes
 
1445
 * Extension length:   2 bytes
 
1446
 * Verify Data Length: 1 byte
 
1447
 * Verify Data (TLS): 12 bytes (client) or 24 bytes (server)
 
1448
 * Verify Data (SSL): 36 bytes (client) or 72 bytes (server)
 
1449
 */
 
1450
static PRInt32 
 
1451
ssl3_SendRenegotiationInfoXtn(
 
1452
                        sslSocket * ss,
 
1453
                        PRBool      append,
 
1454
                        PRUint32    maxBytes)
 
1455
{
 
1456
    PRInt32 len, needed;
 
1457
 
 
1458
    /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
 
1459
     * both the SCSV and the empty RI, so when we send SCSV in 
 
1460
     * the initial handshake, we don't also send RI.
 
1461
     */
 
1462
    if (!ss || ss->ssl3.hs.sendingSCSV)
 
1463
        return 0;
 
1464
    len = !ss->firstHsDone ? 0 : 
 
1465
           (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 
 
1466
                             : ss->ssl3.hs.finishedBytes);
 
1467
    needed = 5 + len;
 
1468
    if (append && maxBytes >= needed) {
 
1469
        SECStatus rv;
 
1470
        /* extension_type */
 
1471
        rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); 
 
1472
        if (rv != SECSuccess) return -1;
 
1473
        /* length of extension_data */
 
1474
        rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2); 
 
1475
        if (rv != SECSuccess) return -1;
 
1476
        /* verify_Data from previous Finished message(s) */
 
1477
        rv = ssl3_AppendHandshakeVariable(ss, 
 
1478
                  ss->ssl3.hs.finishedMsgs.data, len, 1);
 
1479
        if (rv != SECSuccess) return -1;
 
1480
        if (!ss->sec.isServer) {
 
1481
            TLSExtensionData *xtnData = &ss->xtnData;
 
1482
            xtnData->advertised[xtnData->numAdvertised++] = 
 
1483
                                                   ssl_renegotiation_info_xtn;
 
1484
        }
 
1485
    }
 
1486
    return needed;
 
1487
}
 
1488
 
 
1489
/* This function runs in both the client and server.  */
 
1490
static SECStatus
 
1491
ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
 
1492
{
 
1493
    SECStatus rv = SECSuccess;
 
1494
    PRUint32 len = 0;
 
1495
 
 
1496
    if (ss->firstHsDone) {
 
1497
        len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes 
 
1498
                               : ss->ssl3.hs.finishedBytes * 2;
 
1499
    }
 
1500
    if (data->len != 1 + len  ||
 
1501
        data->data[0] != len  || (len && 
 
1502
        NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
 
1503
                         data->data + 1, len))) {
 
1504
        /* Can we do this here? Or, must we arrange for the caller to do it? */     
 
1505
        (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);                   
 
1506
        PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 
1507
        return SECFailure;
 
1508
    }
 
1509
    /* remember that we got this extension and it was correct. */
 
1510
    ss->peerRequestedProtection = 1;
 
1511
    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
 
1512
    if (ss->sec.isServer) {
 
1513
        /* prepare to send back the appropriate response */
 
1514
        rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
 
1515
                                             ssl3_SendRenegotiationInfoXtn);
 
1516
    }
 
1517
    return rv;
 
1518
}
 
1519