1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 /* ECC code moved here from ssl3con.c */
14 #include "cryptohi.h" /* for DSAU_ stuff */
34 /* This is a bodge to allow this code to be compiled against older NSS headers
35 * that don't contain the TLS 1.2 changes. */
36 #ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
37 #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
40 #ifndef NSS_DISABLE_ECC
43 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
44 (x)->pValue=(v); (x)->ulValueLen = (l);
47 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
48 (ss->serverCerts[type].serverKeyPair ? \
49 ss->serverCerts[type].serverKeyPair->pubKey : NULL)
51 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \
52 ((curveName > ec_noName) && \
53 (curveName < ec_pastLastName) && \
54 ((1UL << curveName) & curvemsk) != 0)
58 static SECStatus
ssl3_CreateECDHEphemeralKeys(sslSocket
*ss
, ECName ec_curve
);
60 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
62 /* Table containing OID tags for elliptic curves named in the
65 static const SECOidTag ecName2OIDTag
[] = {
67 SEC_OID_SECG_EC_SECT163K1
, /* 1 */
68 SEC_OID_SECG_EC_SECT163R1
, /* 2 */
69 SEC_OID_SECG_EC_SECT163R2
, /* 3 */
70 SEC_OID_SECG_EC_SECT193R1
, /* 4 */
71 SEC_OID_SECG_EC_SECT193R2
, /* 5 */
72 SEC_OID_SECG_EC_SECT233K1
, /* 6 */
73 SEC_OID_SECG_EC_SECT233R1
, /* 7 */
74 SEC_OID_SECG_EC_SECT239K1
, /* 8 */
75 SEC_OID_SECG_EC_SECT283K1
, /* 9 */
76 SEC_OID_SECG_EC_SECT283R1
, /* 10 */
77 SEC_OID_SECG_EC_SECT409K1
, /* 11 */
78 SEC_OID_SECG_EC_SECT409R1
, /* 12 */
79 SEC_OID_SECG_EC_SECT571K1
, /* 13 */
80 SEC_OID_SECG_EC_SECT571R1
, /* 14 */
81 SEC_OID_SECG_EC_SECP160K1
, /* 15 */
82 SEC_OID_SECG_EC_SECP160R1
, /* 16 */
83 SEC_OID_SECG_EC_SECP160R2
, /* 17 */
84 SEC_OID_SECG_EC_SECP192K1
, /* 18 */
85 SEC_OID_SECG_EC_SECP192R1
, /* 19 */
86 SEC_OID_SECG_EC_SECP224K1
, /* 20 */
87 SEC_OID_SECG_EC_SECP224R1
, /* 21 */
88 SEC_OID_SECG_EC_SECP256K1
, /* 22 */
89 SEC_OID_SECG_EC_SECP256R1
, /* 23 */
90 SEC_OID_SECG_EC_SECP384R1
, /* 24 */
91 SEC_OID_SECG_EC_SECP521R1
, /* 25 */
94 static const PRUint16 curve2bits
[] = {
95 0, /* ec_noName = 0, */
96 163, /* ec_sect163k1 = 1, */
97 163, /* ec_sect163r1 = 2, */
98 163, /* ec_sect163r2 = 3, */
99 193, /* ec_sect193r1 = 4, */
100 193, /* ec_sect193r2 = 5, */
101 233, /* ec_sect233k1 = 6, */
102 233, /* ec_sect233r1 = 7, */
103 239, /* ec_sect239k1 = 8, */
104 283, /* ec_sect283k1 = 9, */
105 283, /* ec_sect283r1 = 10, */
106 409, /* ec_sect409k1 = 11, */
107 409, /* ec_sect409r1 = 12, */
108 571, /* ec_sect571k1 = 13, */
109 571, /* ec_sect571r1 = 14, */
110 160, /* ec_secp160k1 = 15, */
111 160, /* ec_secp160r1 = 16, */
112 160, /* ec_secp160r2 = 17, */
113 192, /* ec_secp192k1 = 18, */
114 192, /* ec_secp192r1 = 19, */
115 224, /* ec_secp224k1 = 20, */
116 224, /* ec_secp224r1 = 21, */
117 256, /* ec_secp256k1 = 22, */
118 256, /* ec_secp256r1 = 23, */
119 384, /* ec_secp384r1 = 24, */
120 521, /* ec_secp521r1 = 25, */
121 65535 /* ec_pastLastName */
124 typedef struct Bits2CurveStr
{
129 static const Bits2Curve bits2curve
[] = {
130 { 192, ec_secp192r1
/* = 19, fast */ },
131 { 160, ec_secp160r2
/* = 17, fast */ },
132 { 160, ec_secp160k1
/* = 15, */ },
133 { 160, ec_secp160r1
/* = 16, */ },
134 { 163, ec_sect163k1
/* = 1, */ },
135 { 163, ec_sect163r1
/* = 2, */ },
136 { 163, ec_sect163r2
/* = 3, */ },
137 { 192, ec_secp192k1
/* = 18, */ },
138 { 193, ec_sect193r1
/* = 4, */ },
139 { 193, ec_sect193r2
/* = 5, */ },
140 { 224, ec_secp224r1
/* = 21, fast */ },
141 { 224, ec_secp224k1
/* = 20, */ },
142 { 233, ec_sect233k1
/* = 6, */ },
143 { 233, ec_sect233r1
/* = 7, */ },
144 { 239, ec_sect239k1
/* = 8, */ },
145 { 256, ec_secp256r1
/* = 23, fast */ },
146 { 256, ec_secp256k1
/* = 22, */ },
147 { 283, ec_sect283k1
/* = 9, */ },
148 { 283, ec_sect283r1
/* = 10, */ },
149 { 384, ec_secp384r1
/* = 24, fast */ },
150 { 409, ec_sect409k1
/* = 11, */ },
151 { 409, ec_sect409r1
/* = 12, */ },
152 { 521, ec_secp521r1
/* = 25, fast */ },
153 { 571, ec_sect571k1
/* = 13, */ },
154 { 571, ec_sect571r1
/* = 14, */ },
158 typedef struct ECDHEKeyPairStr
{
160 int error
; /* error code of the call-once function */
164 /* arrays of ECDHE KeyPairs */
165 static ECDHEKeyPair gECDHEKeyPairs
[ec_pastLastName
];
168 ssl3_ECName2Params(PLArenaPool
* arena
, ECName curve
, SECKEYECParams
* params
)
170 SECOidData
*oidData
= NULL
;
172 if ((curve
<= ec_noName
) || (curve
>= ec_pastLastName
) ||
173 ((oidData
= SECOID_FindOIDByTag(ecName2OIDTag
[curve
])) == NULL
)) {
174 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE
);
178 SECITEM_AllocItem(arena
, params
, (2 + oidData
->oid
.len
));
180 * params->data needs to contain the ASN encoding of an object ID (OID)
181 * representing the named curve. The actual OID is in
182 * oidData->oid.data so we simply prepend 0x06 and OID length
184 params
->data
[0] = SEC_ASN1_OBJECT_ID
;
185 params
->data
[1] = oidData
->oid
.len
;
186 memcpy(params
->data
+ 2, oidData
->oid
.data
, oidData
->oid
.len
);
192 params2ecName(SECKEYECParams
* params
)
194 SECItem oid
= { siBuffer
, NULL
, 0};
195 SECOidData
*oidData
= NULL
;
199 * params->data needs to contain the ASN encoding of an object ID (OID)
200 * representing a named curve. Here, we strip away everything
201 * before the actual OID and use the OID to look up a named curve.
203 if (params
->data
[0] != SEC_ASN1_OBJECT_ID
) return ec_noName
;
204 oid
.len
= params
->len
- 2;
205 oid
.data
= params
->data
+ 2;
206 if ((oidData
= SECOID_FindOID(&oid
)) == NULL
) return ec_noName
;
207 for (i
= ec_noName
+ 1; i
< ec_pastLastName
; i
++) {
208 if (ecName2OIDTag
[i
] == oidData
->offset
)
215 /* Caller must set hiLevel error code. */
217 ssl3_ComputeECDHKeyHash(SECOidTag hashAlg
,
218 SECItem ec_params
, SECItem server_ecpoint
,
219 SSL3Random
*client_rand
, SSL3Random
*server_rand
,
220 SSL3Hashes
*hashes
, PRBool bypassPKCS11
)
224 SECStatus rv
= SECSuccess
;
227 * XXX For now, we only support named curves (the appropriate
228 * checks are made before this method is called) so ec_params
229 * takes up only two bytes. ECPoint needs to fit in 256 bytes
230 * (because the spec says the length must fit in one byte)
232 PRUint8 buf
[2*SSL3_RANDOM_LENGTH
+ 2 + 1 + 256];
234 bufLen
= 2*SSL3_RANDOM_LENGTH
+ ec_params
.len
+ 1 + server_ecpoint
.len
;
235 if (bufLen
<= sizeof buf
) {
238 hashBuf
= PORT_Alloc(bufLen
);
244 memcpy(hashBuf
, client_rand
, SSL3_RANDOM_LENGTH
);
245 pBuf
= hashBuf
+ SSL3_RANDOM_LENGTH
;
246 memcpy(pBuf
, server_rand
, SSL3_RANDOM_LENGTH
);
247 pBuf
+= SSL3_RANDOM_LENGTH
;
248 memcpy(pBuf
, ec_params
.data
, ec_params
.len
);
249 pBuf
+= ec_params
.len
;
250 pBuf
[0] = (PRUint8
)(server_ecpoint
.len
);
252 memcpy(pBuf
, server_ecpoint
.data
, server_ecpoint
.len
);
253 pBuf
+= server_ecpoint
.len
;
254 PORT_Assert((unsigned int)(pBuf
- hashBuf
) == bufLen
);
256 rv
= ssl3_ComputeCommonKeyHash(hashAlg
, hashBuf
, bufLen
, hashes
,
259 PRINT_BUF(95, (NULL
, "ECDHkey hash: ", hashBuf
, bufLen
));
260 PRINT_BUF(95, (NULL
, "ECDHkey hash: MD5 result",
261 hashes
->u
.s
.md5
, MD5_LENGTH
));
262 PRINT_BUF(95, (NULL
, "ECDHkey hash: SHA1 result",
263 hashes
->u
.s
.sha
, SHA1_LENGTH
));
271 /* Called from ssl3_SendClientKeyExchange(). */
273 ssl3_SendECDHClientKeyExchange(sslSocket
* ss
, SECKEYPublicKey
* svrPubKey
)
275 PK11SymKey
* pms
= NULL
;
276 SECStatus rv
= SECFailure
;
277 PRBool isTLS
, isTLS12
;
278 CK_MECHANISM_TYPE target
;
279 SECKEYPublicKey
*pubKey
= NULL
; /* Ephemeral ECDH key */
280 SECKEYPrivateKey
*privKey
= NULL
; /* Ephemeral ECDH key */
282 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveSSL3HandshakeLock(ss
) );
283 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveXmitBufLock(ss
));
285 isTLS
= (PRBool
)(ss
->ssl3
.pwSpec
->version
> SSL_LIBRARY_VERSION_3_0
);
286 isTLS12
= (PRBool
)(ss
->ssl3
.pwSpec
->version
>= SSL_LIBRARY_VERSION_TLS_1_2
);
288 /* Generate ephemeral EC keypair */
289 if (svrPubKey
->keyType
!= ecKey
) {
290 PORT_SetError(SEC_ERROR_BAD_KEY
);
293 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
294 privKey
= SECKEY_CreateECPrivateKey(&svrPubKey
->u
.ec
.DEREncodedParams
,
295 &pubKey
, ss
->pkcs11PinArg
);
296 if (!privKey
|| !pubKey
) {
297 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL
);
301 PRINT_BUF(50, (ss
, "ECDH public value:",
302 pubKey
->u
.ec
.publicValue
.data
,
303 pubKey
->u
.ec
.publicValue
.len
));
306 target
= CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
;
308 target
= CKM_TLS_MASTER_KEY_DERIVE_DH
;
310 target
= CKM_SSL3_MASTER_KEY_DERIVE_DH
;
313 /* Determine the PMS */
314 pms
= PK11_PubDeriveWithKDF(privKey
, svrPubKey
, PR_FALSE
, NULL
, NULL
,
315 CKM_ECDH1_DERIVE
, target
, CKA_DERIVE
, 0,
316 CKD_NULL
, NULL
, NULL
);
319 SSL3AlertDescription desc
= illegal_parameter
;
320 (void)SSL3_SendAlert(ss
, alert_fatal
, desc
);
321 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE
);
325 SECKEY_DestroyPrivateKey(privKey
);
328 rv
= ssl3_InitPendingCipherSpec(ss
, pms
);
329 PK11_FreeSymKey(pms
); pms
= NULL
;
331 if (rv
!= SECSuccess
) {
332 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE
);
336 rv
= ssl3_AppendHandshakeHeader(ss
, client_key_exchange
,
337 pubKey
->u
.ec
.publicValue
.len
+ 1);
338 if (rv
!= SECSuccess
) {
339 goto loser
; /* err set by ssl3_AppendHandshake* */
342 rv
= ssl3_AppendHandshakeVariable(ss
,
343 pubKey
->u
.ec
.publicValue
.data
,
344 pubKey
->u
.ec
.publicValue
.len
, 1);
345 SECKEY_DestroyPublicKey(pubKey
);
348 if (rv
!= SECSuccess
) {
349 goto loser
; /* err set by ssl3_AppendHandshake* */
355 if(pms
) PK11_FreeSymKey(pms
);
356 if(privKey
) SECKEY_DestroyPrivateKey(privKey
);
357 if(pubKey
) SECKEY_DestroyPublicKey(pubKey
);
363 ** Called from ssl3_HandleClientKeyExchange()
366 ssl3_HandleECDHClientKeyExchange(sslSocket
*ss
, SSL3Opaque
*b
,
368 SECKEYPublicKey
*srvrPubKey
,
369 SECKEYPrivateKey
*srvrPrivKey
)
373 SECKEYPublicKey clntPubKey
;
374 CK_MECHANISM_TYPE target
;
375 PRBool isTLS
, isTLS12
;
377 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveRecvBufLock(ss
) );
378 PORT_Assert( ss
->opt
.noLocks
|| ssl_HaveSSL3HandshakeLock(ss
) );
380 clntPubKey
.keyType
= ecKey
;
381 clntPubKey
.u
.ec
.DEREncodedParams
.len
=
382 srvrPubKey
->u
.ec
.DEREncodedParams
.len
;
383 clntPubKey
.u
.ec
.DEREncodedParams
.data
=
384 srvrPubKey
->u
.ec
.DEREncodedParams
.data
;
386 rv
= ssl3_ConsumeHandshakeVariable(ss
, &clntPubKey
.u
.ec
.publicValue
,
388 if (rv
!= SECSuccess
) {
390 return SECFailure
; /* XXX Who sets the error code?? */
393 isTLS
= (PRBool
)(ss
->ssl3
.prSpec
->version
> SSL_LIBRARY_VERSION_3_0
);
394 isTLS12
= (PRBool
)(ss
->ssl3
.prSpec
->version
>= SSL_LIBRARY_VERSION_TLS_1_2
);
397 target
= CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
;
399 target
= CKM_TLS_MASTER_KEY_DERIVE_DH
;
401 target
= CKM_SSL3_MASTER_KEY_DERIVE_DH
;
404 /* Determine the PMS */
405 pms
= PK11_PubDeriveWithKDF(srvrPrivKey
, &clntPubKey
, PR_FALSE
, NULL
, NULL
,
406 CKM_ECDH1_DERIVE
, target
, CKA_DERIVE
, 0,
407 CKD_NULL
, NULL
, NULL
);
411 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE
);
415 rv
= ssl3_InitPendingCipherSpec(ss
, pms
);
416 PK11_FreeSymKey(pms
);
417 if (rv
!= SECSuccess
) {
419 return SECFailure
; /* error code set by ssl3_InitPendingCipherSpec */
425 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk
, int requiredECCbits
)
429 for ( i
= 0; bits2curve
[i
].curve
!= ec_noName
; i
++) {
430 if (bits2curve
[i
].bits
< requiredECCbits
)
432 if (SSL_IS_CURVE_NEGOTIATED(curvemsk
, bits2curve
[i
].curve
)) {
433 return bits2curve
[i
].curve
;
436 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP
);
440 /* find the "weakest link". Get strength of signature key and of sym key.
441 * choose curve for the weakest of those two.
444 ssl3_GetCurveNameForServerSocket(sslSocket
*ss
)
446 SECKEYPublicKey
* svrPublicKey
= NULL
;
447 ECName ec_curve
= ec_noName
;
448 int signatureKeyStrength
= 521;
449 int requiredECCbits
= ss
->sec
.secretKeyBits
* 2;
451 if (ss
->ssl3
.hs
.kea_def
->kea
== kea_ecdhe_ecdsa
) {
452 svrPublicKey
= SSL_GET_SERVER_PUBLIC_KEY(ss
, kt_ecdh
);
454 ec_curve
= params2ecName(&svrPublicKey
->u
.ec
.DEREncodedParams
);
455 if (!SSL_IS_CURVE_NEGOTIATED(ss
->ssl3
.hs
.negotiatedECCurves
, ec_curve
)) {
456 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP
);
459 signatureKeyStrength
= curve2bits
[ ec_curve
];
461 /* RSA is our signing cert */
462 int serverKeyStrengthInBits
;
464 svrPublicKey
= SSL_GET_SERVER_PUBLIC_KEY(ss
, kt_rsa
);
466 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP
);
470 /* currently strength in bytes */
471 serverKeyStrengthInBits
= svrPublicKey
->u
.rsa
.modulus
.len
;
472 if (svrPublicKey
->u
.rsa
.modulus
.data
[0] == 0) {
473 serverKeyStrengthInBits
--;
475 /* convert to strength in bits */
476 serverKeyStrengthInBits
*= BPB
;
478 signatureKeyStrength
=
479 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits
);
481 if ( requiredECCbits
> signatureKeyStrength
)
482 requiredECCbits
= signatureKeyStrength
;
484 return ssl3_GetCurveWithECKeyStrength(ss
->ssl3
.hs
.negotiatedECCurves
,
488 /* function to clear out the lists */
490 ssl3_ShutdownECDHECurves(void *appData
, void *nssData
)
493 ECDHEKeyPair
*keyPair
= &gECDHEKeyPairs
[0];
495 for (i
=0; i
< ec_pastLastName
; i
++, keyPair
++) {
497 ssl3_FreeKeyPair(keyPair
->pair
);
500 memset(gECDHEKeyPairs
, 0, sizeof gECDHEKeyPairs
);
505 ssl3_ECRegister(void)
508 rv
= NSS_RegisterShutdown(ssl3_ShutdownECDHECurves
, gECDHEKeyPairs
);
509 if (rv
!= SECSuccess
) {
510 gECDHEKeyPairs
[ec_noName
].error
= PORT_GetError();
515 /* Create an ECDHE key pair for a given curve */
517 ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve
, ssl3KeyPair
** keyPair
)
519 SECKEYPrivateKey
* privKey
= NULL
;
520 SECKEYPublicKey
* pubKey
= NULL
;
521 SECKEYECParams ecParams
= { siBuffer
, NULL
, 0 };
523 if (ssl3_ECName2Params(NULL
, ec_curve
, &ecParams
) != SECSuccess
) {
526 privKey
= SECKEY_CreateECPrivateKey(&ecParams
, &pubKey
, NULL
);
527 SECITEM_FreeItem(&ecParams
, PR_FALSE
);
529 if (!privKey
|| !pubKey
|| !(*keyPair
= ssl3_NewKeyPair(privKey
, pubKey
))) {
531 SECKEY_DestroyPrivateKey(privKey
);
534 SECKEY_DestroyPublicKey(pubKey
);
536 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL
);
543 /* CallOnce function, called once for each named curve. */
545 ssl3_CreateECDHEphemeralKeyPairOnce(void * arg
)
547 ECName ec_curve
= (ECName
)arg
;
548 ssl3KeyPair
* keyPair
= NULL
;
550 PORT_Assert(gECDHEKeyPairs
[ec_curve
].pair
== NULL
);
552 /* ok, no one has generated a global key for this curve yet, do so */
553 if (ssl3_CreateECDHEphemeralKeyPair(ec_curve
, &keyPair
) != SECSuccess
) {
554 gECDHEKeyPairs
[ec_curve
].error
= PORT_GetError();
558 gECDHEKeyPairs
[ec_curve
].pair
= keyPair
;
563 * Creates the ephemeral public and private ECDH keys used by
564 * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
565 * For now, the elliptic curve is chosen to be the same
566 * strength as the signing certificate (ECC or RSA).
567 * We need an API to specify the curve. This won't be a real
568 * issue until we further develop server-side support for ECC
572 ssl3_CreateECDHEphemeralKeys(sslSocket
*ss
, ECName ec_curve
)
574 ssl3KeyPair
* keyPair
= NULL
;
576 /* if there's no global key for this curve, make one. */
577 if (gECDHEKeyPairs
[ec_curve
].pair
== NULL
) {
580 status
= PR_CallOnce(&gECDHEKeyPairs
[ec_noName
].once
, ssl3_ECRegister
);
581 if (status
!= PR_SUCCESS
) {
582 PORT_SetError(gECDHEKeyPairs
[ec_noName
].error
);
585 status
= PR_CallOnceWithArg(&gECDHEKeyPairs
[ec_curve
].once
,
586 ssl3_CreateECDHEphemeralKeyPairOnce
,
588 if (status
!= PR_SUCCESS
) {
589 PORT_SetError(gECDHEKeyPairs
[ec_curve
].error
);
594 keyPair
= gECDHEKeyPairs
[ec_curve
].pair
;
595 PORT_Assert(keyPair
!= NULL
);
598 ss
->ephemeralECDHKeyPair
= ssl3_GetKeyPairRef(keyPair
);
604 ssl3_HandleECDHServerKeyExchange(sslSocket
*ss
, SSL3Opaque
*b
, PRUint32 length
)
606 PLArenaPool
* arena
= NULL
;
607 SECKEYPublicKey
*peerKey
= NULL
;
608 PRBool isTLS
, isTLS12
;
610 int errCode
= SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH
;
611 SSL3AlertDescription desc
= illegal_parameter
;
613 SECItem signature
= {siBuffer
, NULL
, 0};
615 SECItem ec_params
= {siBuffer
, NULL
, 0};
616 SECItem ec_point
= {siBuffer
, NULL
, 0};
617 unsigned char paramBuf
[3]; /* only for curve_type == named_curve */
618 SSL3SignatureAndHashAlgorithm sigAndHash
;
620 sigAndHash
.hashAlg
= SEC_OID_UNKNOWN
;
622 isTLS
= (PRBool
)(ss
->ssl3
.prSpec
->version
> SSL_LIBRARY_VERSION_3_0
);
623 isTLS12
= (PRBool
)(ss
->ssl3
.prSpec
->version
>= SSL_LIBRARY_VERSION_TLS_1_2
);
625 /* XXX This works only for named curves, revisit this when
626 * we support generic curves.
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. */
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
;
644 rv
= ssl3_ConsumeHandshakeVariable(ss
, &ec_point
, 1, &b
, &length
);
645 if (rv
!= SECSuccess
) {
646 goto loser
; /* malformed. */
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
;
656 rv
= ssl3_ConsumeSignatureAndHashAlgorithm(ss
, &b
, &length
,
658 if (rv
!= SECSuccess
) {
659 goto loser
; /* malformed or unsupported. */
661 rv
= ssl3_CheckSignatureAndHashAlgorithmConsistency(
662 &sigAndHash
, ss
->sec
.peerCert
);
663 if (rv
!= SECSuccess
) {
668 rv
= ssl3_ConsumeHandshakeVariable(ss
, &signature
, 2, &b
, &length
);
669 if (rv
!= SECSuccess
) {
670 goto loser
; /* malformed. */
676 goto alert_loser
; /* malformed. */
679 PRINT_BUF(60, (NULL
, "Server EC params", ec_params
.data
,
681 PRINT_BUF(60, (NULL
, "Server EC point", ec_point
.data
, ec_point
.len
));
683 /* failures after this point are not malformed handshakes. */
684 /* TLS: send decrypt_error if signature failed. */
685 desc
= isTLS
? decrypt_error
: handshake_failure
;
688 * check to make sure the hash is signed by right guy
690 rv
= ssl3_ComputeECDHKeyHash(sigAndHash
.hashAlg
, ec_params
, ec_point
,
691 &ss
->ssl3
.hs
.client_random
,
692 &ss
->ssl3
.hs
.server_random
,
693 &hashes
, ss
->opt
.bypassPKCS11
);
695 if (rv
!= SECSuccess
) {
697 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
700 rv
= ssl3_VerifySignedHashes(&hashes
, ss
->sec
.peerCert
, &signature
,
701 isTLS
, ss
->pkcs11PinArg
);
702 if (rv
!= SECSuccess
) {
704 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
708 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
713 ss
->sec
.peerKey
= peerKey
= PORT_ArenaZNew(arena
, SECKEYPublicKey
);
714 if (peerKey
== NULL
) {
718 peerKey
->arena
= arena
;
719 peerKey
->keyType
= ecKey
;
721 /* set up EC parameters in peerKey */
722 if (ssl3_ECName2Params(arena
, ec_params
.data
[2],
723 &peerKey
->u
.ec
.DEREncodedParams
) != SECSuccess
) {
724 /* we should never get here since we already
725 * checked that we are dealing with a supported curve
727 errCode
= SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE
;
731 /* copy publicValue in peerKey */
732 if (SECITEM_CopyItem(arena
, &peerKey
->u
.ec
.publicValue
, &ec_point
))
734 PORT_FreeArena(arena
, PR_FALSE
);
737 peerKey
->pkcs11Slot
= NULL
;
738 peerKey
->pkcs11ID
= CK_INVALID_HANDLE
;
740 ss
->sec
.peerKey
= peerKey
;
741 ss
->ssl3
.hs
.ws
= wait_cert_request
;
746 (void)SSL3_SendAlert(ss
, alert_fatal
, desc
);
748 PORT_SetError( errCode
);
751 no_memory
: /* no-memory error has already been set. */
752 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
757 ssl3_SendECDHServerKeyExchange(
759 const SSL3SignatureAndHashAlgorithm
*sigAndHash
)
761 const ssl3KEADef
* kea_def
= ss
->ssl3
.hs
.kea_def
;
762 SECStatus rv
= SECFailure
;
764 PRBool isTLS
, isTLS12
;
765 SECItem signed_hash
= {siBuffer
, NULL
, 0};
768 SECKEYPublicKey
* ecdhePub
;
769 SECItem ec_params
= {siBuffer
, NULL
, 0};
770 unsigned char paramBuf
[3];
772 SSL3KEAType certIndex
;
774 /* Generate ephemeral ECDH key pair and send the public key */
775 curve
= ssl3_GetCurveNameForServerSocket(ss
);
776 if (curve
== ec_noName
) {
780 if (ss
->opt
.reuseServerECDHEKey
) {
781 rv
= ssl3_CreateECDHEphemeralKeys(ss
, curve
);
783 rv
= ssl3_CreateECDHEphemeralKeyPair(curve
, &ss
->ephemeralECDHKeyPair
);
785 if (rv
!= SECSuccess
) {
789 ecdhePub
= ss
->ephemeralECDHKeyPair
->pubKey
;
790 PORT_Assert(ecdhePub
!= NULL
);
792 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
796 ec_params
.len
= sizeof paramBuf
;
797 ec_params
.data
= paramBuf
;
798 curve
= params2ecName(&ecdhePub
->u
.ec
.DEREncodedParams
);
799 if (curve
!= ec_noName
) {
800 ec_params
.data
[0] = ec_type_named
;
801 ec_params
.data
[1] = 0x00;
802 ec_params
.data
[2] = curve
;
804 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE
);
808 rv
= ssl3_ComputeECDHKeyHash(sigAndHash
->hashAlg
,
810 ecdhePub
->u
.ec
.publicValue
,
811 &ss
->ssl3
.hs
.client_random
,
812 &ss
->ssl3
.hs
.server_random
,
813 &hashes
, ss
->opt
.bypassPKCS11
);
814 if (rv
!= SECSuccess
) {
815 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
819 isTLS
= (PRBool
)(ss
->ssl3
.pwSpec
->version
> SSL_LIBRARY_VERSION_3_0
);
820 isTLS12
= (PRBool
)(ss
->ssl3
.pwSpec
->version
>= SSL_LIBRARY_VERSION_TLS_1_2
);
822 /* XXX SSLKEAType isn't really a good choice for
823 * indexing certificates but that's all we have
826 if (kea_def
->kea
== kea_ecdhe_rsa
)
828 else /* kea_def->kea == kea_ecdhe_ecdsa */
831 rv
= ssl3_SignHashes(&hashes
, ss
->serverCerts
[certIndex
].SERVERKEY
,
832 &signed_hash
, isTLS
);
833 if (rv
!= SECSuccess
) {
834 goto loser
; /* ssl3_SignHashes has set err. */
836 if (signed_hash
.data
== NULL
) {
837 /* how can this happen and rv == SECSuccess ?? */
838 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
842 length
= ec_params
.len
+
843 1 + ecdhePub
->u
.ec
.publicValue
.len
+
844 (isTLS12
? 2 : 0) + 2 + signed_hash
.len
;
846 rv
= ssl3_AppendHandshakeHeader(ss
, server_key_exchange
, length
);
847 if (rv
!= SECSuccess
) {
848 goto loser
; /* err set by AppendHandshake. */
851 rv
= ssl3_AppendHandshake(ss
, ec_params
.data
, ec_params
.len
);
852 if (rv
!= SECSuccess
) {
853 goto loser
; /* err set by AppendHandshake. */
856 rv
= ssl3_AppendHandshakeVariable(ss
, ecdhePub
->u
.ec
.publicValue
.data
,
857 ecdhePub
->u
.ec
.publicValue
.len
, 1);
858 if (rv
!= SECSuccess
) {
859 goto loser
; /* err set by AppendHandshake. */
863 rv
= ssl3_AppendSignatureAndHashAlgorithm(ss
, sigAndHash
);
864 if (rv
!= SECSuccess
) {
865 goto loser
; /* err set by AppendHandshake. */
869 rv
= ssl3_AppendHandshakeVariable(ss
, signed_hash
.data
,
871 if (rv
!= SECSuccess
) {
872 goto loser
; /* err set by AppendHandshake. */
875 PORT_Free(signed_hash
.data
);
879 if (signed_hash
.data
!= NULL
)
880 PORT_Free(signed_hash
.data
);
884 /* Lists of ECC cipher suites for searching and disabling. */
886 static const ssl3CipherSuite ecdh_suites
[] = {
887 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
888 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
889 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
890 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
891 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
892 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
893 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
894 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
895 TLS_ECDH_RSA_WITH_NULL_SHA
,
896 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
897 0 /* end of list marker */
900 static const ssl3CipherSuite ecdh_ecdsa_suites
[] = {
901 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
902 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
903 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
904 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
905 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
906 0 /* end of list marker */
909 static const ssl3CipherSuite ecdh_rsa_suites
[] = {
910 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
911 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
912 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
913 TLS_ECDH_RSA_WITH_NULL_SHA
,
914 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
915 0 /* end of list marker */
918 static const ssl3CipherSuite ecdhe_ecdsa_suites
[] = {
919 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
,
920 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
,
921 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
,
922 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
,
923 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
,
924 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
,
925 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
926 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
927 0 /* end of list marker */
930 static const ssl3CipherSuite ecdhe_rsa_suites
[] = {
931 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
932 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,
933 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
,
934 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
935 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
,
936 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
,
937 TLS_ECDHE_RSA_WITH_NULL_SHA
,
938 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
939 0 /* end of list marker */
942 /* List of all ECC cipher suites */
943 static const ssl3CipherSuite ecSuites
[] = {
944 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
,
945 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
,
946 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
,
947 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
,
948 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
,
949 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
,
950 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
951 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
952 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
953 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,
954 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
,
955 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
956 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
,
957 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
,
958 TLS_ECDHE_RSA_WITH_NULL_SHA
,
959 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
960 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
961 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
962 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
963 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
964 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
965 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
966 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
967 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
968 TLS_ECDH_RSA_WITH_NULL_SHA
,
969 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
970 0 /* end of list marker */
973 /* On this socket, Disable the ECC cipher suites in the argument's list */
975 ssl3_DisableECCSuites(sslSocket
* ss
, const ssl3CipherSuite
* suite
)
979 for (; *suite
; ++suite
) {
980 SECStatus rv
= ssl3_CipherPrefSet(ss
, *suite
, PR_FALSE
);
982 PORT_Assert(rv
== SECSuccess
); /* else is coding error */
987 /* Look at the server certs configured on this socket, and disable any
988 * ECC cipher suites that are not supported by those certs.
991 ssl3_FilterECCipherSuitesByServerCerts(sslSocket
* ss
)
993 CERTCertificate
* svrCert
;
995 svrCert
= ss
->serverCerts
[kt_rsa
].serverCert
;
997 ssl3_DisableECCSuites(ss
, ecdhe_rsa_suites
);
1000 svrCert
= ss
->serverCerts
[kt_ecdh
].serverCert
;
1002 ssl3_DisableECCSuites(ss
, ecdh_suites
);
1003 ssl3_DisableECCSuites(ss
, ecdhe_ecdsa_suites
);
1005 SECOidTag sigTag
= SECOID_GetAlgorithmTag(&svrCert
->signature
);
1008 case SEC_OID_PKCS1_RSA_ENCRYPTION
:
1009 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION
:
1010 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION
:
1011 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION
:
1012 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
:
1013 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION
:
1014 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
:
1015 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION
:
1016 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION
:
1017 ssl3_DisableECCSuites(ss
, ecdh_ecdsa_suites
);
1019 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE
:
1020 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE
:
1021 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE
:
1022 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE
:
1023 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE
:
1024 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST
:
1025 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST
:
1026 ssl3_DisableECCSuites(ss
, ecdh_rsa_suites
);
1029 ssl3_DisableECCSuites(ss
, ecdh_suites
);
1035 /* Ask: is ANY ECC cipher suite enabled on this socket? */
1036 /* Order(N^2). Yuk. Also, this ignores export policy. */
1038 ssl3_IsECCEnabled(sslSocket
* ss
)
1040 const ssl3CipherSuite
* suite
;
1043 /* make sure we can do ECC */
1044 slot
= PK11_GetBestSlot(CKM_ECDH1_DERIVE
, ss
->pkcs11PinArg
);
1048 PK11_FreeSlot(slot
);
1050 /* make sure an ECC cipher is enabled */
1051 for (suite
= ecSuites
; *suite
; ++suite
) {
1052 PRBool enabled
= PR_FALSE
;
1053 SECStatus rv
= ssl3_CipherPrefGet(ss
, *suite
, &enabled
);
1055 PORT_Assert(rv
== SECSuccess
); /* else is coding error */
1056 if (rv
== SECSuccess
&& enabled
)
1064 /* Prefabricated TLS client hello extension, Elliptic Curves List,
1065 * offers only 3 curves, the Suite B curves, 23-25
1067 static const PRUint8 suiteBECList
[12] = {
1068 BE(10), /* Extension type */
1069 BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */
1070 BE( 6), /* octets that follow ( 3 pairs) */
1071 BE(23), BE(24), BE(25)
1074 /* Prefabricated TLS client hello extension, Elliptic Curves List,
1075 * offers curves 1-25.
1077 static const PRUint8 tlsECList
[56] = {
1078 BE(10), /* Extension type */
1079 BE(52), /* octets that follow (25 pairs + 1 length pair) */
1080 BE(50), /* octets that follow (25 pairs) */
1081 BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
1082 BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
1083 BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
1087 static const PRUint8 ecPtFmt
[6] = {
1088 BE(11), /* Extension type */
1089 BE( 2), /* octets that follow */
1090 1, /* octets that follow */
1091 0 /* uncompressed type only */
1094 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be
1095 * called before this function. It looks to see if we have a token which
1096 * is capable of doing smaller than SuiteB curves. If the token can, we
1097 * presume the token can do the whole SSL suite of curves. If it can't we
1098 * presume the token that allowed ECC to be enabled can only do suite B
1101 ssl3_SuiteBOnly(sslSocket
*ss
)
1104 /* See if we can support small curves (like 163). If not, assume we can
1105 * only support Suite-B curves (P-256, P-384, P-521). */
1106 PK11SlotInfo
*slot
=
1107 PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE
, 0, 163,
1108 ss
? ss
->pkcs11PinArg
: NULL
);
1111 /* nope, presume we can only do suite B */
1114 /* we can, presume we can do all curves */
1115 PK11_FreeSlot(slot
);
1122 /* Send our "canned" (precompiled) Supported Elliptic Curves extension,
1123 * which says that we support all TLS-defined named curves.
1126 ssl3_SendSupportedCurvesXtn(
1131 PRInt32 ecListSize
= 0;
1132 const PRUint8
*ecList
= NULL
;
1134 if (!ss
|| !ssl3_IsECCEnabled(ss
))
1137 if (ssl3_SuiteBOnly(ss
)) {
1138 ecListSize
= sizeof suiteBECList
;
1139 ecList
= suiteBECList
;
1141 ecListSize
= sizeof tlsECList
;
1145 if (append
&& maxBytes
>= ecListSize
) {
1146 SECStatus rv
= ssl3_AppendHandshake(ss
, ecList
, ecListSize
);
1147 if (rv
!= SECSuccess
)
1149 if (!ss
->sec
.isServer
) {
1150 TLSExtensionData
*xtnData
= &ss
->xtnData
;
1151 xtnData
->advertised
[xtnData
->numAdvertised
++] =
1152 ssl_elliptic_curves_xtn
;
1159 ssl3_GetSupportedECCurveMask(sslSocket
*ss
)
1161 if (ssl3_SuiteBOnly(ss
)) {
1162 return SSL3_SUITE_B_SUPPORTED_CURVES_MASK
;
1164 return SSL3_ALL_SUPPORTED_CURVES_MASK
;
1167 /* Send our "canned" (precompiled) Supported Point Formats extension,
1168 * which says that we only support uncompressed points.
1171 ssl3_SendSupportedPointFormatsXtn(
1176 if (!ss
|| !ssl3_IsECCEnabled(ss
))
1178 if (append
&& maxBytes
>= (sizeof ecPtFmt
)) {
1179 SECStatus rv
= ssl3_AppendHandshake(ss
, ecPtFmt
, (sizeof ecPtFmt
));
1180 if (rv
!= SECSuccess
)
1182 if (!ss
->sec
.isServer
) {
1183 TLSExtensionData
*xtnData
= &ss
->xtnData
;
1184 xtnData
->advertised
[xtnData
->numAdvertised
++] =
1185 ssl_ec_point_formats_xtn
;
1188 return (sizeof ecPtFmt
);
1191 /* Just make sure that the remote client supports uncompressed points,
1192 * Since that is all we support. Disable ECC cipher suites if it doesn't.
1195 ssl3_HandleSupportedPointFormatsXtn(sslSocket
*ss
, PRUint16 ex_type
,
1200 if (data
->len
< 2 || data
->len
> 255 || !data
->data
||
1201 data
->len
!= (unsigned int)data
->data
[0] + 1) {
1202 return ssl3_DecodeError(ss
);
1204 for (i
= data
->len
; --i
> 0; ) {
1205 if (data
->data
[i
] == 0) {
1206 /* indicate that we should send a reply */
1208 rv
= ssl3_RegisterServerHelloExtensionSender(ss
, ex_type
,
1209 &ssl3_SendSupportedPointFormatsXtn
);
1214 /* evil client doesn't support uncompressed */
1215 ssl3_DisableECCSuites(ss
, ecSuites
);
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
);
1232 ec_curve
= params2ecName(&srvPublicKey
->u
.ec
.DEREncodedParams
);
1237 /* Ensure that the curve in our server cert is one of the ones supported
1238 * by the remote client, and disable all ECC cipher suites if not.
1241 ssl3_HandleSupportedCurvesXtn(sslSocket
*ss
, PRUint16 ex_type
, SECItem
*data
)
1244 PRUint32 peerCurves
= 0;
1245 PRUint32 mutualCurves
= 0;
1246 PRUint16 svrCertCurveName
;
1248 if (!data
->data
|| data
->len
< 4) {
1249 (void)ssl3_DecodeError(ss
);
1253 /* get the length of elliptic_curve_list */
1254 list_len
= ssl3_ConsumeHandshakeNumber(ss
, 2, &data
->data
, &data
->len
);
1255 if (list_len
< 0 || data
->len
!= list_len
|| (data
->len
% 2) != 0) {
1256 (void)ssl3_DecodeError(ss
);
1259 /* build bit vector of peer's supported curve names */
1261 PRInt32 curve_name
=
1262 ssl3_ConsumeHandshakeNumber(ss
, 2, &data
->data
, &data
->len
);
1263 if (curve_name
< 0) {
1264 return SECFailure
; /* fatal alert already sent */
1266 if (curve_name
> ec_noName
&& curve_name
< ec_pastLastName
) {
1267 peerCurves
|= (1U << curve_name
);
1270 /* What curves do we support in common? */
1271 mutualCurves
= ss
->ssl3
.hs
.negotiatedECCurves
&= peerCurves
;
1272 if (!mutualCurves
) {
1273 /* no mutually supported EC Curves, disable ECC */
1274 ssl3_DisableECCSuites(ss
, ecSuites
);
1278 /* if our ECC cert doesn't use one of these supported curves,
1279 * disable ECC cipher suites that require an ECC cert.
1281 svrCertCurveName
= ssl3_GetSvrCertCurveName(ss
);
1282 if (svrCertCurveName
!= ec_noName
&&
1283 (mutualCurves
& (1U << svrCertCurveName
)) != 0) {
1286 /* Our EC cert doesn't contain a mutually supported curve.
1287 * Disable all ECC cipher suites that require an EC cert
1289 ssl3_DisableECCSuites(ss
, ecdh_ecdsa_suites
);
1290 ssl3_DisableECCSuites(ss
, ecdhe_ecdsa_suites
);
1294 #endif /* NSS_DISABLE_ECC */