~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/ssl/ssl3ecc.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SSL3 Protocol
 
3
 *
 
4
 * ***** BEGIN LICENSE BLOCK *****
 
5
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
6
 *
 
7
 * The contents of this file are subject to the Mozilla Public License Version
 
8
 * 1.1 (the "License"); you may not use this file except in compliance with
 
9
 * the License. You may obtain a copy of the License at
 
10
 * http://www.mozilla.org/MPL/
 
11
 *
 
12
 * Software distributed under the License is distributed on an "AS IS" basis,
 
13
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
14
 * for the specific language governing rights and limitations under the
 
15
 * License.
 
16
 *
 
17
 * The Original Code is the Netscape security libraries.
 
18
 *
 
19
 * The Initial Developer of the Original Code is
 
20
 * Netscape Communications Corporation.
 
21
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
 
22
 * the Initial Developer. All Rights Reserved.
 
23
 *
 
24
 * Contributor(s):
 
25
 *   Dr Vipul Gupta <vipul.gupta@sun.com> and
 
26
 *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
 
27
 *
 
28
 * Alternatively, the contents of this file may be used under the terms of
 
29
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
30
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
31
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
32
 * of those above. If you wish to allow use of your version of this file only
 
33
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
34
 * use your version of this file under the terms of the MPL, indicate your
 
35
 * decision by deleting the provisions above and replace them with the notice
 
36
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
37
 * the provisions above, a recipient may use your version of this file under
 
38
 * the terms of any one of the MPL, the GPL or the LGPL.
 
39
 *
 
40
 * ***** END LICENSE BLOCK ***** */
 
41
 
 
42
/* ECC code moved here from ssl3con.c */
 
43
/* $Id: ssl3ecc.c,v 1.3.2.9 2006/08/05 01:54:03 julien.pierre.bugs%sun.com Exp $ */
 
44
 
 
45
#include "nssrenam.h"
 
46
#include "nss.h"
 
47
#include "cert.h"
 
48
#include "ssl.h"
 
49
#include "cryptohi.h"   /* for DSAU_ stuff */
 
50
#include "keyhi.h"
 
51
#include "secder.h"
 
52
#include "secitem.h"
 
53
 
 
54
#include "sslimpl.h"
 
55
#include "sslproto.h"
 
56
#include "sslerr.h"
 
57
#include "prtime.h"
 
58
#include "prinrval.h"
 
59
#include "prerror.h"
 
60
#include "pratom.h"
 
61
#include "prthread.h"
 
62
#include "prinit.h"
 
63
 
 
64
#include "pk11func.h"
 
65
#include "secmod.h"
 
66
#include "nsslocks.h"
 
67
#include "ec.h"
 
68
#include "blapi.h"
 
69
 
 
70
#include <stdio.h>
 
71
 
 
72
#ifdef NSS_ENABLE_ECC
 
73
 
 
74
#ifndef PK11_SETATTRS
 
75
#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
 
76
                (x)->pValue=(v); (x)->ulValueLen = (l);
 
77
#endif
 
78
 
 
79
#define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
 
80
    (ss->serverCerts[type].serverKeyPair ? \
 
81
    ss->serverCerts[type].serverKeyPair->pubKey : NULL)
 
82
 
 
83
#define SSL_IS_CURVE_NEGOTIATED(ss, curveName) \
 
84
    ((curveName > ec_noName) && \
 
85
     (curveName < ec_pastLastName) && \
 
86
     ((1UL << curveName) & ss->ssl3.hs.negotiatedECCurves) != 0)
 
87
 
 
88
/* Types and names of elliptic curves used in TLS */
 
89
typedef enum { ec_type_explicitPrime      = 1,
 
90
               ec_type_explicitChar2Curve = 2,
 
91
               ec_type_named
 
92
} ECType;
 
93
 
 
94
typedef enum { ec_noName     = 0,
 
95
               ec_sect163k1  = 1, 
 
96
               ec_sect163r1  = 2, 
 
97
               ec_sect163r2  = 3,
 
98
               ec_sect193r1  = 4, 
 
99
               ec_sect193r2  = 5, 
 
100
               ec_sect233k1  = 6,
 
101
               ec_sect233r1  = 7, 
 
102
               ec_sect239k1  = 8, 
 
103
               ec_sect283k1  = 9,
 
104
               ec_sect283r1  = 10, 
 
105
               ec_sect409k1  = 11, 
 
106
               ec_sect409r1  = 12,
 
107
               ec_sect571k1  = 13, 
 
108
               ec_sect571r1  = 14, 
 
109
               ec_secp160k1  = 15,
 
110
               ec_secp160r1  = 16, 
 
111
               ec_secp160r2  = 17, 
 
112
               ec_secp192k1  = 18,
 
113
               ec_secp192r1  = 19, 
 
114
               ec_secp224k1  = 20, 
 
115
               ec_secp224r1  = 21,
 
116
               ec_secp256k1  = 22, 
 
117
               ec_secp256r1  = 23, 
 
118
               ec_secp384r1  = 24,
 
119
               ec_secp521r1  = 25,
 
120
               ec_pastLastName
 
121
} ECName;
 
122
 
 
123
static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve);
 
124
 
 
125
#define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
 
126
 
 
127
/* Table containing OID tags for elliptic curves named in the
 
128
 * ECC-TLS IETF draft.
 
129
 */
 
130
static const SECOidTag ecName2OIDTag[] = {
 
131
        0,  
 
132
        SEC_OID_SECG_EC_SECT163K1,  /*  1 */
 
133
        SEC_OID_SECG_EC_SECT163R1,  /*  2 */
 
134
        SEC_OID_SECG_EC_SECT163R2,  /*  3 */
 
135
        SEC_OID_SECG_EC_SECT193R1,  /*  4 */
 
136
        SEC_OID_SECG_EC_SECT193R2,  /*  5 */
 
137
        SEC_OID_SECG_EC_SECT233K1,  /*  6 */
 
138
        SEC_OID_SECG_EC_SECT233R1,  /*  7 */
 
139
        SEC_OID_SECG_EC_SECT239K1,  /*  8 */
 
140
        SEC_OID_SECG_EC_SECT283K1,  /*  9 */
 
141
        SEC_OID_SECG_EC_SECT283R1,  /* 10 */
 
142
        SEC_OID_SECG_EC_SECT409K1,  /* 11 */
 
143
        SEC_OID_SECG_EC_SECT409R1,  /* 12 */
 
144
        SEC_OID_SECG_EC_SECT571K1,  /* 13 */
 
145
        SEC_OID_SECG_EC_SECT571R1,  /* 14 */
 
146
        SEC_OID_SECG_EC_SECP160K1,  /* 15 */
 
147
        SEC_OID_SECG_EC_SECP160R1,  /* 16 */
 
148
        SEC_OID_SECG_EC_SECP160R2,  /* 17 */
 
149
        SEC_OID_SECG_EC_SECP192K1,  /* 18 */
 
150
        SEC_OID_SECG_EC_SECP192R1,  /* 19 */
 
151
        SEC_OID_SECG_EC_SECP224K1,  /* 20 */
 
152
        SEC_OID_SECG_EC_SECP224R1,  /* 21 */
 
153
        SEC_OID_SECG_EC_SECP256K1,  /* 22 */
 
154
        SEC_OID_SECG_EC_SECP256R1,  /* 23 */
 
155
        SEC_OID_SECG_EC_SECP384R1,  /* 24 */
 
156
        SEC_OID_SECG_EC_SECP521R1,  /* 25 */
 
157
};
 
