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