Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / net / third_party / nss / ssl / ssl3ecc.c
blobd5d6c9c6bc6903ea74ed9592672492170b08b94a
1 /*
2 * SSL3 Protocol
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 /* ECC code moved here from ssl3con.c */
10 #include "nss.h"
11 #include "cert.h"
12 #include "ssl.h"
13 #include "cryptohi.h" /* for DSAU_ stuff */
14 #include "keyhi.h"
15 #include "secder.h"
16 #include "secitem.h"
18 #include "sslimpl.h"
19 #include "sslproto.h"
20 #include "sslerr.h"
21 #include "prtime.h"
22 #include "prinrval.h"
23 #include "prerror.h"
24 #include "pratom.h"
25 #include "prthread.h"
26 #include "prinit.h"
28 #include "pk11func.h"
29 #include "secmod.h"
31 #include <stdio.h>
33 /* This is a bodge to allow this code to be compiled against older NSS headers
34 * that don't contain the TLS 1.2 changes. */
35 #ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
36 #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
37 #endif
39 #ifndef NSS_DISABLE_ECC
41 #ifndef PK11_SETATTRS
42 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
43 (x)->pValue=(v); (x)->ulValueLen = (l);
44 #endif
46 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
47 (ss->serverCerts[type].serverKeyPair ? \
48 ss->serverCerts[type].serverKeyPair->pubKey : NULL)
50 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \
51 ((curveName > ec_noName) && \
52 (curveName < ec_pastLastName) && \
53 ((1UL << curveName) & curvemsk) != 0)
57 static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve);
59 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
61 /* Table containing OID tags for elliptic curves named in the
62 * ECC-TLS IETF draft.
64 static const SECOidTag ecName2OIDTag[] = {
66 SEC_OID_SECG_EC_SECT163K1, /* 1 */
67 SEC_OID_SECG_EC_SECT163R1, /* 2 */
68 SEC_OID_SECG_EC_SECT163R2, /* 3 */
69 SEC_OID_SECG_EC_SECT193R1, /* 4 */
70 SEC_OID_SECG_EC_SECT193R2, /* 5 */
71 SEC_OID_SECG_EC_SECT233K1, /* 6 */
72 SEC_OID_SECG_EC_SECT233R1, /* 7 */
73 SEC_OID_SECG_EC_SECT239K1, /* 8 */
74 SEC_OID_SECG_EC_SECT283K1, /* 9 */
75 SEC_OID_SECG_EC_SECT283R1, /* 10 */
76 SEC_OID_SECG_EC_SECT409K1, /* 11 */
77 SEC_OID_SECG_EC_SECT409R1, /* 12 */
78 SEC_OID_SECG_EC_SECT571K1, /* 13 */
79 SEC_OID_SECG_EC_SECT571R1, /* 14 */
80 SEC_OID_SECG_EC_SECP160K1, /* 15 */
81 SEC_OID_SECG_EC_SECP160R1, /* 16 */
82 SEC_OID_SECG_EC_SECP160R2, /* 17 */
83 SEC_OID_SECG_EC_SECP192K1, /* 18 */
84 SEC_OID_SECG_EC_SECP192R1, /* 19 */
85 SEC_OID_SECG_EC_SECP224K1, /* 20 */
86 SEC_OID_SECG_EC_SECP224R1, /* 21 */
87 SEC_OID_SECG_EC_SECP256K1, /* 22 */
88 SEC_OID_SECG_EC_SECP256R1, /* 23 */
89 SEC_OID_SECG_EC_SECP384R1, /* 24 */
90 SEC_OID_SECG_EC_SECP521R1, /* 25 */
93 static const PRUint16 curve2bits[] = {
94 0, /* ec_noName = 0, */
95 163, /* ec_sect163k1 = 1, */
96 163, /* ec_sect163r1 = 2, */
97 163, /* ec_sect163r2 = 3, */
98 193, /* ec_sect193r1 = 4, */
99 193, /* ec_sect193r2 = 5, */
100 233, /* ec_sect233k1 = 6, */
101 233, /* ec_sect233r1 = 7, */
102 239, /* ec_sect239k1 = 8, */
103 283, /* ec_sect283k1 = 9, */
104 283, /* ec_sect283r1 = 10, */
105 409, /* ec_sect409k1 = 11, */
106 409, /* ec_sect409r1 = 12, */
107 571, /* ec_sect571k1 = 13, */
108 571, /* ec_sect571r1 = 14, */
109 160, /* ec_secp160k1 = 15, */
110 160, /* ec_secp160r1 = 16, */
111 160, /* ec_secp160r2 = 17, */
112 192, /* ec_secp192k1 = 18, */
113 192, /* ec_secp192r1 = 19, */
114 224, /* ec_secp224k1 = 20, */
115 224, /* ec_secp224r1 = 21, */
116 256, /* ec_secp256k1 = 22, */
117 256, /* ec_secp256r1 = 23, */
118 384, /* ec_secp384r1 = 24, */
119 521, /* ec_secp521r1 = 25, */
120 65535 /* ec_pastLastName */
123 typedef struct Bits2CurveStr {
124 PRUint16 bits;
125 ECName curve;
126 } Bits2Curve;
128 static const Bits2Curve bits2curve [] = {
129 { 192, ec_secp192r1 /* = 19, fast */ },
130 { 160, ec_secp160r2 /* = 17, fast */ },
131 { 160, ec_secp160k1 /* = 15, */ },
132 { 160, ec_secp160r1 /* = 16, */ },
133 { 163, ec_sect163k1 /* = 1, */ },
134 { 163, ec_sect163r1 /* = 2, */ },
135 { 163, ec_sect163r2 /* = 3, */ },
136 { 192, ec_secp192k1 /* = 18, */ },
137 { 193, ec_sect193r1 /* = 4, */ },
138 { 193, ec_sect193r2 /* = 5, */ },
139 { 224, ec_secp224r1 /* = 21, fast */ },
140 { 224, ec_secp224k1 /* = 20, */ },
141 { 233, ec_sect233k1 /* = 6, */ },
142 { 233, ec_sect233r1 /* = 7, */ },
143 { 239, ec_sect239k1 /* = 8, */ },
144 { 256, ec_secp256r1 /* = 23, fast */ },
145 { 256, ec_secp256k1 /* = 22, */ },
146 { 283, ec_sect283k1 /* = 9, */ },
147 { 283, ec_sect283r1 /* = 10, */ },
148 { 384, ec_secp384r1 /* = 24, fast */ },
149 { 409, ec_sect409k1 /* = 11, */ },
150 { 409, ec_sect409r1 /* = 12, */ },
151 { 521, ec_secp521r1 /* = 25, fast */ },
152 { 571, ec_sect571k1 /* = 13, */ },
153 { 571, ec_sect571r1 /* = 14, */ },
154 { 65535, ec_noName }
157 typedef struct ECDHEKeyPairStr {
158 ssl3KeyPair * pair;
159 int error; /* error code of the call-once function */
160 PRCallOnceType once;
161 } ECDHEKeyPair;
163 /* arrays of ECDHE KeyPairs */
164 static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName];
166 SECStatus
167 ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params)
169 SECOidData *oidData = NULL;
171 if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
172 ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
173 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
174 return SECFailure;
177 SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
179 * params->data needs to contain the ASN encoding of an object ID (OID)
180 * representing the named curve. The actual OID is in
181 * oidData->oid.data so we simply prepend 0x06 and OID length
183 params->data[0] = SEC_ASN1_OBJECT_ID;
184 params->data[1] = oidData->oid.len;
185 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
187 return SECSuccess;
190 static ECName
191 params2ecName(SECKEYECParams * params)
193 SECItem oid = { siBuffer, NULL, 0};
194 SECOidData *oidData = NULL;
195 ECName i;
198 * params->data needs to contain the ASN encoding of an object ID (OID)
199 * representing a named curve. Here, we strip away everything
200 * before the actual OID and use the OID to look up a named curve.
202 if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
203 oid.len = params->len - 2;
204 oid.data = params->data + 2;
205 if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
206 for (i = ec_noName + 1; i < ec_pastLastName; i++) {
207 if (ecName2OIDTag[i] == oidData->offset)
208 return i;
211 return ec_noName;
214 /* Caller must set hiLevel error code. */
215 static SECStatus
216 ssl3_ComputeECDHKeyHash(SECOidTag hashAlg,
217 SECItem ec_params, SECItem server_ecpoint,
218 SSL3Random *client_rand, SSL3Random *server_rand,
219 SSL3Hashes *hashes, PRBool bypassPKCS11)
221 PRUint8 * hashBuf;
222 PRUint8 * pBuf;
223 SECStatus rv = SECSuccess;
224 unsigned int bufLen;
226 * XXX For now, we only support named curves (the appropriate
227 * checks are made before this method is called) so ec_params
228 * takes up only two bytes. ECPoint needs to fit in 256 bytes
229 * (because the spec says the length must fit in one byte)
231 PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
233 bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
234 if (bufLen <= sizeof buf) {
235 hashBuf = buf;
236 } else {
237 hashBuf = PORT_Alloc(bufLen);
238 if (!hashBuf) {
239 return SECFailure;
243 memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
244 pBuf = hashBuf + SSL3_RANDOM_LENGTH;
245 memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
246 pBuf += SSL3_RANDOM_LENGTH;
247 memcpy(pBuf, ec_params.data, ec_params.len);
248 pBuf += ec_params.len;
249 pBuf[0] = (PRUint8)(server_ecpoint.len);
250 pBuf += 1;
251 memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
252 pBuf += server_ecpoint.len;
253 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
255 rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
256 bypassPKCS11);
258 PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
259 PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
260 hashes->u.s.md5, MD5_LENGTH));
261 PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
262 hashes->u.s.sha, SHA1_LENGTH));
264 if (hashBuf != buf)
265 PORT_Free(hashBuf);
266 return rv;
270 /* Called from ssl3_SendClientKeyExchange(). */
271 SECStatus
272 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
274 PK11SymKey * pms = NULL;
275 SECStatus rv = SECFailure;
276 PRBool isTLS, isTLS12;
277 CK_MECHANISM_TYPE target;
278 SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
279 SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
281 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
282 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
284 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
285 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
287 /* Generate ephemeral EC keypair */
288 if (svrPubKey->keyType != ecKey) {
289 PORT_SetError(SEC_ERROR_BAD_KEY);
290 goto loser;
292 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
293 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
294 &pubKey, ss->pkcs11PinArg);
295 if (!privKey || !pubKey) {
296 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
297 rv = SECFailure;
298 goto loser;
300 PRINT_BUF(50, (ss, "ECDH public value:",
301 pubKey->u.ec.publicValue.data,
302 pubKey->u.ec.publicValue.len));
304 if (isTLS12) {
305 target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
306 } else if (isTLS) {
307 target = CKM_TLS_MASTER_KEY_DERIVE_DH;
308 } else {
309 target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
312 /* Determine the PMS */
313 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
314 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
315 CKD_NULL, NULL, NULL);
317 if (pms == NULL) {
318 SSL3AlertDescription desc = illegal_parameter;
319 (void)SSL3_SendAlert(ss, alert_fatal, desc);
320 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
321 goto loser;
324 SECKEY_DestroyPrivateKey(privKey);
325 privKey = NULL;
327 rv = ssl3_InitPendingCipherSpec(ss, pms);
328 PK11_FreeSymKey(pms); pms = NULL;
330 if (rv != SECSuccess) {
331 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
332 goto loser;
335 rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
336 pubKey->u.ec.publicValue.len + 1);
337 if (rv != SECSuccess) {
338 goto loser; /* err set by ssl3_AppendHandshake* */
341 rv = ssl3_AppendHandshakeVariable(ss,
342 pubKey->u.ec.publicValue.data,
343 pubKey->u.ec.publicValue.len, 1);
344 SECKEY_DestroyPublicKey(pubKey);
345 pubKey = NULL;
347 if (rv != SECSuccess) {
348 goto loser; /* err set by ssl3_AppendHandshake* */
351 rv = SECSuccess;
353 loser:
354 if(pms) PK11_FreeSymKey(pms);
355 if(privKey) SECKEY_DestroyPrivateKey(privKey);
356 if(pubKey) SECKEY_DestroyPublicKey(pubKey);
357 return rv;
362 ** Called from ssl3_HandleClientKeyExchange()
364 SECStatus
365 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
366 PRUint32 length,
367 SECKEYPublicKey *srvrPubKey,
368 SECKEYPrivateKey *srvrPrivKey)
370 PK11SymKey * pms;
371 SECStatus rv;
372 SECKEYPublicKey clntPubKey;
373 CK_MECHANISM_TYPE target;
374 PRBool isTLS, isTLS12;
376 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
377 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
379 clntPubKey.keyType = ecKey;
380 clntPubKey.u.ec.DEREncodedParams.len =
381 srvrPubKey->u.ec.DEREncodedParams.len;
382 clntPubKey.u.ec.DEREncodedParams.data =
383 srvrPubKey->u.ec.DEREncodedParams.data;
385 rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
386 1, &b, &length);
387 if (rv != SECSuccess) {
388 SEND_ALERT
389 return SECFailure; /* XXX Who sets the error code?? */
392 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
393 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
395 if (isTLS12) {
396 target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
397 } else if (isTLS) {
398 target = CKM_TLS_MASTER_KEY_DERIVE_DH;
399 } else {
400 target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
403 /* Determine the PMS */
404 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
405 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
406 CKD_NULL, NULL, NULL);
408 if (pms == NULL) {
409 /* last gasp. */
410 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
411 return SECFailure;
414 rv = ssl3_InitPendingCipherSpec(ss, pms);
415 PK11_FreeSymKey(pms);
416 if (rv != SECSuccess) {
417 SEND_ALERT
418 return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
420 return SECSuccess;
423 ECName
424 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits)
426 int i;
428 for ( i = 0; bits2curve[i].curve != ec_noName; i++) {
429 if (bits2curve[i].bits < requiredECCbits)
430 continue;
431 if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) {
432 return bits2curve[i].curve;
435 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
436 return ec_noName;
439 /* find the "weakest link". Get strength of signature key and of sym key.
440 * choose curve for the weakest of those two.
442 ECName
443 ssl3_GetCurveNameForServerSocket(sslSocket *ss)
445 SECKEYPublicKey * svrPublicKey = NULL;
446 ECName ec_curve = ec_noName;
447 int signatureKeyStrength = 521;
448 int requiredECCbits = ss->sec.secretKeyBits * 2;
450 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) {
451 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh);
452 if (svrPublicKey)
453 ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams);
454 if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) {
455 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
456 return ec_noName;
458 signatureKeyStrength = curve2bits[ ec_curve ];
459 } else {
460 /* RSA is our signing cert */
461 int serverKeyStrengthInBits;
463 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
464 if (!svrPublicKey) {
465 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
466 return ec_noName;
469 /* currently strength in bytes */
470 serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len;
471 if (svrPublicKey->u.rsa.modulus.data[0] == 0) {
472 serverKeyStrengthInBits--;
474 /* convert to strength in bits */
475 serverKeyStrengthInBits *= BPB;
477 signatureKeyStrength =
478 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
480 if ( requiredECCbits > signatureKeyStrength )
481 requiredECCbits = signatureKeyStrength;
483 return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves,
484 requiredECCbits);
487 /* function to clear out the lists */
488 static SECStatus
489 ssl3_ShutdownECDHECurves(void *appData, void *nssData)
491 int i;
492 ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
494 for (i=0; i < ec_pastLastName; i++, keyPair++) {
495 if (keyPair->pair) {
496 ssl3_FreeKeyPair(keyPair->pair);
499 memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
500 return SECSuccess;
503 static PRStatus
504 ssl3_ECRegister(void)
506 SECStatus rv;
507 rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
508 if (rv != SECSuccess) {
509 gECDHEKeyPairs[ec_noName].error = PORT_GetError();
511 return (PRStatus)rv;
514 /* Create an ECDHE key pair for a given curve */
515 static SECStatus
516 ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve, ssl3KeyPair** keyPair)
518 SECKEYPrivateKey * privKey = NULL;
519 SECKEYPublicKey * pubKey = NULL;
520 SECKEYECParams ecParams = { siBuffer, NULL, 0 };
522 if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) {
523 return SECFailure;
525 privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
526 SECITEM_FreeItem(&ecParams, PR_FALSE);
528 if (!privKey || !pubKey || !(*keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
529 if (privKey) {
530 SECKEY_DestroyPrivateKey(privKey);
532 if (pubKey) {
533 SECKEY_DestroyPublicKey(pubKey);
535 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
536 return SECFailure;
539 return SECSuccess;
542 /* CallOnce function, called once for each named curve. */
543 static PRStatus
544 ssl3_CreateECDHEphemeralKeyPairOnce(void * arg)
546 ECName ec_curve = (ECName)arg;
547 ssl3KeyPair * keyPair = NULL;
549 PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
551 /* ok, no one has generated a global key for this curve yet, do so */
552 if (ssl3_CreateECDHEphemeralKeyPair(ec_curve, &keyPair) != SECSuccess) {
553 gECDHEKeyPairs[ec_curve].error = PORT_GetError();
554 return PR_FAILURE;
557 gECDHEKeyPairs[ec_curve].pair = keyPair;
558 return PR_SUCCESS;
562 * Creates the ephemeral public and private ECDH keys used by
563 * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
564 * For now, the elliptic curve is chosen to be the same
565 * strength as the signing certificate (ECC or RSA).
566 * We need an API to specify the curve. This won't be a real
567 * issue until we further develop server-side support for ECC
568 * cipher suites.
570 static SECStatus
571 ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve)
573 ssl3KeyPair * keyPair = NULL;
575 /* if there's no global key for this curve, make one. */
576 if (gECDHEKeyPairs[ec_curve].pair == NULL) {
577 PRStatus status;
579 status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister);
580 if (status != PR_SUCCESS) {
581 PORT_SetError(gECDHEKeyPairs[ec_noName].error);
582 return SECFailure;
584 status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once,
585 ssl3_CreateECDHEphemeralKeyPairOnce,
586 (void *)ec_curve);
587 if (status != PR_SUCCESS) {
588 PORT_SetError(gECDHEKeyPairs[ec_curve].error);
589 return SECFailure;
593 keyPair = gECDHEKeyPairs[ec_curve].pair;
594 PORT_Assert(keyPair != NULL);
595 if (!keyPair)
596 return SECFailure;
597 ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
599 return SECSuccess;
602 SECStatus
603 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
605 PLArenaPool * arena = NULL;
606 SECKEYPublicKey *peerKey = NULL;
607 PRBool isTLS, isTLS12;
608 SECStatus rv;
609 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
610 SSL3AlertDescription desc = illegal_parameter;
611 SSL3Hashes hashes;
612 SECItem signature = {siBuffer, NULL, 0};
614 SECItem ec_params = {siBuffer, NULL, 0};
615 SECItem ec_point = {siBuffer, NULL, 0};
616 unsigned char paramBuf[3]; /* only for curve_type == named_curve */
617 SSL3SignatureAndHashAlgorithm sigAndHash;
619 sigAndHash.hashAlg = SEC_OID_UNKNOWN;
621 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
622 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
624 /* XXX This works only for named curves, revisit this when
625 * we support generic curves.
627 ec_params.len = sizeof paramBuf;
628 ec_params.data = paramBuf;
629 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
630 if (rv != SECSuccess) {
631 goto loser; /* malformed. */
634 /* Fail if the curve is not a named curve */
635 if ((ec_params.data[0] != ec_type_named) ||
636 (ec_params.data[1] != 0) ||
637 !supportedCurve(ec_params.data[2])) {
638 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
639 desc = handshake_failure;
640 goto alert_loser;
643 rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
644 if (rv != SECSuccess) {
645 goto loser; /* malformed. */
647 /* Fail if the ec point uses compressed representation */
648 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
649 errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
650 desc = handshake_failure;
651 goto alert_loser;
654 if (isTLS12) {
655 rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
656 &sigAndHash);
657 if (rv != SECSuccess) {
658 goto loser; /* malformed or unsupported. */
660 rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
661 &sigAndHash, ss->sec.peerCert);
662 if (rv != SECSuccess) {
663 goto loser;
667 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
668 if (rv != SECSuccess) {
669 goto loser; /* malformed. */
672 if (length != 0) {
673 if (isTLS)
674 desc = decode_error;
675 goto alert_loser; /* malformed. */
678 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
679 ec_params.len));
680 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
682 /* failures after this point are not malformed handshakes. */
683 /* TLS: send decrypt_error if signature failed. */
684 desc = isTLS ? decrypt_error : handshake_failure;
687 * check to make sure the hash is signed by right guy
689 rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point,
690 &ss->ssl3.hs.client_random,
691 &ss->ssl3.hs.server_random,
692 &hashes, ss->opt.bypassPKCS11);
694 if (rv != SECSuccess) {
695 errCode =
696 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
697 goto alert_loser;
699 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
700 isTLS, ss->pkcs11PinArg);
701 if (rv != SECSuccess) {
702 errCode =
703 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
704 goto alert_loser;
707 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
708 if (arena == NULL) {
709 goto no_memory;
712 ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
713 if (peerKey == NULL) {
714 goto no_memory;
717 peerKey->arena = arena;
718 peerKey->keyType = ecKey;
720 /* set up EC parameters in peerKey */
721 if (ssl3_ECName2Params(arena, ec_params.data[2],
722 &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
723 /* we should never get here since we already
724 * checked that we are dealing with a supported curve
726 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
727 goto alert_loser;
730 /* copy publicValue in peerKey */
731 if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
733 PORT_FreeArena(arena, PR_FALSE);
734 goto no_memory;
736 peerKey->pkcs11Slot = NULL;
737 peerKey->pkcs11ID = CK_INVALID_HANDLE;
739 ss->sec.peerKey = peerKey;
740 ss->ssl3.hs.ws = wait_cert_request;
742 return SECSuccess;
744 alert_loser:
745 (void)SSL3_SendAlert(ss, alert_fatal, desc);
746 loser:
747 PORT_SetError( errCode );
748 return SECFailure;
750 no_memory: /* no-memory error has already been set. */
751 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
752 return SECFailure;
755 SECStatus
756 ssl3_SendECDHServerKeyExchange(
757 sslSocket *ss,
758 const SSL3SignatureAndHashAlgorithm *sigAndHash)
760 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
761 SECStatus rv = SECFailure;
762 int length;
763 PRBool isTLS, isTLS12;
764 SECItem signed_hash = {siBuffer, NULL, 0};
765 SSL3Hashes hashes;
767 SECKEYPublicKey * ecdhePub;
768 SECItem ec_params = {siBuffer, NULL, 0};
769 unsigned char paramBuf[3];
770 ECName curve;
771 SSL3KEAType certIndex;
773 /* Generate ephemeral ECDH key pair and send the public key */
774 curve = ssl3_GetCurveNameForServerSocket(ss);
775 if (curve == ec_noName) {
776 goto loser;
779 if (ss->opt.reuseServerECDHEKey) {
780 rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
781 } else {
782 rv = ssl3_CreateECDHEphemeralKeyPair(curve, &ss->ephemeralECDHKeyPair);
784 if (rv != SECSuccess) {
785 goto loser;
788 ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
789 PORT_Assert(ecdhePub != NULL);
790 if (!ecdhePub) {
791 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
792 return SECFailure;
795 ec_params.len = sizeof paramBuf;
796 ec_params.data = paramBuf;
797 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
798 if (curve != ec_noName) {
799 ec_params.data[0] = ec_type_named;
800 ec_params.data[1] = 0x00;
801 ec_params.data[2] = curve;
802 } else {
803 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
804 goto loser;
807 rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg,
808 ec_params,
809 ecdhePub->u.ec.publicValue,
810 &ss->ssl3.hs.client_random,
811 &ss->ssl3.hs.server_random,
812 &hashes, ss->opt.bypassPKCS11);
813 if (rv != SECSuccess) {
814 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
815 goto loser;
818 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
819 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
821 /* XXX SSLKEAType isn't really a good choice for
822 * indexing certificates but that's all we have
823 * for now.
825 if (kea_def->kea == kea_ecdhe_rsa)
826 certIndex = kt_rsa;
827 else /* kea_def->kea == kea_ecdhe_ecdsa */
828 certIndex = kt_ecdh;
830 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
831 &signed_hash, isTLS);
832 if (rv != SECSuccess) {
833 goto loser; /* ssl3_SignHashes has set err. */
835 if (signed_hash.data == NULL) {
836 /* how can this happen and rv == SECSuccess ?? */
837 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
838 goto loser;
841 length = ec_params.len +
842 1 + ecdhePub->u.ec.publicValue.len +
843 (isTLS12 ? 2 : 0) + 2 + signed_hash.len;
845 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
846 if (rv != SECSuccess) {
847 goto loser; /* err set by AppendHandshake. */
850 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
851 if (rv != SECSuccess) {
852 goto loser; /* err set by AppendHandshake. */
855 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
856 ecdhePub->u.ec.publicValue.len, 1);
857 if (rv != SECSuccess) {
858 goto loser; /* err set by AppendHandshake. */
861 if (isTLS12) {
862 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash);
863 if (rv != SECSuccess) {
864 goto loser; /* err set by AppendHandshake. */
868 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
869 signed_hash.len, 2);
870 if (rv != SECSuccess) {
871 goto loser; /* err set by AppendHandshake. */
874 PORT_Free(signed_hash.data);
875 return SECSuccess;
877 loser:
878 if (signed_hash.data != NULL)
879 PORT_Free(signed_hash.data);
880 return SECFailure;
883 /* Lists of ECC cipher suites for searching and disabling. */
885 static const ssl3CipherSuite ecdh_suites[] = {
886 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
887 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
888 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
889 TLS_ECDH_ECDSA_WITH_NULL_SHA,
890 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
891 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
892 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
893 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
894 TLS_ECDH_RSA_WITH_NULL_SHA,
895 TLS_ECDH_RSA_WITH_RC4_128_SHA,
896 0 /* end of list marker */
899 static const ssl3CipherSuite ecdh_ecdsa_suites[] = {
900 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
901 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
902 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
903 TLS_ECDH_ECDSA_WITH_NULL_SHA,
904 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
905 0 /* end of list marker */
908 static const ssl3CipherSuite ecdh_rsa_suites[] = {
909 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
910 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
911 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
912 TLS_ECDH_RSA_WITH_NULL_SHA,
913 TLS_ECDH_RSA_WITH_RC4_128_SHA,
914 0 /* end of list marker */
917 static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
918 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
919 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
920 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
921 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
922 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
923 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
924 TLS_ECDHE_ECDSA_WITH_NULL_SHA,
925 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
926 0 /* end of list marker */
929 static const ssl3CipherSuite ecdhe_rsa_suites[] = {
930 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
931 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
932 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
933 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
934 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
935 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
936 TLS_ECDHE_RSA_WITH_NULL_SHA,
937 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
938 0 /* end of list marker */
941 /* List of all ECC cipher suites */
942 static const ssl3CipherSuite ecSuites[] = {
943 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
944 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
945 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
946 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
947 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
948 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
949 TLS_ECDHE_ECDSA_WITH_NULL_SHA,
950 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
951 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
952 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
953 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
954 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
955 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
956 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
957 TLS_ECDHE_RSA_WITH_NULL_SHA,
958 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
959 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
960 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
961 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
962 TLS_ECDH_ECDSA_WITH_NULL_SHA,
963 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
964 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
965 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
966 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
967 TLS_ECDH_RSA_WITH_NULL_SHA,
968 TLS_ECDH_RSA_WITH_RC4_128_SHA,
969 0 /* end of list marker */
972 /* On this socket, Disable the ECC cipher suites in the argument's list */
973 SECStatus
974 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
976 if (!suite)
977 suite = ecSuites;
978 for (; *suite; ++suite) {
979 SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
981 PORT_Assert(rv == SECSuccess); /* else is coding error */
983 return SECSuccess;
986 /* Look at the server certs configured on this socket, and disable any
987 * ECC cipher suites that are not supported by those certs.
989 void
990 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
992 CERTCertificate * svrCert;
994 svrCert = ss->serverCerts[kt_rsa].serverCert;
995 if (!svrCert) {
996 ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
999 svrCert = ss->serverCerts[kt_ecdh].serverCert;
1000 if (!svrCert) {
1001 ssl3_DisableECCSuites(ss, ecdh_suites);
1002 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
1003 } else {
1004 SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
1006 switch (sigTag) {
1007 case SEC_OID_PKCS1_RSA_ENCRYPTION:
1008 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
1009 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
1010 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
1011 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
1012 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
1013 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
1014 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
1015 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
1016 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
1017 break;
1018 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
1019 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
1020 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
1021 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
1022 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
1023 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
1024 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
1025 ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
1026 break;
1027 default:
1028 ssl3_DisableECCSuites(ss, ecdh_suites);
1029 break;
1034 /* Ask: is ANY ECC cipher suite enabled on this socket? */
1035 /* Order(N^2). Yuk. Also, this ignores export policy. */
1036 PRBool
1037 ssl3_IsECCEnabled(sslSocket * ss)
1039 const ssl3CipherSuite * suite;
1040 PK11SlotInfo *slot;
1042 /* make sure we can do ECC */
1043 slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg);
1044 if (!slot) {
1045 return PR_FALSE;
1047 PK11_FreeSlot(slot);
1049 /* make sure an ECC cipher is enabled */
1050 for (suite = ecSuites; *suite; ++suite) {
1051 PRBool enabled = PR_FALSE;
1052 SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled);
1054 PORT_Assert(rv == SECSuccess); /* else is coding error */
1055 if (rv == SECSuccess && enabled)
1056 return PR_TRUE;
1058 return PR_FALSE;
1061 #define BE(n) 0, n
1063 /* Prefabricated TLS client hello extension, Elliptic Curves List,
1064 * offers only 3 curves, the Suite B curves, 23-25
1066 static const PRUint8 suiteBECList[12] = {
1067 BE(10), /* Extension type */
1068 BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */
1069 BE( 6), /* octets that follow ( 3 pairs) */
1070 BE(23), BE(24), BE(25)
1073 /* Prefabricated TLS client hello extension, Elliptic Curves List,
1074 * offers curves 1-25.
1076 static const PRUint8 tlsECList[56] = {
1077 BE(10), /* Extension type */
1078 BE(52), /* octets that follow (25 pairs + 1 length pair) */
1079 BE(50), /* octets that follow (25 pairs) */
1080 BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
1081 BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
1082 BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
1083 BE(24), BE(25)
1086 static const PRUint8 ecPtFmt[6] = {
1087 BE(11), /* Extension type */
1088 BE( 2), /* octets that follow */
1089 1, /* octets that follow */
1090 0 /* uncompressed type only */
1093 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be
1094 * called before this function. It looks to see if we have a token which
1095 * is capable of doing smaller than SuiteB curves. If the token can, we
1096 * presume the token can do the whole SSL suite of curves. If it can't we
1097 * presume the token that allowed ECC to be enabled can only do suite B
1098 * curves. */
1099 static PRBool
1100 ssl3_SuiteBOnly(sslSocket *ss)
1102 #if 0
1103 /* See if we can support small curves (like 163). If not, assume we can
1104 * only support Suite-B curves (P-256, P-384, P-521). */
1105 PK11SlotInfo *slot =
1106 PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163,
1107 ss ? ss->pkcs11PinArg : NULL);
1109 if (!slot) {
1110 /* nope, presume we can only do suite B */
1111 return PR_TRUE;
1113 /* we can, presume we can do all curves */
1114 PK11_FreeSlot(slot);
1115 return PR_FALSE;
1116 #else
1117 return PR_TRUE;
1118 #endif
1121 /* Send our "canned" (precompiled) Supported Elliptic Curves extension,
1122 * which says that we support all TLS-defined named curves.
1124 PRInt32
1125 ssl3_SendSupportedCurvesXtn(
1126 sslSocket * ss,
1127 PRBool append,
1128 PRUint32 maxBytes)
1130 PRInt32 ecListSize = 0;
1131 const PRUint8 *ecList = NULL;
1133 if (!ss || !ssl3_IsECCEnabled(ss))
1134 return 0;
1136 if (ssl3_SuiteBOnly(ss)) {
1137 ecListSize = sizeof suiteBECList;
1138 ecList = suiteBECList;
1139 } else {
1140 ecListSize = sizeof tlsECList;
1141 ecList = tlsECList;
1144 if (append && maxBytes >= ecListSize) {
1145 SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize);
1146 if (rv != SECSuccess)
1147 return -1;
1148 if (!ss->sec.isServer) {
1149 TLSExtensionData *xtnData = &ss->xtnData;
1150 xtnData->advertised[xtnData->numAdvertised++] =
1151 ssl_elliptic_curves_xtn;
1154 return ecListSize;
1157 PRUint32
1158 ssl3_GetSupportedECCurveMask(sslSocket *ss)
1160 if (ssl3_SuiteBOnly(ss)) {
1161 return SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
1163 return SSL3_ALL_SUPPORTED_CURVES_MASK;
1166 /* Send our "canned" (precompiled) Supported Point Formats extension,
1167 * which says that we only support uncompressed points.
1169 PRInt32
1170 ssl3_SendSupportedPointFormatsXtn(
1171 sslSocket * ss,
1172 PRBool append,
1173 PRUint32 maxBytes)
1175 if (!ss || !ssl3_IsECCEnabled(ss))
1176 return 0;
1177 if (append && maxBytes >= (sizeof ecPtFmt)) {
1178 SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt));
1179 if (rv != SECSuccess)
1180 return -1;
1181 if (!ss->sec.isServer) {
1182 TLSExtensionData *xtnData = &ss->xtnData;
1183 xtnData->advertised[xtnData->numAdvertised++] =
1184 ssl_ec_point_formats_xtn;
1187 return (sizeof ecPtFmt);
1190 /* Just make sure that the remote client supports uncompressed points,
1191 * Since that is all we support. Disable ECC cipher suites if it doesn't.
1193 SECStatus
1194 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type,
1195 SECItem *data)
1197 int i;
1199 if (data->len < 2 || data->len > 255 || !data->data ||
1200 data->len != (unsigned int)data->data[0] + 1) {
1201 /* malformed */
1202 goto loser;
1204 for (i = data->len; --i > 0; ) {
1205 if (data->data[i] == 0) {
1206 /* indicate that we should send a reply */
1207 SECStatus rv;
1208 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
1209 &ssl3_SendSupportedPointFormatsXtn);
1210 return rv;
1213 loser:
1214 /* evil client doesn't support uncompressed */
1215 ssl3_DisableECCSuites(ss, ecSuites);
1216 return SECFailure;
1220 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
1221 (ss->serverCerts[type].serverKeyPair ? \
1222 ss->serverCerts[type].serverKeyPair->pubKey : NULL)
1224 /* Extract the TLS curve name for the public key in our EC server cert. */
1225 ECName ssl3_GetSvrCertCurveName(sslSocket *ss)
1227 SECKEYPublicKey *srvPublicKey;
1228 ECName ec_curve = ec_noName;
1230 srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
1231 if (srvPublicKey) {
1232 ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
1234 return ec_curve;
1237 /* Ensure that the curve in our server cert is one of the ones suppored
1238 * by the remote client, and disable all ECC cipher suites if not.
1240 SECStatus
1241 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
1243 PRInt32 list_len;
1244 PRUint32 peerCurves = 0;
1245 PRUint32 mutualCurves = 0;
1246 PRUint16 svrCertCurveName;
1248 if (!data->data || data->len < 4 || data->len > 65535)
1249 goto loser;
1250 /* get the length of elliptic_curve_list */
1251 list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1252 if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
1253 /* malformed */
1254 goto loser;
1256 /* build bit vector of peer's supported curve names */
1257 while (data->len) {
1258 PRInt32 curve_name =
1259 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1260 if (curve_name > ec_noName && curve_name < ec_pastLastName) {
1261 peerCurves |= (1U << curve_name);
1264 /* What curves do we support in common? */
1265 mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
1266 if (!mutualCurves) { /* no mutually supported EC Curves */
1267 goto loser;
1270 /* if our ECC cert doesn't use one of these supported curves,
1271 * disable ECC cipher suites that require an ECC cert.
1273 svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
1274 if (svrCertCurveName != ec_noName &&
1275 (mutualCurves & (1U << svrCertCurveName)) != 0) {
1276 return SECSuccess;
1278 /* Our EC cert doesn't contain a mutually supported curve.
1279 * Disable all ECC cipher suites that require an EC cert
1281 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
1282 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
1283 return SECFailure;
1285 loser:
1286 /* no common curve supported */
1287 ssl3_DisableECCSuites(ss, ecSuites);
1288 return SECFailure;
1291 #endif /* NSS_DISABLE_ECC */