158
 
 
159
static const PRUint16 curve2bits[] = {
 
160
          0, /*  ec_noName     = 0,   */
 
161
        163, /*  ec_sect163k1  = 1,   */
 
162
        163, /*  ec_sect163r1  = 2,   */
 
163
        163, /*  ec_sect163r2  = 3,   */
 
164
        193, /*  ec_sect193r1  = 4,   */
 
165
        193, /*  ec_sect193r2  = 5,   */
 
166
        233, /*  ec_sect233k1  = 6,   */
 
167
        233, /*  ec_sect233r1  = 7,   */
 
168
        239, /*  ec_sect239k1  = 8,   */
 
169
        283, /*  ec_sect283k1  = 9,   */
 
170
        283, /*  ec_sect283r1  = 10,  */
 
171
        409, /*  ec_sect409k1  = 11,  */
 
172
        409, /*  ec_sect409r1  = 12,  */
 
173
        571, /*  ec_sect571k1  = 13,  */
 
174
        571, /*  ec_sect571r1  = 14,  */
 
175
        160, /*  ec_secp160k1  = 15,  */
 
176
        160, /*  ec_secp160r1  = 16,  */
 
177
        160, /*  ec_secp160r2  = 17,  */
 
178
        192, /*  ec_secp192k1  = 18,  */
 
179
        192, /*  ec_secp192r1  = 19,  */
 
180
        224, /*  ec_secp224k1  = 20,  */
 
181
        224, /*  ec_secp224r1  = 21,  */
 
182
        256, /*  ec_secp256k1  = 22,  */
 
183
        256, /*  ec_secp256r1  = 23,  */
 
184
        384, /*  ec_secp384r1  = 24,  */
 
185
        521, /*  ec_secp521r1  = 25,  */
 
186
      65535  /*  ec_pastLastName      */
 
187
};
 
188
 
 
189
typedef struct Bits2CurveStr {
 
190
    PRUint16    bits;
 
191
    ECName      curve;
 
192
} Bits2Curve;
 
193
 
 
194
static const Bits2Curve bits2curve [] = {
 
195
   {    192,     ec_secp192r1    /*  = 19,  fast */  },
 
196
   {    160,     ec_secp160r2    /*  = 17,  fast */  },
 
197
   {    160,     ec_secp160k1    /*  = 15,  */       },
 
198
   {    160,     ec_secp160r1    /*  = 16,  */       },
 
199
   {    163,     ec_sect163k1    /*  = 1,   */       },
 
200
   {    163,     ec_sect163r1    /*  = 2,   */       },
 
201
   {    163,     ec_sect163r2    /*  = 3,   */       },
 
202
   {    192,     ec_secp192k1    /*  = 18,  */       },
 
203
   {    193,     ec_sect193r1    /*  = 4,   */       },
 
204
   {    193,     ec_sect193r2    /*  = 5,   */       },
 
205
   {    224,     ec_secp224r1    /*  = 21,  fast */  },
 
206
   {    224,     ec_secp224k1    /*  = 20,  */       },
 
207
   {    233,     ec_sect233k1    /*  = 6,   */       },
 
208
   {    233,     ec_sect233r1    /*  = 7,   */       },
 
209
   {    239,     ec_sect239k1    /*  = 8,   */       },
 
210
   {    256,     ec_secp256r1    /*  = 23,  fast */  },
 
211
   {    256,     ec_secp256k1    /*  = 22,  */       },
 
212
   {    283,     ec_sect283k1    /*  = 9,   */       },
 
213
   {    283,     ec_sect283r1    /*  = 10,  */       },
 
214
   {    384,     ec_secp384r1    /*  = 24,  fast */  },
 
215
   {    409,     ec_sect409k1    /*  = 11,  */       },
 
216
   {    409,     ec_sect409r1    /*  = 12,  */       },
 
217
   {    521,     ec_secp521r1    /*  = 25,  fast */  },
 
218
   {    571,     ec_sect571k1    /*  = 13,  */       },
 
219
   {    571,     ec_sect571r1    /*  = 14,  */       },
 
220
   {  65535,     ec_noName    }
 
221
};
 
222
 
 
223
typedef struct ECDHEKeyPairStr {
 
224
    ssl3KeyPair *  pair;
 
225
    PRInt32        flag;
 
226
    PRCallOnceType once;
 
227
} ECDHEKeyPair;
 
228
 
 
229
/* arrays of ECDHE KeyPairs */
 
230
static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName];
 
231
 
 
232
static SECStatus 
 
233
ecName2params(PRArenaPool * arena, ECName curve, SECKEYECParams * params)
 
234
{
 
235
    SECOidData *oidData = NULL;
 
236
 
 
237
    if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
 
238
        ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
 
239
        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
 
240
        return SECFailure;
 
241
    }
 
242
 
 
243
    SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
 
244
    /* 
 
245
     * params->data needs to contain the ASN encoding of an object ID (OID)
 
246
     * representing the named curve. The actual OID is in 
 
247
     * oidData->oid.data so we simply prepend 0x06 and OID length
 
248
     */
 
249
    params->data[0] = SEC_ASN1_OBJECT_ID;
 
250
    params->data[1] = oidData->oid.len;
 
251
    memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
 
252
 
 
253
    return SECSuccess;
 
254
}
 
255
 
 
256
static ECName 
 
257
params2ecName(SECKEYECParams * params)
 
258
{
 
259
    SECItem oid = { siBuffer, NULL, 0};
 
260
    SECOidData *oidData = NULL;
 
261
    ECName i;
 
262
 
 
263
    /* 
 
264
     * params->data needs to contain the ASN encoding of an object ID (OID)
 
265
     * representing a named curve. Here, we strip away everything
 
266
     * before the actual OID and use the OID to look up a named curve.
 
267
     */
 
268
    if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
 
269
    oid.len = params->len - 2;
 
270
    oid.data = params->data + 2;
 
271
    if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
 
272
    for (i = ec_noName + 1; i < ec_pastLastName; i++) {
 
273
        if (ecName2OIDTag[i] == oidData->offset)
 
274
            return i;
 
275
    }
 
276
 
 
277
    return ec_noName;
 
278
}
 
279
 
 
280
/* Caller must set hiLevel error code. */
 
281
static SECStatus
 
282
ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint,
 
283
                             SSL3Random *client_rand, SSL3Random *server_rand,
 
284
                             SSL3Hashes *hashes, PRBool bypassPKCS11)
 
