| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * SSL3 Protocol | |
| 3 * | |
| 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/. */ | |
| 7 | |
| 8 /* ECC code moved here from ssl3con.c */ | |
| 9 | |
| 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" | |
| 17 | |
| 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" | |
| 27 | |
| 28 #include "pk11func.h" | |
| 29 #include "secmod.h" | |
| 30 | |
| 31 #include <stdio.h> | |
| 32 | |
| 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 | |
| 38 | |
| 39 #ifdef NSS_ENABLE_ECC | |
| 40 | |
| 41 #ifndef PK11_SETATTRS | |
| 42 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ | |
| 43 (x)->pValue=(v); (x)->ulValueLen = (l); | |
| 44 #endif | |
| 45 | |
| 46 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \ | |
| 47 (ss->serverCerts[type].serverKeyPair ? \ | |
| 48 ss->serverCerts[type].serverKeyPair->pubKey : NULL) | |
| 49 | |
| 50 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \ | |
| 51 ((curveName > ec_noName) && \ | |
| 52 (curveName < ec_pastLastName) && \ | |
| 53 ((1UL << curveName) & curvemsk) != 0) | |
| 54 | |
| 55 | |
| 56 | |
| 57 static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve); | |
| 58 | |
| 59 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName)) | |
| 60 | |
| 61 /* Table containing OID tags for elliptic curves named in the | |
| 62 * ECC-TLS IETF draft. | |
| 63 */ | |
| 64 static const SECOidTag ecName2OIDTag[] = { | |
| 65 0, | |
| 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 */ | |
| 91 }; | |
| 92 | |
| 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 */ | |
| 121 }; | |
| 122 | |
| 123 typedef struct Bits2CurveStr { | |
| 124 PRUint16 bits; | |
| 125 ECName curve; | |
| 126 } Bits2Curve; | |
| 127 | |
| 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 } | |
| 155 }; | |
| 156 | |
| 157 typedef struct ECDHEKeyPairStr { | |
| 158 ssl3KeyPair * pair; | |
| 159 int error; /* error code of the call-once function */ | |
| 160 PRCallOnceType once; | |
| 161 } ECDHEKeyPair; | |
| 162 | |
| 163 /* arrays of ECDHE KeyPairs */ | |
| 164 static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; | |
| 165 | |
| 166 SECStatus | |
| 167 ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params) | |
| 168 { | |
| 169 SECOidData *oidData = NULL; | |
| 170 | |
| 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; | |
| 175 } | |
| 176 | |
| 177 SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)); | |
| 178 /* | |
| 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 | |
| 182 */ | |
| 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); | |
| 186 | |
| 187 return SECSuccess; | |
| 188 } | |
| 189 | |
| 190 static ECName | |
| 191 params2ecName(SECKEYECParams * params) | |
| 192 { | |
| 193 SECItem oid = { siBuffer, NULL, 0}; | |
| 194 SECOidData *oidData = NULL; | |
| 195 ECName i; | |
| 196 | |
| 197 /* | |
| 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. | |
| 201 */ | |
| 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; | |
| 209 } | |
| 210 | |
| 211 return ec_noName; | |
| 212 } | |
| 213 | |
| 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) | |
| 220 { | |
| 221 PRUint8 * hashBuf; | |
| 222 PRUint8 * pBuf; | |
| 223 SECStatus rv = SECSuccess; | |
| 224 unsigned int bufLen; | |
| 225 /* | |
| 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) | |
| 230 */ | |
| 231 PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256]; | |
| 232 | |
| 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; | |
| 240 } | |
| 241 } | |
| 242 | |
| 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); | |
| 254 | |
| 255 rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, | |
| 256 bypassPKCS11); | |
| 257 | |
| 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)); | |
| 263 | |
| 264 if (hashBuf != buf) | |
| 265 PORT_Free(hashBuf); | |
| 266 return rv; | |
| 267 } | |
| 268 | |
| 269 | |
| 270 /* Called from ssl3_SendClientKeyExchange(). */ | |
| 271 SECStatus | |
| 272 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) | |
| 273 { | |
| 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 */ | |
| 280 | |
| 281 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | |
| 282 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | |
| 283 | |
| 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); | |
| 286 | |
| 287 /* Generate ephemeral EC keypair */ | |
| 288 if (svrPubKey->keyType != ecKey) { | |
| 289 PORT_SetError(SEC_ERROR_BAD_KEY); | |
| 290 goto loser; | |
| 291 } | |
| 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; | |
| 299 } | |
| 300 PRINT_BUF(50, (ss, "ECDH public value:", | |
| 301 pubKey->u.ec.publicValue.data, | |
| 302 pubKey->u.ec.publicValue.len)); | |
| 303 | |
| 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; | |
| 310 } | |
| 311 | |
| 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); | |
| 316 | |
| 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; | |
| 322 } | |
| 323 | |
| 324 SECKEY_DestroyPrivateKey(privKey); | |
| 325 privKey = NULL; | |
| 326 | |
| 327 rv = ssl3_InitPendingCipherSpec(ss, pms); | |
| 328 PK11_FreeSymKey(pms); pms = NULL; | |
| 329 | |
| 330 if (rv != SECSuccess) { | |
| 331 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | |
| 332 goto loser; | |
| 333 } | |
| 334 | |
| 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* */ | |
| 339 } | |
| 340 | |
| 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; | |
| 346 | |
| 347 if (rv != SECSuccess) { | |
| 348 goto loser; /* err set by ssl3_AppendHandshake* */ | |
| 349 } | |
| 350 | |
| 351 rv = SECSuccess; | |
| 352 | |
| 353 loser: | |
| 354 if(pms) PK11_FreeSymKey(pms); | |
| 355 if(privKey) SECKEY_DestroyPrivateKey(privKey); | |
| 356 if(pubKey) SECKEY_DestroyPublicKey(pubKey); | |
| 357 return rv; | |
| 358 } | |
| 359 | |
| 360 | |
| 361 /* | |
| 362 ** Called from ssl3_HandleClientKeyExchange() | |
| 363 */ | |
| 364 SECStatus | |
| 365 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, | |
| 366 PRUint32 length, | |
| 367 SECKEYPublicKey *srvrPubKey, | |
| 368 SECKEYPrivateKey *srvrPrivKey) | |
| 369 { | |
| 370 PK11SymKey * pms; | |
| 371 SECStatus rv; | |
| 372 SECKEYPublicKey clntPubKey; | |
| 373 CK_MECHANISM_TYPE target; | |
| 374 PRBool isTLS, isTLS12; | |
| 375 | |
| 376 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | |
| 377 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | |
| 378 | |
| 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; | |
| 384 | |
| 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?? */ | |
| 390 } | |
| 391 | |
| 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); | |
| 394 | |
| 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; | |
| 401 } | |
| 402 | |
| 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); | |
| 407 | |
| 408 if (pms == NULL) { | |
| 409 /* last gasp. */ | |
| 410 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | |
| 411 return SECFailure; | |
| 412 } | |
| 413 | |
| 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 */ | |
| 419 } | |
| 420 return SECSuccess; | |
| 421 } | |
| 422 | |
| 423 ECName | |
| 424 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits) | |
| 425 { | |
| 426 int i; | |
| 427 | |
| 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; | |
| 433 } | |
| 434 } | |
| 435 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | |
| 436 return ec_noName; | |
| 437 } | |
| 438 | |
| 439 /* find the "weakest link". Get strength of signature key and of sym key. | |
| 440 * choose curve for the weakest of those two. | |
| 441 */ | |
| 442 ECName | |
| 443 ssl3_GetCurveNameForServerSocket(sslSocket *ss) | |
| 444 { | |
| 445 SECKEYPublicKey * svrPublicKey = NULL; | |
| 446 ECName ec_curve = ec_noName; | |
| 447 int signatureKeyStrength = 521; | |
| 448 int requiredECCbits = ss->sec.secretKeyBits * 2; | |
| 449 | |
| 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; | |
| 457 } | |
| 458 signatureKeyStrength = curve2bits[ ec_curve ]; | |
| 459 } else { | |
| 460 /* RSA is our signing cert */ | |
| 461 int serverKeyStrengthInBits; | |
| 462 | |
| 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; | |
| 467 } | |
| 468 | |
| 469 /* currently strength in bytes */ | |
| 470 serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len; | |
| 471 if (svrPublicKey->u.rsa.modulus.data[0] == 0) { | |
| 472 serverKeyStrengthInBits--; | |
| 473 } | |
| 474 /* convert to strength in bits */ | |
| 475 serverKeyStrengthInBits *= BPB; | |
| 476 | |
| 477 signatureKeyStrength = | |
| 478 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); | |
| 479 } | |
| 480 if ( requiredECCbits > signatureKeyStrength ) | |
| 481 requiredECCbits = signatureKeyStrength; | |
| 482 | |
| 483 return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves, | |
| 484 requiredECCbits); | |
| 485 } | |
| 486 | |
| 487 /* function to clear out the lists */ | |
| 488 static SECStatus | |
| 489 ssl3_ShutdownECDHECurves(void *appData, void *nssData) | |
| 490 { | |
| 491 int i; | |
| 492 ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0]; | |
| 493 | |
| 494 for (i=0; i < ec_pastLastName; i++, keyPair++) { | |
| 495 if (keyPair->pair) { | |
| 496 ssl3_FreeKeyPair(keyPair->pair); | |
| 497 } | |
| 498 } | |
| 499 memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs); | |
| 500 return SECSuccess; | |
| 501 } | |
| 502 | |
| 503 static PRStatus | |
| 504 ssl3_ECRegister(void) | |
| 505 { | |
| 506 SECStatus rv; | |
| 507 rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs); | |
| 508 if (rv != SECSuccess) { | |
| 509 gECDHEKeyPairs[ec_noName].error = PORT_GetError(); | |
| 510 } | |
| 511 return (PRStatus)rv; | |
| 512 } | |
| 513 | |
| 514 /* CallOnce function, called once for each named curve. */ | |
| 515 static PRStatus | |
| 516 ssl3_CreateECDHEphemeralKeyPair(void * arg) | |
| 517 { | |
| 518 SECKEYPrivateKey * privKey = NULL; | |
| 519 SECKEYPublicKey * pubKey = NULL; | |
| 520 ssl3KeyPair * keyPair = NULL; | |
| 521 ECName ec_curve = (ECName)arg; | |
| 522 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; | |
| 523 | |
| 524 PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); | |
| 525 | |
| 526 /* ok, no one has generated a global key for this curve yet, do so */ | |
| 527 if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) { | |
| 528 gECDHEKeyPairs[ec_curve].error = PORT_GetError(); | |
| 529 return PR_FAILURE; | |
| 530 } | |
| 531 | |
| 532 privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); | |
| 533 SECITEM_FreeItem(&ecParams, PR_FALSE); | |
| 534 | |
| 535 if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) { | |
| 536 if (privKey) { | |
| 537 SECKEY_DestroyPrivateKey(privKey); | |
| 538 } | |
| 539 if (pubKey) { | |
| 540 SECKEY_DestroyPublicKey(pubKey); | |
| 541 } | |
| 542 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); | |
| 543 gECDHEKeyPairs[ec_curve].error = PORT_GetError(); | |
| 544 return PR_FAILURE; | |
| 545 } | |
| 546 | |
| 547 gECDHEKeyPairs[ec_curve].pair = keyPair; | |
| 548 return PR_SUCCESS; | |
| 549 } | |
| 550 | |
| 551 /* | |
| 552 * Creates the ephemeral public and private ECDH keys used by | |
| 553 * server in ECDHE_RSA and ECDHE_ECDSA handshakes. | |
| 554 * For now, the elliptic curve is chosen to be the same | |
| 555 * strength as the signing certificate (ECC or RSA). | |
| 556 * We need an API to specify the curve. This won't be a real | |
| 557 * issue until we further develop server-side support for ECC | |
| 558 * cipher suites. | |
| 559 */ | |
| 560 static SECStatus | |
| 561 ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) | |
| 562 { | |
| 563 ssl3KeyPair * keyPair = NULL; | |
| 564 | |
| 565 /* if there's no global key for this curve, make one. */ | |
| 566 if (gECDHEKeyPairs[ec_curve].pair == NULL) { | |
| 567 PRStatus status; | |
| 568 | |
| 569 status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister); | |
| 570 if (status != PR_SUCCESS) { | |
| 571 PORT_SetError(gECDHEKeyPairs[ec_noName].error); | |
| 572 return SECFailure; | |
| 573 } | |
| 574 status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, | |
| 575 ssl3_CreateECDHEphemeralKeyPair, | |
| 576 (void *)ec_curve); | |
| 577 if (status != PR_SUCCESS) { | |
| 578 PORT_SetError(gECDHEKeyPairs[ec_curve].error); | |
| 579 return SECFailure; | |
| 580 } | |
| 581 } | |
| 582 | |
| 583 keyPair = gECDHEKeyPairs[ec_curve].pair; | |
| 584 PORT_Assert(keyPair != NULL); | |
| 585 if (!keyPair) | |
| 586 return SECFailure; | |
| 587 ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair); | |
| 588 | |
| 589 return SECSuccess; | |
| 590 } | |
| 591 | |
| 592 SECStatus | |
| 593 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) | |
| 594 { | |
| 595 PLArenaPool * arena = NULL; | |
| 596 SECKEYPublicKey *peerKey = NULL; | |
| 597 PRBool isTLS, isTLS12; | |
| 598 SECStatus rv; | |
| 599 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH; | |
| 600 SSL3AlertDescription desc = illegal_parameter; | |
| 601 SSL3Hashes hashes; | |
| 602 SECItem signature = {siBuffer, NULL, 0}; | |
| 603 | |
| 604 SECItem ec_params = {siBuffer, NULL, 0}; | |
| 605 SECItem ec_point = {siBuffer, NULL, 0}; | |
| 606 unsigned char paramBuf[3]; /* only for curve_type == named_curve */ | |
| 607 SSL3SignatureAndHashAlgorithm sigAndHash; | |
| 608 | |
| 609 sigAndHash.hashAlg = SEC_OID_UNKNOWN; | |
| 610 | |
| 611 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | |
| 612 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | |
| 613 | |
| 614 /* XXX This works only for named curves, revisit this when | |
| 615 * we support generic curves. | |
| 616 */ | |
| 617 ec_params.len = sizeof paramBuf; | |
| 618 ec_params.data = paramBuf; | |
| 619 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); | |
| 620 if (rv != SECSuccess) { | |
| 621 goto loser; /* malformed. */ | |
| 622 } | |
| 623 | |
| 624 /* Fail if the curve is not a named curve */ | |
| 625 if ((ec_params.data[0] != ec_type_named) || | |
| 626 (ec_params.data[1] != 0) || | |
| 627 !supportedCurve(ec_params.data[2])) { | |
| 628 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; | |
| 629 desc = handshake_failure; | |
| 630 goto alert_loser; | |
| 631 } | |
| 632 | |
| 633 rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length); | |
| 634 if (rv != SECSuccess) { | |
| 635 goto loser; /* malformed. */ | |
| 636 } | |
| 637 /* Fail if the ec point uses compressed representation */ | |
| 638 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) { | |
| 639 errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM; | |
| 640 desc = handshake_failure; | |
| 641 goto alert_loser; | |
| 642 } | |
| 643 | |
| 644 if (isTLS12) { | |
| 645 rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, | |
| 646 &sigAndHash); | |
| 647 if (rv != SECSuccess) { | |
| 648 goto loser; /* malformed or unsupported. */ | |
| 649 } | |
| 650 rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( | |
| 651 &sigAndHash, ss->sec.peerCert); | |
| 652 if (rv != SECSuccess) { | |
| 653 goto loser; | |
| 654 } | |
| 655 } | |
| 656 | |
| 657 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); | |
| 658 if (rv != SECSuccess) { | |
| 659 goto loser; /* malformed. */ | |
| 660 } | |
| 661 | |
| 662 if (length != 0) { | |
| 663 if (isTLS) | |
| 664 desc = decode_error; | |
| 665 goto alert_loser; /* malformed. */ | |
| 666 } | |
| 667 | |
| 668 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, | |
| 669 ec_params.len)); | |
| 670 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len)); | |
| 671 | |
| 672 /* failures after this point are not malformed handshakes. */ | |
| 673 /* TLS: send decrypt_error if signature failed. */ | |
| 674 desc = isTLS ? decrypt_error : handshake_failure; | |
| 675 | |
| 676 /* | |
| 677 * check to make sure the hash is signed by right guy | |
| 678 */ | |
| 679 rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point, | |
| 680 &ss->ssl3.hs.client_random, | |
| 681 &ss->ssl3.hs.server_random, | |
| 682 &hashes, ss->opt.bypassPKCS11); | |
| 683 | |
| 684 if (rv != SECSuccess) { | |
| 685 errCode = | |
| 686 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | |
| 687 goto alert_loser; | |
| 688 } | |
| 689 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, | |
| 690 isTLS, ss->pkcs11PinArg); | |
| 691 if (rv != SECSuccess) { | |
| 692 errCode = | |
| 693 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | |
| 694 goto alert_loser; | |
| 695 } | |
| 696 | |
| 697 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
| 698 if (arena == NULL) { | |
| 699 goto no_memory; | |
| 700 } | |
| 701 | |
| 702 ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); | |
| 703 if (peerKey == NULL) { | |
| 704 goto no_memory; | |
| 705 } | |
| 706 | |
| 707 peerKey->arena = arena; | |
| 708 peerKey->keyType = ecKey; | |
| 709 | |
| 710 /* set up EC parameters in peerKey */ | |
| 711 if (ssl3_ECName2Params(arena, ec_params.data[2], | |
| 712 &peerKey->u.ec.DEREncodedParams) != SECSuccess) { | |
| 713 /* we should never get here since we already | |
| 714 * checked that we are dealing with a supported curve | |
| 715 */ | |
| 716 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; | |
| 717 goto alert_loser; | |
| 718 } | |
| 719 | |
| 720 /* copy publicValue in peerKey */ | |
| 721 if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point)) | |
| 722 { | |
| 723 PORT_FreeArena(arena, PR_FALSE); | |
| 724 goto no_memory; | |
| 725 } | |
| 726 peerKey->pkcs11Slot = NULL; | |
| 727 peerKey->pkcs11ID = CK_INVALID_HANDLE; | |
| 728 | |
| 729 ss->sec.peerKey = peerKey; | |
| 730 ss->ssl3.hs.ws = wait_cert_request; | |
| 731 | |
| 732 return SECSuccess; | |
| 733 | |
| 734 alert_loser: | |
| 735 (void)SSL3_SendAlert(ss, alert_fatal, desc); | |
| 736 loser: | |
| 737 PORT_SetError( errCode ); | |
| 738 return SECFailure; | |
| 739 | |
| 740 no_memory: /* no-memory error has already been set. */ | |
| 741 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | |
| 742 return SECFailure; | |
| 743 } | |
| 744 | |
| 745 SECStatus | |
| 746 ssl3_SendECDHServerKeyExchange( | |
| 747 sslSocket *ss, | |
| 748 const SSL3SignatureAndHashAlgorithm *sigAndHash) | |
| 749 { | |
| 750 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; | |
| 751 SECStatus rv = SECFailure; | |
| 752 int length; | |
| 753 PRBool isTLS, isTLS12; | |
| 754 SECItem signed_hash = {siBuffer, NULL, 0}; | |
| 755 SSL3Hashes hashes; | |
| 756 | |
| 757 SECKEYPublicKey * ecdhePub; | |
| 758 SECItem ec_params = {siBuffer, NULL, 0}; | |
| 759 unsigned char paramBuf[3]; | |
| 760 ECName curve; | |
| 761 SSL3KEAType certIndex; | |
| 762 | |
| 763 /* Generate ephemeral ECDH key pair and send the public key */ | |
| 764 curve = ssl3_GetCurveNameForServerSocket(ss); | |
| 765 if (curve == ec_noName) { | |
| 766 goto loser; | |
| 767 } | |
| 768 rv = ssl3_CreateECDHEphemeralKeys(ss, curve); | |
| 769 if (rv != SECSuccess) { | |
| 770 goto loser; /* err set by AppendHandshake. */ | |
| 771 } | |
| 772 ecdhePub = ss->ephemeralECDHKeyPair->pubKey; | |
| 773 PORT_Assert(ecdhePub != NULL); | |
| 774 if (!ecdhePub) { | |
| 775 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | |
| 776 return SECFailure; | |
| 777 } | |
| 778 | |
| 779 ec_params.len = sizeof paramBuf; | |
| 780 ec_params.data = paramBuf; | |
| 781 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); | |
| 782 if (curve != ec_noName) { | |
| 783 ec_params.data[0] = ec_type_named; | |
| 784 ec_params.data[1] = 0x00; | |
| 785 ec_params.data[2] = curve; | |
| 786 } else { | |
| 787 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | |
| 788 goto loser; | |
| 789 } | |
| 790 | |
| 791 rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg, | |
| 792 ec_params, | |
| 793 ecdhePub->u.ec.publicValue, | |
| 794 &ss->ssl3.hs.client_random, | |
| 795 &ss->ssl3.hs.server_random, | |
| 796 &hashes, ss->opt.bypassPKCS11); | |
| 797 if (rv != SECSuccess) { | |
| 798 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | |
| 799 goto loser; | |
| 800 } | |
| 801 | |
| 802 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | |
| 803 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | |
| 804 | |
| 805 /* XXX SSLKEAType isn't really a good choice for | |
| 806 * indexing certificates but that's all we have | |
| 807 * for now. | |
| 808 */ | |
| 809 if (kea_def->kea == kea_ecdhe_rsa) | |
| 810 certIndex = kt_rsa; | |
| 811 else /* kea_def->kea == kea_ecdhe_ecdsa */ | |
| 812 certIndex = kt_ecdh; | |
| 813 | |
| 814 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, | |
| 815 &signed_hash, isTLS); | |
| 816 if (rv != SECSuccess) { | |
| 817 goto loser; /* ssl3_SignHashes has set err. */ | |
| 818 } | |
| 819 if (signed_hash.data == NULL) { | |
| 820 /* how can this happen and rv == SECSuccess ?? */ | |
| 821 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | |
| 822 goto loser; | |
| 823 } | |
| 824 | |
| 825 length = ec_params.len + | |
| 826 1 + ecdhePub->u.ec.publicValue.len + | |
| 827 (isTLS12 ? 2 : 0) + 2 + signed_hash.len; | |
| 828 | |
| 829 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); | |
| 830 if (rv != SECSuccess) { | |
| 831 goto loser; /* err set by AppendHandshake. */ | |
| 832 } | |
| 833 | |
| 834 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len); | |
| 835 if (rv != SECSuccess) { | |
| 836 goto loser; /* err set by AppendHandshake. */ | |
| 837 } | |
| 838 | |
| 839 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data, | |
| 840 ecdhePub->u.ec.publicValue.len, 1); | |
| 841 if (rv != SECSuccess) { | |
| 842 goto loser; /* err set by AppendHandshake. */ | |
| 843 } | |
| 844 | |
| 845 if (isTLS12) { | |
| 846 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash); | |
| 847 if (rv != SECSuccess) { | |
| 848 goto loser; /* err set by AppendHandshake. */ | |
| 849 } | |
| 850 } | |
| 851 | |
| 852 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, | |
| 853 signed_hash.len, 2); | |
| 854 if (rv != SECSuccess) { | |
| 855 goto loser; /* err set by AppendHandshake. */ | |
| 856 } | |
| 857 | |
| 858 PORT_Free(signed_hash.data); | |
| 859 return SECSuccess; | |
| 860 | |
| 861 loser: | |
| 862 if (signed_hash.data != NULL) | |
| 863 PORT_Free(signed_hash.data); | |
| 864 return SECFailure; | |
| 865 } | |
| 866 | |
| 867 /* Lists of ECC cipher suites for searching and disabling. */ | |
| 868 | |
| 869 static const ssl3CipherSuite ecdh_suites[] = { | |
| 870 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | |
| 871 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | |
| 872 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | |
| 873 TLS_ECDH_ECDSA_WITH_NULL_SHA, | |
| 874 TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | |
| 875 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, | |
| 876 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, | |
| 877 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, | |
| 878 TLS_ECDH_RSA_WITH_NULL_SHA, | |
| 879 TLS_ECDH_RSA_WITH_RC4_128_SHA, | |
| 880 0 /* end of list marker */ | |
| 881 }; | |
| 882 | |
| 883 static const ssl3CipherSuite ecdh_ecdsa_suites[] = { | |
| 884 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | |
| 885 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | |
| 886 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | |
| 887 TLS_ECDH_ECDSA_WITH_NULL_SHA, | |
| 888 TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | |
| 889 0 /* end of list marker */ | |
| 890 }; | |
| 891 | |
| 892 static const ssl3CipherSuite ecdh_rsa_suites[] = { | |
| 893 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, | |
| 894 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, | |
| 895 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, | |
| 896 TLS_ECDH_RSA_WITH_NULL_SHA, | |
| 897 TLS_ECDH_RSA_WITH_RC4_128_SHA, | |
| 898 0 /* end of list marker */ | |
| 899 }; | |
| 900 | |
| 901 static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { | |
| 902 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, | |
| 903 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, | |
| 904 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | |
| 905 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | |
| 906 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | |
| 907 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, | |
| 908 TLS_ECDHE_ECDSA_WITH_NULL_SHA, | |
| 909 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | |
| 910 0 /* end of list marker */ | |
| 911 }; | |
| 912 | |
| 913 static const ssl3CipherSuite ecdhe_rsa_suites[] = { | |
| 914 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, | |
| 915 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, | |
| 916 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | |
| 917 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | |
| 918 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | |
| 919 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, | |
| 920 TLS_ECDHE_RSA_WITH_NULL_SHA, | |
| 921 TLS_ECDHE_RSA_WITH_RC4_128_SHA, | |
| 922 0 /* end of list marker */ | |
| 923 }; | |
| 924 | |
| 925 /* List of all ECC cipher suites */ | |
| 926 static const ssl3CipherSuite ecSuites[] = { | |
| 927 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, | |
| 928 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, | |
| 929 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | |
| 930 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | |
| 931 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | |
| 932 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, | |
| 933 TLS_ECDHE_ECDSA_WITH_NULL_SHA, | |
| 934 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | |
| 935 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, | |
| 936 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, | |
| 937 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | |
| 938 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | |
| 939 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | |
| 940 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, | |
| 941 TLS_ECDHE_RSA_WITH_NULL_SHA, | |
| 942 TLS_ECDHE_RSA_WITH_RC4_128_SHA, | |
| 943 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | |
| 944 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | |
| 945 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | |
| 946 TLS_ECDH_ECDSA_WITH_NULL_SHA, | |
| 947 TLS_ECDH_ECDSA_WITH_RC4_128_SHA, | |
| 948 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, | |
| 949 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, | |
| 950 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, | |
| 951 TLS_ECDH_RSA_WITH_NULL_SHA, | |
| 952 TLS_ECDH_RSA_WITH_RC4_128_SHA, | |
| 953 0 /* end of list marker */ | |
| 954 }; | |
| 955 | |
| 956 /* On this socket, Disable the ECC cipher suites in the argument's list */ | |
| 957 SECStatus | |
| 958 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite) | |
| 959 { | |
| 960 if (!suite) | |
| 961 suite = ecSuites; | |
| 962 for (; *suite; ++suite) { | |
| 963 SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); | |
| 964 | |
| 965 PORT_Assert(rv == SECSuccess); /* else is coding error */ | |
| 966 } | |
| 967 return SECSuccess; | |
| 968 } | |
| 969 | |
| 970 /* Look at the server certs configured on this socket, and disable any | |
| 971 * ECC cipher suites that are not supported by those certs. | |
| 972 */ | |
| 973 void | |
| 974 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss) | |
| 975 { | |
| 976 CERTCertificate * svrCert; | |
| 977 | |
| 978 svrCert = ss->serverCerts[kt_rsa].serverCert; | |
| 979 if (!svrCert) { | |
| 980 ssl3_DisableECCSuites(ss, ecdhe_rsa_suites); | |
| 981 } | |
| 982 | |
| 983 svrCert = ss->serverCerts[kt_ecdh].serverCert; | |
| 984 if (!svrCert) { | |
| 985 ssl3_DisableECCSuites(ss, ecdh_suites); | |
| 986 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | |
| 987 } else { | |
| 988 SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature); | |
| 989 | |
| 990 switch (sigTag) { | |
| 991 case SEC_OID_PKCS1_RSA_ENCRYPTION: | |
| 992 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: | |
| 993 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: | |
| 994 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: | |
| 995 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: | |
| 996 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: | |
| 997 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: | |
| 998 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: | |
| 999 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: | |
| 1000 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); | |
| 1001 break; | |
| 1002 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: | |
| 1003 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: | |
| 1004 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: | |
| 1005 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: | |
| 1006 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: | |
| 1007 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: | |
| 1008 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: | |
| 1009 ssl3_DisableECCSuites(ss, ecdh_rsa_suites); | |
| 1010 break; | |
| 1011 default: | |
| 1012 ssl3_DisableECCSuites(ss, ecdh_suites); | |
| 1013 break; | |
| 1014 } | |
| 1015 } | |
| 1016 } | |
| 1017 | |
| 1018 /* Ask: is ANY ECC cipher suite enabled on this socket? */ | |
| 1019 /* Order(N^2). Yuk. Also, this ignores export policy. */ | |
| 1020 PRBool | |
| 1021 ssl3_IsECCEnabled(sslSocket * ss) | |
| 1022 { | |
| 1023 const ssl3CipherSuite * suite; | |
| 1024 PK11SlotInfo *slot; | |
| 1025 | |
| 1026 /* make sure we can do ECC */ | |
| 1027 slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg); | |
| 1028 if (!slot) { | |
| 1029 return PR_FALSE; | |
| 1030 } | |
| 1031 PK11_FreeSlot(slot); | |
| 1032 | |
| 1033 /* make sure an ECC cipher is enabled */ | |
| 1034 for (suite = ecSuites; *suite; ++suite) { | |
| 1035 PRBool enabled = PR_FALSE; | |
| 1036 SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled); | |
| 1037 | |
| 1038 PORT_Assert(rv == SECSuccess); /* else is coding error */ | |
| 1039 if (rv == SECSuccess && enabled) | |
| 1040 return PR_TRUE; | |
| 1041 } | |
| 1042 return PR_FALSE; | |
| 1043 } | |
| 1044 | |
| 1045 #define BE(n) 0, n | |
| 1046 | |
| 1047 /* Prefabricated TLS client hello extension, Elliptic Curves List, | |
| 1048 * offers only 3 curves, the Suite B curves, 23-25 | |
| 1049 */ | |
| 1050 static const PRUint8 suiteBECList[12] = { | |
| 1051 BE(10), /* Extension type */ | |
| 1052 BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */ | |
| 1053 BE( 6), /* octets that follow ( 3 pairs) */ | |
| 1054 BE(23), BE(24), BE(25) | |
| 1055 }; | |
| 1056 | |
| 1057 /* Prefabricated TLS client hello extension, Elliptic Curves List, | |
| 1058 * offers curves 1-25. | |
| 1059 */ | |
| 1060 static const PRUint8 tlsECList[56] = { | |
| 1061 BE(10), /* Extension type */ | |
| 1062 BE(52), /* octets that follow (25 pairs + 1 length pair) */ | |
| 1063 BE(50), /* octets that follow (25 pairs) */ | |
| 1064 BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7), | |
| 1065 BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15), | |
| 1066 BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23), | |
| 1067 BE(24), BE(25) | |
| 1068 }; | |
| 1069 | |
| 1070 static const PRUint8 ecPtFmt[6] = { | |
| 1071 BE(11), /* Extension type */ | |
| 1072 BE( 2), /* octets that follow */ | |
| 1073 1, /* octets that follow */ | |
| 1074 0 /* uncompressed type only */ | |
| 1075 }; | |
| 1076 | |
| 1077 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be | |
| 1078 * called before this function. It looks to see if we have a token which | |
| 1079 * is capable of doing smaller than SuiteB curves. If the token can, we | |
| 1080 * presume the token can do the whole SSL suite of curves. If it can't we | |
| 1081 * presume the token that allowed ECC to be enabled can only do suite B | |
| 1082 * curves. */ | |
| 1083 static PRBool | |
| 1084 ssl3_SuiteBOnly(sslSocket *ss) | |
| 1085 { | |
| 1086 #if 0 | |
| 1087 /* See if we can support small curves (like 163). If not, assume we can | |
| 1088 * only support Suite-B curves (P-256, P-384, P-521). */ | |
| 1089 PK11SlotInfo *slot = | |
| 1090 PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163, | |
| 1091 ss ? ss->pkcs11PinArg : NULL); | |
| 1092 | |
| 1093 if (!slot) { | |
| 1094 /* nope, presume we can only do suite B */ | |
| 1095 return PR_TRUE; | |
| 1096 } | |
| 1097 /* we can, presume we can do all curves */ | |
| 1098 PK11_FreeSlot(slot); | |
| 1099 return PR_FALSE; | |
| 1100 #else | |
| 1101 return PR_TRUE; | |
| 1102 #endif | |
| 1103 } | |
| 1104 | |
| 1105 /* Send our "canned" (precompiled) Supported Elliptic Curves extension, | |
| 1106 * which says that we support all TLS-defined named curves. | |
| 1107 */ | |
| 1108 PRInt32 | |
| 1109 ssl3_SendSupportedCurvesXtn( | |
| 1110 sslSocket * ss, | |
| 1111 PRBool append, | |
| 1112 PRUint32 maxBytes) | |
| 1113 { | |
| 1114 PRInt32 ecListSize = 0; | |
| 1115 const PRUint8 *ecList = NULL; | |
| 1116 | |
| 1117 if (!ss || !ssl3_IsECCEnabled(ss)) | |
| 1118 return 0; | |
| 1119 | |
| 1120 if (ssl3_SuiteBOnly(ss)) { | |
| 1121 ecListSize = sizeof suiteBECList; | |
| 1122 ecList = suiteBECList; | |
| 1123 } else { | |
| 1124 ecListSize = sizeof tlsECList; | |
| 1125 ecList = tlsECList; | |
| 1126 } | |
| 1127 | |
| 1128 if (append && maxBytes >= ecListSize) { | |
| 1129 SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize); | |
| 1130 if (rv != SECSuccess) | |
| 1131 return -1; | |
| 1132 if (!ss->sec.isServer) { | |
| 1133 TLSExtensionData *xtnData = &ss->xtnData; | |
| 1134 xtnData->advertised[xtnData->numAdvertised++] = | |
| 1135 ssl_elliptic_curves_xtn; | |
| 1136 } | |
| 1137 } | |
| 1138 return ecListSize; | |
| 1139 } | |
| 1140 | |
| 1141 PRUint32 | |
| 1142 ssl3_GetSupportedECCurveMask(sslSocket *ss) | |
| 1143 { | |
| 1144 if (ssl3_SuiteBOnly(ss)) { | |
| 1145 return SSL3_SUITE_B_SUPPORTED_CURVES_MASK; | |
| 1146 } | |
| 1147 return SSL3_ALL_SUPPORTED_CURVES_MASK; | |
| 1148 } | |
| 1149 | |
| 1150 /* Send our "canned" (precompiled) Supported Point Formats extension, | |
| 1151 * which says that we only support uncompressed points. | |
| 1152 */ | |
| 1153 PRInt32 | |
| 1154 ssl3_SendSupportedPointFormatsXtn( | |
| 1155 sslSocket * ss, | |
| 1156 PRBool append, | |
| 1157 PRUint32 maxBytes) | |
| 1158 { | |
| 1159 if (!ss || !ssl3_IsECCEnabled(ss)) | |
| 1160 return 0; | |
| 1161 if (append && maxBytes >= (sizeof ecPtFmt)) { | |
| 1162 SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); | |
| 1163 if (rv != SECSuccess) | |
| 1164 return -1; | |
| 1165 if (!ss->sec.isServer) { | |
| 1166 TLSExtensionData *xtnData = &ss->xtnData; | |
| 1167 xtnData->advertised[xtnData->numAdvertised++] = | |
| 1168 ssl_ec_point_formats_xtn; | |
| 1169 } | |
| 1170 } | |
| 1171 return (sizeof ecPtFmt); | |
| 1172 } | |
| 1173 | |
| 1174 /* Just make sure that the remote client supports uncompressed points, | |
| 1175 * Since that is all we support. Disable ECC cipher suites if it doesn't. | |
| 1176 */ | |
| 1177 SECStatus | |
| 1178 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type, | |
| 1179 SECItem *data) | |
| 1180 { | |
| 1181 int i; | |
| 1182 | |
| 1183 if (data->len < 2 || data->len > 255 || !data->data || | |
| 1184 data->len != (unsigned int)data->data[0] + 1) { | |
| 1185 /* malformed */ | |
| 1186 goto loser; | |
| 1187 } | |
| 1188 for (i = data->len; --i > 0; ) { | |
| 1189 if (data->data[i] == 0) { | |
| 1190 /* indicate that we should send a reply */ | |
| 1191 SECStatus rv; | |
| 1192 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | |
| 1193 &ssl3_SendSupportedPointFormatsXtn); | |
| 1194 return rv; | |
| 1195 } | |
| 1196 } | |
| 1197 loser: | |
| 1198 /* evil client doesn't support uncompressed */ | |
| 1199 ssl3_DisableECCSuites(ss, ecSuites); | |
| 1200 return SECFailure; | |
| 1201 } | |
| 1202 | |
| 1203 | |
| 1204 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \ | |
| 1205 (ss->serverCerts[type].serverKeyPair ? \ | |
| 1206 ss->serverCerts[type].serverKeyPair->pubKey : NULL) | |
| 1207 | |
| 1208 /* Extract the TLS curve name for the public key in our EC server cert. */ | |
| 1209 ECName ssl3_GetSvrCertCurveName(sslSocket *ss) | |
| 1210 { | |
| 1211 SECKEYPublicKey *srvPublicKey; | |
| 1212 ECName ec_curve = ec_noName; | |
| 1213 | |
| 1214 srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh); | |
| 1215 if (srvPublicKey) { | |
| 1216 ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams); | |
| 1217 } | |
| 1218 return ec_curve; | |
| 1219 } | |
| 1220 | |
| 1221 /* Ensure that the curve in our server cert is one of the ones suppored | |
| 1222 * by the remote client, and disable all ECC cipher suites if not. | |
| 1223 */ | |
| 1224 SECStatus | |
| 1225 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | |
| 1226 { | |
| 1227 PRInt32 list_len; | |
| 1228 PRUint32 peerCurves = 0; | |
| 1229 PRUint32 mutualCurves = 0; | |
| 1230 PRUint16 svrCertCurveName; | |
| 1231 | |
| 1232 if (!data->data || data->len < 4 || data->len > 65535) | |
| 1233 goto loser; | |
| 1234 /* get the length of elliptic_curve_list */ | |
| 1235 list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | |
| 1236 if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { | |
| 1237 /* malformed */ | |
| 1238 goto loser; | |
| 1239 } | |
| 1240 /* build bit vector of peer's supported curve names */ | |
| 1241 while (data->len) { | |
| 1242 PRInt32 curve_name = | |
| 1243 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | |
| 1244 if (curve_name > ec_noName && curve_name < ec_pastLastName) { | |
| 1245 peerCurves |= (1U << curve_name); | |
| 1246 } | |
| 1247 } | |
| 1248 /* What curves do we support in common? */ | |
| 1249 mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves; | |
| 1250 if (!mutualCurves) { /* no mutually supported EC Curves */ | |
| 1251 goto loser; | |
| 1252 } | |
| 1253 | |
| 1254 /* if our ECC cert doesn't use one of these supported curves, | |
| 1255 * disable ECC cipher suites that require an ECC cert. | |
| 1256 */ | |
| 1257 svrCertCurveName = ssl3_GetSvrCertCurveName(ss); | |
| 1258 if (svrCertCurveName != ec_noName && | |
| 1259 (mutualCurves & (1U << svrCertCurveName)) != 0) { | |
| 1260 return SECSuccess; | |
| 1261 } | |
| 1262 /* Our EC cert doesn't contain a mutually supported curve. | |
| 1263 * Disable all ECC cipher suites that require an EC cert | |
| 1264 */ | |
| 1265 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); | |
| 1266 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | |
| 1267 return SECFailure; | |
| 1268 | |
| 1269 loser: | |
| 1270 /* no common curve supported */ | |
| 1271 ssl3_DisableECCSuites(ss, ecSuites); | |
| 1272 return SECFailure; | |
| 1273 } | |
| 1274 | |
| 1275 #endif /* NSS_ENABLE_ECC */ | |
| OLD | NEW |