285
{
 
286
    PRUint8     * hashBuf;
 
287
    PRUint8     * pBuf;
 
288
    SECStatus     rv            = SECSuccess;
 
289
    unsigned int  bufLen;
 
290
    /*
 
291
     * XXX For now, we only support named curves (the appropriate
 
292
     * checks are made before this method is called) so ec_params
 
293
     * takes up only two bytes. ECPoint needs to fit in 256 bytes
 
294
     * (because the spec says the length must fit in one byte)
 
295
     */
 
296
    PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
 
297
 
 
298
    bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
 
299
    if (bufLen <= sizeof buf) {
 
300
        hashBuf = buf;
 
301
    } else {
 
302
        hashBuf = PORT_Alloc(bufLen);
 
303
        if (!hashBuf) {
 
304
            return SECFailure;
 
305
        }
 
306
    }
 
307
 
 
308
    memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); 
 
309
        pBuf = hashBuf + SSL3_RANDOM_LENGTH;
 
310
    memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
 
311
        pBuf += SSL3_RANDOM_LENGTH;
 
312
    memcpy(pBuf, ec_params.data, ec_params.len);
 
313
        pBuf += ec_params.len;
 
314
    pBuf[0] = (PRUint8)(server_ecpoint.len);
 
315
    pBuf += 1;
 
316
    memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
 
317
        pBuf += server_ecpoint.len;
 
318
    PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
 
319
 
 
320
    rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
 
321
 
 
322
    PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
 
323
    PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
 
324
    PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
 
325
 
 
326
    if (hashBuf != buf && hashBuf != NULL)
 
327
        PORT_Free(hashBuf);
 
328
    return rv;
 
329
}
 
330
 
 
331
 
 
332
/* Called from ssl3_SendClientKeyExchange(). */
 
333
SECStatus
 
334
ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
 
335
{
 
336
    PK11SymKey *        pms             = NULL;
 
337
    SECStatus           rv              = SECFailure;
 
338
    PRBool              isTLS;
 
339
    CK_MECHANISM_TYPE   target;
 
340
    SECKEYPublicKey     *pubKey = NULL;         /* Ephemeral ECDH key */
 
341
    SECKEYPrivateKey    *privKey = NULL;        /* Ephemeral ECDH key */
 
342
 
 
343
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
 
344
    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
 
345
 
 
346
    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
 
347
 
 
348
    /* Generate ephemeral EC keypair */
 
349
    /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
 
350
    privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, 
 
351
                                        &pubKey, NULL);
 
352
    if (!privKey || !pubKey) {
 
353
            ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
 
354
            rv = SECFailure;
 
355
            goto loser;
 
356
    }
 
357
    PRINT_BUF(50, (ss, "ECDH public value:",
 
358
                                        pubKey->u.ec.publicValue.data,
 
359
                                        pubKey->u.ec.publicValue.len));
 
360
 
 
361
    if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
 
362
    else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
 
363
 
 
364
    /*  Determine the PMS */
 
365
    pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
 
366
                            CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
 
367
                            CKD_NULL, NULL, NULL);
 
368
 
 
369
    if (pms == NULL) {
 
370
        SSL3AlertDescription desc  = illegal_parameter;
 
371
        (void)SSL3_SendAlert(ss, alert_fatal, desc);
 
372
        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
 
373
        goto loser;
 
374
    }
 
375
 
 
376
    SECKEY_DestroyPrivateKey(privKey);
 
377
    privKey = NULL;
 
378
 
 
379
    rv = ssl3_InitPendingCipherSpec(ss,  pms);
 
380
    PK11_FreeSymKey(pms); pms = NULL;
 
381
 
 
382
    if (rv != SECSuccess) {
 
383
        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
 
384
        goto loser;
 
385
    }
 
386
 
 
387
    rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, 
 
388
                                        pubKey->u.ec.publicValue.len + 1);
 
389
    if (rv != SECSuccess) {
 
390
        goto loser;     /* err set by ssl3_AppendHandshake* */
 
391
    }
 
392
 
 
393
    rv = ssl3_AppendHandshakeVariable(ss, 
 
394
                                        pubKey->u.ec.publicValue.data,
 
395
                                        pubKey->u.ec.publicValue.len, 1);
 
396
    SECKEY_DestroyPublicKey(pubKey);
 
397
    pubKey = NULL;
 
398
 
 
399
    if (rv != SECSuccess) {
 
400
        goto loser;     /* err set by ssl3_AppendHandshake* */
 
401
    }
 
402
 
 
403
    rv = SECSuccess;
 
404
 
 
405
loser:
 
406
    if(pms) PK11_FreeSymKey(pms);
 
407
    if(privKey) SECKEY_DestroyPrivateKey(privKey);
 
408
    if(pubKey) SECKEY_DestroyPublicKey(pubKey);
 
409
    return rv;
 
410
}
 
411
 
 
412
 
 
413
/*
 
414
** Called from ssl3_HandleClientKeyExchange()
 
415
*/
 
416
SECStatus
 
417
ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
 
418
                                     PRUint32 length,
 
419
                                     SECKEYPublicKey *srvrPubKey,
 
420
                                     SECKEYPrivateKey *srvrPrivKey)
 
421
{
 
422
    PK11SymKey *      pms;
 
423
    SECStatus         rv;
 
424
    SECKEYPublicKey   clntPubKey;
 
425
    CK_MECHANISM_TYPE   target;
 
426
    PRBool isTLS;
 
427
 
 
428
    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
 
429
    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
 
430
 
 
431
    clntPubKey.keyType = ecKey;
 
432
    clntPubKey.u.ec.DEREncodedParams.len = 
 
433
        srvrPubKey->u.ec.DEREncodedParams.len;
 
434
    clntPubKey.u.ec.DEREncodedParams.data = 
 
435
        srvrPubKey->u.ec.DEREncodedParams.data;
 
436
 
 
437
    rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, 
 
438
                                       1, &b, &length);
 
439
    if (rv != SECSuccess) {
 
440
        SEND_ALERT
 
441
        return SECFailure;      /* XXX Who sets the error code?? */
 
442
    }
 
443
 
 
444
    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
 
445
 
 
446
    if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
 
447
    else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
 
448
 
 
449
    /*  Determine the PMS */
 
450
    pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
 
451
                            CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
 
452
                            CKD_NULL, NULL, NULL);
 
453
 
 
454
    if (pms == NULL) {
 
455
        /* last gasp.  */
 
456
        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
 
457
        return SECFailure;
 
458
    }
 
459
 
 
460
    rv = ssl3_InitPendingCipherSpec(ss,  pms);
 
461
    PK11_FreeSymKey(pms);
 
462
    if (rv != SECSuccess) {
 
463
        SEND_ALERT
 
464
        return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
 
465
    }
 
466
    return SECSuccess;
 
467
}
 
468
 
 
469
/* find the "weakest link".  Get strength of signature key and of sym key.
 
470
 * choose curve for the weakest of those two.
 
471
 */
 
472
ECName
 
473
ssl3_GetCurveNameForServerSocket(sslSocket *ss)
 
474
{
 
475
    SECKEYPublicKey * svrPublicKey = NULL;
 
476
    ECName ec_curve = ec_noName;
 
477
    int    signatureKeyStrength = 521;
 
478
    int    requiredECCbits = ss->sec.secretKeyBits * 2;
 
479
    int    i;
 
480
 
 
481
    if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) {
 
482
        svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh);
 
483
        if (svrPublicKey)
 
484
            ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams);
 
485
        if (!SSL_IS_CURVE_NEGOTIATED(ss, ec_curve)) {
 
486
            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
 
487
            return ec_noName;
 
488
        }
 
489
        signatureKeyStrength = curve2bits[ ec_curve ];
 
490
    } else {
 
491
        /* RSA is our signing cert */
 
492
        int serverKeyStrengthInBits;
 
493
 
 
494
        svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
 
495
        if (!svrPublicKey) {
 
496
            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
 
497
            return ec_noName;
 
498
        }
 
499
 
 
500
        /* currently strength in bytes */
 
501
        serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len;
 
502
        if (svrPublicKey->u.rsa.modulus.data[0] == 0) {
 
503
            serverKeyStrengthInBits--;
 
504
        }
 
505
        /* convert to strength in bits */
 
506
        serverKeyStrengthInBits *= BPB;
 
507
 
 
508
        if (serverKeyStrengthInBits <= 1024) {
 
509
            signatureKeyStrength = 160;
 
510
        } else if (serverKeyStrengthInBits <= 2048) {
 
511
            signatureKeyStrength = 224;
 
512
        } else if (serverKeyStrengthInBits <= 3072) {
 
513
            signatureKeyStrength = 256;
 
514
        } else if (serverKeyStrengthInBits <= 7168) {
 
515
            signatureKeyStrength = 384;
 
516
        } else  {
 
517
            signatureKeyStrength = 521;
 
518
        }
 
519
    }
 
520
    if ( requiredECCbits > signatureKeyStrength ) 
 
521
         requiredECCbits = signatureKeyStrength;
 
522
 
 
523
    for ( i = 0; bits2curve[i].curve != ec_noName; i++) {
 
524
        if (bits2curve[i].bits < requiredECCbits)
 
525
            continue;
 
526
        if (SSL_IS_CURVE_NEGOTIATED(ss, bits2curve[i].curve)) {
 
527
            return bits2curve[i].curve;
 
528
        }
 
529
    }
 
530
    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
 
531
    return ec_noName;
 
532
}
 
533
 
 
534
/* function to clear out the lists */
 
535
static SECStatus 
 
536
ssl3_ShutdownECDHECurves(void *appData, void *nssData)
 
537
{
 
538
    int i;
 
539
    ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
 
540
 
 
541
    for (i=0; i < ec_pastLastName; i++, keyPair++) {
 
542
        if (keyPair->pair) {
 
543
            ssl3_FreeKeyPair(keyPair->pair);
 
544
        }
 
545
    }
 
546
    memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
 
547
    return SECSuccess;
 
548
}
 
549
 
 
550
static PRStatus
 
551
ssl3_ECRegister(void)
 
552
{
 
553
   SECStatus rv;
 
554
   rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
 
555
   return (PRStatus)rv;
 
556
}
 
557
 
 
558
/* CallOnce function, called once for each named curve. */
 
559
static PRStatus 
 
560
ssl3_CreateECDHEphemeralKeyPair(void * arg)
 
561
{
 
562
    SECKEYPrivateKey *    privKey  = NULL;
 
563
    SECKEYPublicKey *     pubKey   = NULL;
 
564
    ssl3KeyPair *         keyPair  = NULL;
 
565
    ECName                ec_curve = (ECName)arg;
 
566
    SECKEYECParams        ecParams = { siBuffer, NULL, 0 };
 
567
 
 
568
    PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
 
569
 
 
570
    /* ok, no one has generated a global key for this curve yet, do so */
 
571
    if (ecName2params(NULL, ec_curve, &ecParams) != SECSuccess) {
 
572
        return PR_FAILURE;
 
573
    }
 
574
 
 
575
    privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);    
 
576
    SECITEM_FreeItem(&ecParams, PR_FALSE);
 
577
 
 
578
    if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
 
579
        if (privKey) {
 
580
            SECKEY_DestroyPrivateKey(privKey);
 
581
        }
 
582
        if (pubKey) {
 
583
            SECKEY_DestroyPublicKey(pubKey);
 
584
        }
 
585
        ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
 
586
        return PR_FAILURE;
 
587
    }
 
588
 
 
589
    gECDHEKeyPairs[ec_curve].pair = keyPair;
 
590
    return PR_SUCCESS;
 
591
}
 
592
 
 
593
/*
 
594
 * Creates the ephemeral public and private ECDH keys used by
 
595
 * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
 
596
 * For now, the elliptic curve is chosen to be the same
 
597
 * strength as the signing certificate (ECC or RSA).
 
598
 * We need an API to specify the curve. This won't be a real
 
599
 * issue until we further develop server-side support for ECC
 
600
 * cipher suites.
 
601
 */
 
602
static SECStatus
 
603
ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve)
 
604
{
 
605
    ssl3KeyPair *         keyPair        = NULL;
 
606
 
 
607
    /* if there's no global key for this curve, make one. */
 
608
    if (gECDHEKeyPairs[ec_curve].pair == NULL) {
 
609
        PRStatus status;
 
610
 
 
611
        status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister);
 
612
        if (status != PR_SUCCESS) {
 
613
            return SECFailure;
 
614
        }
 
615
        status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once,
 
616
                                    ssl3_CreateECDHEphemeralKeyPair,
 
617
                                    (void *)ec_curve);
 
618
        if (status != PR_SUCCESS) {
 
619
            return SECFailure;
 
620
        }
 
621
    }
 
622
 
 
623
    keyPair = gECDHEKeyPairs[ec_curve].pair;
 
624
    PORT_Assert(keyPair != NULL);
 
625
    if (!keyPair) 
 
626
        return SECFailure;
 
627
    ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
 
628
 
 
629
    return SECSuccess;
 
630
}
 
631
 
 
632
SECStatus
 
633
ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
 
634
{
 
635
    PRArenaPool *    arena     = NULL;
 
636
    SECKEYPublicKey *peerKey   = NULL;
 
637
    PRBool           isTLS;
 
638
    SECStatus        rv;
 
639
    int              errCode   = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
 
640
    SSL3AlertDescription desc  = illegal_parameter;
 
641
    SSL3Hashes       hashes;
 
642
    SECItem          signature = {siBuffer, NULL, 0};
 
643
 
 
644
    SECItem          ec_params = {siBuffer, NULL, 0};
 
645
    SECItem          ec_point  = {siBuffer, NULL, 0};
 
646
    unsigned char    paramBuf[3]; /* only for curve_type == named_curve */
 
647
 
 
648
    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
 
649
 
 
650
    /* XXX This works only for named curves, revisit this when
 
651
     * we support generic curves.
 
652
     */
 
653
    ec_params.len  = sizeof paramBuf;
 
654
    ec_params.data = paramBuf;
 
655
    rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
 
656
    if (rv != SECSuccess) {
 
657
        goto loser;             /* malformed. */
 
658
    }
 
659
 
 
660
    /* Fail if the curve is not a named curve */
 
661
    if ((ec_params.data[0] != ec_type_named) || 
 
662
        (ec_params.data[1] != 0) ||
 
663
        !supportedCurve(ec_params.data[2])) {
 
664
            errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
 
665
            desc = handshake_failure;
 
666
            goto alert_loser;
 
667
    }
 
668
 
 
669
    rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
 
670
    if (rv != SECSuccess) {
 
671
        goto loser;             /* malformed. */
 
672
    }
 
673
    /* Fail if the ec point uses compressed representation */
 
674
    if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
 
675
            errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
 
676
            desc = handshake_failure;
 
677
            goto alert_loser;
 
678
    }
 
679
 
 
680
    rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
 
681
    if (rv != SECSuccess) {
 
682
        goto loser;             /* malformed. */
 
683
    }
 
684
 
 
685
    if (length != 0) {
 
686
        if (isTLS)
 
687
            desc = decode_error;
 
688
        goto alert_loser;               /* malformed. */
 
689
    }
 
690
 
 
691
    PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, 
 
692
        ec_params.len));
 
693
    PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
 
694
 
 
695
    /* failures after this point are not malformed handshakes. */
 
696
    /* TLS: send decrypt_error if signature failed. */
 
697
    desc = isTLS ? decrypt_error : handshake_failure;
 
698
 
 
699
    /*
 
700
     *  check to make sure the hash is signed by right guy
 
701
     */
 
702
    rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point,
 
703
                                      &ss->ssl3.hs.client_random,
 
704
                                      &ss->ssl3.hs.server_random, 
 
705
                                      &hashes, ss->opt.bypassPKCS11);
 
706
 
 
707
    if (rv != SECSuccess) {
 
708
        errCode =
 
709
            ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 
710
        goto alert_loser;
 
711
    }
 
712
    rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
 
713
                                isTLS, ss->pkcs11PinArg);
 
714
    if (rv != SECSuccess)  {
 
715
        errCode =
 
716
            ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 
717
        goto alert_loser;
 
718
    }
 
719
 
 
720
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 
721
    if (arena == NULL) {
 
722
        goto no_memory;
 
723
    }
 
724
 
 
725
    ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
 
726
    if (peerKey == NULL) {
 
727
        goto no_memory;
 
728
    }
 
729
 
 
730
    peerKey->arena                 = arena;
 
731
    peerKey->keyType               = ecKey;
 
732
 
 
733
    /* set up EC parameters in peerKey */
 
734
    if (ecName2params(arena, ec_params.data[2], 
 
735
            &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
 
736
        /* we should never get here since we already 
 
737
         * checked that we are dealing with a supported curve
 
738
         */
 
739
        errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
 
740
        goto alert_loser;
 
741
    }
 
742
 
 
743
    /* copy publicValue in peerKey */
 
744
    if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue,  &ec_point))
 
745
    {
 
746
        PORT_FreeArena(arena, PR_FALSE);
 
747
        goto no_memory;
 
748
    }
 
749
    peerKey->pkcs11Slot         = NULL;
 
750
    peerKey->pkcs11ID           = CK_INVALID_HANDLE;
 
751
 
 
752
    ss->sec.peerKey = peerKey;
 
753
    ss->ssl3.hs.ws = wait_cert_request;
 
754
 
 
755
    return SECSuccess;
 
756
 
 
757
alert_loser:
 
758
    (void)SSL3_SendAlert(ss, alert_fatal, desc);
 
759
loser:
 
760
    PORT_SetError( errCode );
 
761
    return SECFailure;
 
762
 
 
763
no_memory:      /* no-memory error has already been set. */
 
764
    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 
765
    return SECFailure;
 
766
}
 
767
 
 
768
SECStatus
 
769
ssl3_SendECDHServerKeyExchange(sslSocket *ss)
 
770
{
 
771
const ssl3KEADef *     kea_def     = ss->ssl3.hs.kea_def;
 
772
    SECStatus          rv          = SECFailure;
 
773
    int                length;
 
774
    PRBool             isTLS;
 
775
    SECItem            signed_hash = {siBuffer, NULL, 0};
 
776
    SSL3Hashes         hashes;
 
777
 
 
778
    SECKEYPublicKey *  ecdhePub;
 
779
    SECItem            ec_params = {siBuffer, NULL, 0};
 
780
    unsigned char      paramBuf[3];
 
781
    ECName             curve;
 
782
    SSL3KEAType        certIndex;
 
783
 
 
784
 
 
785
    /* Generate ephemeral ECDH key pair and send the public key */
 
786
    curve = ssl3_GetCurveNameForServerSocket(ss);
 
787
    if (curve == ec_noName) {
 
788
        goto loser;
 
789
    }
 
790
    rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
 
791
    if (rv != SECSuccess) {
 
792
        goto loser;     /* err set by AppendHandshake. */
 
793
    }       
 
794
    ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
 
795
    PORT_Assert(ecdhePub != NULL);
 
796
    if (!ecdhePub) {
 
797
        PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 
798
        return SECFailure;
 
799
    }   
 
800
    
 
801
    ec_params.len  = sizeof paramBuf;
 
802
    ec_params.data = paramBuf;
 
803
    curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
 
804
    if (curve != ec_noName) {
 
805
        ec_params.data[0] = ec_type_named;
 
806
        ec_params.data[1] = 0x00;
 
807
        ec_params.data[2] = curve;
 
808
    } else {
 
809
        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
 
810
        goto loser;
 
811
    }           
 
812
 
 
813
    rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue,
 
814
                                      &ss->ssl3.hs.client_random,
 
815
                                      &ss->ssl3.hs.server_random,
 
816
                                      &hashes, ss->opt.bypassPKCS11);
 
817
    if (rv != SECSuccess) {
 
818
        ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 
819
        goto loser;
 
820
    }
 
821
 
 
822
    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
 
823
 
 
824
    /* XXX SSLKEAType isn't really a good choice for 
 
825
     * indexing certificates but that's all we have
 
826
     * for now.
 
827
     */
 
828
    if (kea_def->kea == kea_ecdhe_rsa)
 
829
        certIndex = kt_rsa;
 
830
    else /* kea_def->kea == kea_ecdhe_ecdsa */
 
831
        certIndex = kt_ecdh;
 
832
 
 
833
    rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, 
 
834
                         &signed_hash, isTLS);
 
835
    if (rv != SECSuccess) {
 
836
        goto loser;             /* ssl3_SignHashes has set err. */
 
837
    }
 
838
    if (signed_hash.data == NULL) {
 
839
        /* how can this happen and rv == SECSuccess ?? */
 
840
        PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
 
841
        goto loser;
 
842
    }
 
843
 
 
844
    length = ec_params.len + 
 
845
             1 + ecdhePub->u.ec.publicValue.len + 
 
846
             2 + signed_hash.len;
 
847
 
 
848
    rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
 
849
    if (rv != SECSuccess) {
 
850
        goto loser;     /* err set by AppendHandshake. */
 
851
    }
 
852
 
 
853
    rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
 
854
    if (rv != SECSuccess) {
 
855
        goto loser;     /* err set by AppendHandshake. */
 
856
    }
 
857
 
 
858
    rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
 
859
                                      ecdhePub->u.ec.publicValue.len, 1);
 
860
    if (rv != SECSuccess) {
 
861
        goto loser;     /* err set by AppendHandshake. */
 
862
    }
 
863
 
 
864
    rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
 
865
                                      signed_hash.len, 2);
 
866
    if (rv != SECSuccess) {
 
867
        goto loser;     /* err set by AppendHandshake. */
 
868
    }
 
869
 
 
870
    PORT_Free(signed_hash.data);
 
871
    return SECSuccess;
 
872
 
 
873
loser:
 
874
    if (signed_hash.data != NULL) 
 
875
        PORT_Free(signed_hash.data);
 
876
    return SECFailure;
 
877
}
 
878
 
 
879
/* Lists of ECC cipher suites for searching and disabling. */
 
880
 
 
881
static const ssl3CipherSuite ecdh_suites[] = {
 
882
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
 
883
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
 
884
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
 
885
    TLS_ECDH_ECDSA_WITH_NULL_SHA,
 
886
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
 
887
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
 
888
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
 
889
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
 
890
    TLS_ECDH_RSA_WITH_NULL_SHA,
 
891
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
 
892
    0 /* end of list marker */
 
893
};
 
894
 
 
895
static const ssl3CipherSuite ecdh_ecdsa_suites[] = {
 
896
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
 
897
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
 
898
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
 
899
    TLS_ECDH_ECDSA_WITH_NULL_SHA,
 
900
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
 
901
    0 /* end of list marker */
 
902
};
 
903
 
 
904
static const ssl3CipherSuite ecdh_rsa_suites[] = {
 
905
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
 
906
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
 
907
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
 
908
    TLS_ECDH_RSA_WITH_NULL_SHA,
 
909
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
 
910
    0 /* end of list marker */
 
911
};
 
912
 
 
913
static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
 
914
    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
 
915
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
 
916
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
 
917
    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
 
918
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
 
919
    0 /* end of list marker */
 
920
};
 
921
 
 
922
static const ssl3CipherSuite ecdhe_rsa_suites[] = {
 
923
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
 
924
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
 
925
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
 
926
    TLS_ECDHE_RSA_WITH_NULL_SHA,
 
927
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
 
928
    0 /* end of list marker */
 
929
};
 
930
 
 
931
/* List of all ECC cipher suites */
 
932
static const ssl3CipherSuite ecSuites[] = {
 
933
    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
 
934
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
 
935
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
 
936
    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
 
937
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
 
938
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
 
939
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
 
940
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
 
941
    TLS_ECDHE_RSA_WITH_NULL_SHA,
 
942
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
 
943
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
 
944
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
 
945
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
 
946
    TLS_ECDH_ECDSA_WITH_NULL_SHA,
 
947
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
 
948
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
 
949
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
 
950
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
 
951
    TLS_ECDH_RSA_WITH_NULL_SHA,
 
952
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
 
953
    0 /* end of list marker */
 
954
};
 
955
 
 
956
/* On this socket, Disable the ECC cipher suites in the argument's list */
 
957
SECStatus
 
958
ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
 
959
{
 
960
    if (!suite)
 
961
        suite = ecSuites;
 
962
    for (; *suite; ++suite) {
 
963
        SECStatus rv      = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
 
964
 
 
965
        PORT_Assert(rv == SECSuccess); /* else is coding error */
 
966
    }
 
967
    return SECSuccess;
 
968
}
 
969
 
 
970
/* Look at the server certs configured on this socket, and disable any
 
971
 * ECC cipher suites that are not supported by those certs.
 
972
 */
 
973
void
 
974
ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
 
975
{
 
976
    CERTCertificate * svrCert;
 
977
 
 
978
    svrCert = ss->serverCerts[kt_rsa].serverCert;
 
979
    if (!svrCert) {
 
980
        ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
 
981
    }
 
982
 
 
983
    svrCert = ss->serverCerts[kt_ecdh].serverCert;
 
984
    if (!svrCert) {
 
985
        ssl3_DisableECCSuites(ss, ecdh_suites);
 
986
        ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
 
987
    } else {
 
988
        SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
 
989
 
 
990
        switch (sigTag) {
 
991
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
 
992
        case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
 
993
        case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
 
994
        case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
 
995
        case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
 
996
        case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
 
997
        case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
 
998
        case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 
999
            ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
 
1000
            break;
 
1001
        case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
 
1002
        case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
 
1003
        case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
 
1004
        case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
 
1005
        case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
 
1006
        case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
 
1007
        case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
 
1008
            ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
 
1009
            break;
 
1010
        default:
 
1011
            ssl3_DisableECCSuites(ss, ecdh_suites);
 
1012
            break;
 
1013
        }
 
1014
    }
 
1015
}
 
1016
 
 
1017
/* Ask: is ANY ECC cipher suite enabled on this socket? */
 
1018
/* Order(N^2).  Yuk.  Also, this ignores export policy. */
 
1019
PRBool
 
1020
ssl3_IsECCEnabled(sslSocket * ss)
 
1021
{
 
1022
    const ssl3CipherSuite * suite;
 
1023
 
 
1024
    for (suite = ecSuites; *suite; ++suite) {
 
1025
        PRBool    enabled = PR_FALSE;
 
1026
        SECStatus rv      = ssl3_CipherPrefGet(ss, *suite, &enabled);
 
1027
 
 
1028
        PORT_Assert(rv == SECSuccess); /* else is coding error */
 
1029
        if (rv == SECSuccess && enabled)
 
1030
            return PR_TRUE;
 
1031
    }
 
1032
    return PR_FALSE;
 
1033
}
 
1034
 
 
1035
#define BE(n) 0, n
 
1036
 
 
1037
#ifndef NSS_ECC_MORE_THAN_SUITE_B
 
1038
/* Prefabricated TLS client hello extension, Elliptic Curves List,
 
1039
 * offers only 3 curves, the Suite B curves, 23-25 
 
1040
 */
 
1041
static const PRUint8 EClist[12] = {
 
1042
    BE(10),         /* Extension type */
 
1043
    BE( 8),         /* octets that follow ( 3 pairs + 1 length pair) */
 
1044
    BE( 6),         /* octets that follow ( 3 pairs) */
 
1045
    BE(23), BE(24), BE(25)
 
1046
};
 
1047
#else
 
1048
/* Prefabricated TLS client hello extension, Elliptic Curves List,
 
1049
 * offers curves 1-25.
 
1050
 */
 
1051
static const PRUint8 EClist[56] = {
 
1052
    BE(10),         /* Extension type */
 
1053
    BE(52),         /* octets that follow (25 pairs + 1 length pair) */
 
1054
    BE(50),         /* octets that follow (25 pairs) */
 
1055
            BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7), 
 
1056
    BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15), 
 
1057
    BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23), 
 
1058
    BE(24), BE(25)
 
1059
};
 
1060
#endif
 
1061
 
 
1062
static const PRUint8 ECPtFmt[6] = {
 
1063
    BE(11),         /* Extension type */
 
1064
    BE( 2),         /* octets that follow */
 
1065
             1,     /* octets that follow */
 
1066
                 0  /* uncompressed type only */
 
1067
};
 
1068
 
 
1069
/* Send our "canned" (precompiled) Supported Elliptic Curves extension,
 
1070
 * which says that we support all TLS-defined named curves.
 
1071
 */
 
1072
PRInt32
 
1073
ssl3_SendSupportedEllipticCurvesExtension(
 
1074
                        sslSocket * ss,
 
1075
                        PRBool      append,
 
1076
                        PRUint32    maxBytes)
 
1077
{
 
1078
    if (!ss || !ssl3_IsECCEnabled(ss))
 
1079
        return 0;
 
1080
    if (append && maxBytes >= (sizeof EClist)) {
 
1081
        SECStatus rv = ssl3_AppendHandshake(ss, EClist, (sizeof EClist));
 
1082
    }
 
1083
    return (sizeof EClist);
 
1084
}
 
1085
 
 
1086
/* Send our "canned" (precompiled) Supported Point Formats extension,
 
1087
 * which says that we only support uncompressed points.
 
1088
 */
 
1089
PRInt32
 
1090
ssl3_SendSupportedPointFormatsExtension(
 
1091
                        sslSocket * ss,
 
1092
                        PRBool      append,
 
1093
                        PRUint32    maxBytes)
 
1094
{
 
1095
    if (!ss || !ssl3_IsECCEnabled(ss))
 
1096
        return 0;
 
1097
    if (append && maxBytes >= (sizeof ECPtFmt)) {
 
1098
        SECStatus rv = ssl3_AppendHandshake(ss, ECPtFmt, (sizeof ECPtFmt));
 
1099
    }
 
1100
    return (sizeof ECPtFmt);
 
1101
}
 
1102
 
 
1103
/* Just make sure that the remote client supports uncompressed points,
 
1104
 * Since that is all we support.  Disable ECC cipher suites if it doesn't.
 
1105
 */
 
1106
static SECStatus
 
1107
ssl3_HandleSupportedPointFormatsExtension(sslSocket * ss, PRUint16 ex_type, 
 
1108
                                          SECItem *data)
 
1109
{
 
1110
    int i;
 
1111
 
 
1112
    if (data->len < 2 || data->len > 255 || !data->data ||
 
1113
        data->len != (unsigned int)data->data[0] + 1) {
 
1114
        /* malformed */
 
1115
        goto loser;
 
1116
    }
 
1117
    for (i = data->len; --i > 0; ) {
 
1118
        if (data->data[i] == 0) {
 
1119
            /* indicate that we should send a reply */
 
1120
            SECStatus rv;
 
1121
            rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
 
1122
                              &ssl3_SendSupportedPointFormatsExtension);
 
1123
            return rv;
 
1124
        }
 
1125
    }
 
1126
loser:
 
1127
    /* evil client doesn't support uncompressed */
 
1128
    ssl3_DisableECCSuites(ss, ecSuites);
 
1129
    return SECFailure;
 
1130
}
 
1131
 
 
1132
 
 
1133
#define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
 
1134
    (ss->serverCerts[type].serverKeyPair ? \
 
1135
    ss->serverCerts[type].serverKeyPair->pubKey : NULL)
 
1136
 
 
1137
/* Extract the TLS curve name for the public key in our EC server cert. */
 
1138
ECName ssl3_GetSvrCertCurveName(sslSocket *ss) 
 
1139
{
 
1140
    SECKEYPublicKey       *srvPublicKey; 
 
1141
    ECName                ec_curve       = ec_noName;
 
1142
 
 
1143
    srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
 
1144
    if (srvPublicKey) {
 
1145
        ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
 
1146
    }
 
1147
    return ec_curve;
 
1148
}
 
1149
 
 
1150
/* Ensure that the curve in our server cert is one of the ones suppored
 
1151
 * by the remote client, and disable all ECC cipher suites if not.
 
1152
 */
 
1153
static SECStatus
 
1154
ssl3_HandleSupportedEllipticCurvesExtension(sslSocket * ss, PRUint16 ex_type, 
 
1155
                                            SECItem *data)
 
1156
{
 
1157
    PRInt32  list_len;
 
1158
    PRUint32 peerCurves   = 0;
 
1159
    PRUint32 mutualCurves = 0;
 
1160
    PRUint16 svrCertCurveName;
 
1161
 
 
1162
    if (!data->data || data->len < 4 || data->len > 65535)
 
1163
        goto loser;
 
1164
    /* get the length of elliptic_curve_list */
 
1165
    list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
 
1166
    if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
 
1167
        /* malformed */
 
1168
        goto loser;
 
1169
    }
 
1170
    /* build bit vector of peer's supported curve names */
 
1171
    while (data->len) {
 
1172
        PRInt32  curve_name = 
 
1173
                 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
 
1174
        if (curve_name > ec_noName && curve_name < ec_pastLastName) {
 
1175
            peerCurves |= (1U << curve_name);
 
1176
        }
 
1177
    }
 
1178
    /* What curves do we support in common? */
 
1179
    mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
 
1180
    if (!mutualCurves) { /* no mutually supported EC Curves */
 
1181
        goto loser;
 
1182
    }
 
1183
 
 
1184
    /* if our ECC cert doesn't use one of these supported curves, 
 
1185
     * disable ECC cipher suites that require an ECC cert. 
 
1186
     */
 
1187
    svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
 
1188
    if (svrCertCurveName != ec_noName &&
 
1189
        (mutualCurves & (1U << svrCertCurveName)) != 0) {
 
1190
        return SECSuccess;
 
1191
    }
 
1192
    /* Our EC cert doesn't contain a mutually supported curve.
 
1193
     * Disable all ECC cipher suites that require an EC cert 
 
1194
     */
 
1195
    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
 
1196
    ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
 
1197
    return SECFailure;
 
1198
 
 
1199
loser:
 
1200
    /* no common curve supported */
 
1201
    ssl3_DisableECCSuites(ss, ecSuites);
 
1202
    return SECFailure;
 
1203
}
 
1204
 
 
1205
#endif /* NSS_ENABLE_ECC */
 
1206
 
 
1207
/* Format an SNI extension, using the name from the socket's URL,
 
1208
 * unless that name is a dotted decimal string.
 
1209
 */
 
1210
PRInt32 
 
1211
ssl3_SendServerNameIndicationExtension(
 
1212
                        sslSocket * ss,
 
1213
                        PRBool      append,
 
1214
                        PRUint32    maxBytes)
 
1215
{
 
1216
    PRUint32 len, span;
 
1217
    /* must have a hostname */
 
1218
    if (!ss || !ss->url || !ss->url[0])
 
1219
        return 0;
 
1220
    /* must have at lest one character other than [0-9\.] */
 
1221
    len  = PORT_Strlen(ss->url);
 
1222
    span = strspn(ss->url, "0123456789.");
 
1223
    if (len == span) {
 
1224
        /* is a dotted decimal IP address */
 
1225
        return 0;
 
1226
    }
 
1227
    if (append && maxBytes >= len + 9) {
 
1228
        SECStatus rv;
 
1229
        /* extension_type */
 
1230
        rv = ssl3_AppendHandshakeNumber(ss,       0, 2); 
 
1231
        if (rv != SECSuccess) return 0;
 
1232
        /* length of extension_data */
 
1233
        rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); 
 
1234
        if (rv != SECSuccess) return 0;
 
1235
        /* length of server_name_list */
 
1236
        rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
 
1237
        if (rv != SECSuccess) return 0;
 
1238
        /* Name Type (host_name) */
 
1239
        rv = ssl3_AppendHandshake(ss,       "\0",    1);
 
1240
        if (rv != SECSuccess) return 0;
 
1241
        /* HostName (length and value) */
 
1242
        rv = ssl3_AppendHandshakeVariable(ss, ss->url, len, 2);
 
1243
        if (rv != SECSuccess) return 0;
 
1244
    }
 
1245
    return len + 9;
 
1246
}
 
1247
 
 
1248
/* handle an incoming SNI extension, by ignoring it. */
 
1249
SECStatus
 
1250
ssl3_HandleServerNameIndicationExtension(sslSocket * ss, PRUint16 ex_type, 
 
1251
                                         SECItem *data)
 
1252
{
 
1253
    /* For now, we ignore this, as if we didn't understand it. :-)  */
 
1254
    return SECSuccess;
 
1255
}
 
1256
 
 
1257
/* Table of handlers for received TLS hello extensions, one per extension.
 
1258
 * In the second generation, this table will be dynamic, and functions
 
1259
 * will be registered here.
 
1260
 */
 
1261
static const ssl3HelloExtensionHandler handlers[] = {
 
1262
    {  0, &ssl3_HandleServerNameIndicationExtension    },
 
1263
#ifdef NSS_ENABLE_ECC
 
1264
    { 10, &ssl3_HandleSupportedEllipticCurvesExtension },
 
1265
    { 11, &ssl3_HandleSupportedPointFormatsExtension   },
 
1266
#endif
 
1267
    { -1, NULL }
 
1268
};
 
1269
 
 
1270
/* Table of functions to format TLS hello extensions, one per extension.
 
1271
 * This static table is for the formatting of client hello extensions.
 
1272
 * The server's table of hello senders is dynamic, in the socket struct,
 
1273
 * and sender functions are registered there.
 
1274
 */
 
1275
static const 
 
1276
ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSION_SENDERS] = {
 
1277
    {  0, &ssl3_SendServerNameIndicationExtension    },
 
1278
#ifdef NSS_ENABLE_ECC
 
1279
    { 10, &ssl3_SendSupportedEllipticCurvesExtension },
 
1280
    { 11, &ssl3_SendSupportedPointFormatsExtension   },
 
1281
#else
 
1282
    { -1, NULL }
 
1283
#endif
 
1284
};
 
1285
 
 
1286
/* go through hello extensions in buffer "b".
 
1287
 * For each one, find the extension handler in the table above, and 
 
1288
 * if present, invoke that handler.  
 
1289
 * ignore any extensions with unknown extension types.
 
1290
 */
 
1291
SECStatus 
 
1292
ssl3_HandleClientHelloExtensions(sslSocket *ss, 
 
1293
                                 SSL3Opaque **b, 
 
1294
                                 PRUint32 *length)
 
1295
{
 
1296
    while (*length) {
 
1297
        const ssl3HelloExtensionHandler * handler;
 
1298
        SECStatus rv;
 
1299
        PRInt32   extension_type;
 
1300
        SECItem   extension_data;
 
1301
 
 
1302
        /* Get the extension's type field */
 
1303
        extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
 
1304
        if (extension_type < 0)  /* failure to decode extension_type */
 
1305
            return SECFailure;   /* alert already sent */
 
1306
 
 
1307
        /* get the data for this extension, so we can pass it or skip it. */
 
1308
        rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
 
1309
        if (rv != SECSuccess)
 
1310
            return rv;
 
1311
 
 
1312
        /* find extension_type in table of Client Hello Extension Handlers */
 
1313
        for (handler = handlers; handler->ex_type >= 0; handler++) {
 
1314
            if (handler->ex_type == extension_type)
 
1315
                break;
 
1316
        }
 
1317
 
 
1318
        /* if found,  Call this handler */
 
1319
        if (handler->ex_type == extension_type) {
 
1320
            rv = (*handler->ex_handler)(ss, (PRUint16)extension_type, 
 
1321
                                                     &extension_data);
 
1322
            /* Ignore this result */
 
1323
            /* Essentially, treat all bad extensions as unrecognized types. */
 
1324
        }
 
1325
    }
 
1326
    return SECSuccess;
 
1327
}
 
1328
 
 
1329
/* Add a callback function to the table of senders of server hello extensions.
 
1330
 */
 
1331
SECStatus 
 
1332
ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
 
1333
                                        ssl3HelloExtensionSenderFunc cb)
 
1334
{
 
1335
    int i;
 
1336
    ssl3HelloExtensionSender *sender = &ss->serverExtensionSenders[0];
 
1337
 
 
1338
    for (i = 0; i < MAX_EXTENSION_SENDERS; ++i, ++sender) {
 
1339
        if (!sender->ex_sender) {
 
1340
            sender->ex_type   = ex_type;
 
1341
            sender->ex_sender = cb;
 
1342
            return SECSuccess;
 
1343
        }
 
1344
        /* detect duplicate senders */
 
1345
        PORT_Assert(sender->ex_type != ex_type);
 
1346
        if (sender->ex_type == ex_type) {
 
1347
            /* duplicate */
 
1348
            break;
 
1349
        }
 
1350
    }
 
1351
    PORT_Assert(i < MAX_EXTENSION_SENDERS); /* table needs to grow */
 
1352
    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 
1353
    return SECFailure;
 
1354
}
 
1355
 
 
1356
/* call each of the extension senders and return the accumulated length */
 
1357
PRInt32
 
1358
ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
 
1359
                               const ssl3HelloExtensionSender *sender)
 
1360
{
 
1361
    PRInt32 total_exten_len = 0;
 
1362
    int i;
 
1363
 
 
1364
    if (!sender)
 
1365
        sender = &clientHelloSenders[0];
 
1366
 
 
1367
    for (i = 0; i < MAX_EXTENSION_SENDERS; ++i, ++sender) {
 
1368
        if (sender->ex_sender) {
 
1369
            PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
 
1370
            if (extLen < 0)
 
1371
                return -1;
 
1372
            maxBytes        -= extLen;
 
1373
            total_exten_len += extLen;
 
1374
        }
 
1375
    }
 
1376
    return total_exten_len;
 
1377
}
 
1378