/* function to clear out the lists */ static SECStatus ssl_ShutdownECDHECurves(void *appData, void *nssData) { int i; for (i = 0; i < PR_ARRAY_SIZE(gECDHEKeyPairs); i++) { if (gECDHEKeyPairs[i].pair) { ssl_FreeEphemeralKeyPair(gECDHEKeyPairs[i].pair); } } memset(gECDHEKeyPairs, 0, sizeof(gECDHEKeyPairs)); return SECSuccess; }
void ssl3_DestroyExtensionData(TLSExtensionData *xtnData) { ssl3_FreeSniNameArray(xtnData); PORT_Free(xtnData->sigSchemes); SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); tls13_DestroyKeyShares(&xtnData->remoteKeyShares); SECITEM_FreeItem(&xtnData->certReqContext, PR_FALSE); SECITEM_FreeItem(&xtnData->applicationToken, PR_FALSE); if (xtnData->certReqAuthorities.arena) { PORT_FreeArena(xtnData->certReqAuthorities.arena, PR_FALSE); xtnData->certReqAuthorities.arena = NULL; } PORT_Free(xtnData->advertised); ssl_FreeEphemeralKeyPair(xtnData->esniPrivateKey); SECITEM_FreeItem(&xtnData->keyShareExtension, PR_FALSE); }
/* Called from ssl3_SendClientKeyExchange(). */ SECStatus ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) { PK11SymKey *pms = NULL; SECStatus rv = SECFailure; PRBool isTLS, isTLS12; CK_MECHANISM_TYPE target; const namedGroupDef *groupDef; sslEphemeralKeyPair *keyPair = NULL; SECKEYPublicKey *pubKey; PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); /* Generate ephemeral EC keypair */ if (svrPubKey->keyType != ecKey) { PORT_SetError(SEC_ERROR_BAD_KEY); goto loser; } groupDef = ssl_ECPubKey2NamedGroup(svrPubKey); if (!groupDef) { PORT_SetError(SEC_ERROR_BAD_KEY); goto loser; } rv = ssl_CreateECDHEphemeralKeyPair(groupDef, &keyPair); if (rv != SECSuccess) { ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); goto loser; } pubKey = keyPair->keys->pubKey; PRINT_BUF(50, (ss, "ECDH public value:", pubKey->u.ec.publicValue.data, pubKey->u.ec.publicValue.len)); if (isTLS12) { target = CKM_TLS12_MASTER_KEY_DERIVE_DH; } else if (isTLS) { target = CKM_TLS_MASTER_KEY_DERIVE_DH; } else { target = CKM_SSL3_MASTER_KEY_DERIVE_DH; } /* Determine the PMS */ pms = PK11_PubDeriveWithKDF(keyPair->keys->privKey, svrPubKey, PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, CKD_NULL, NULL, NULL); if (pms == NULL) { (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser; } rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, pubKey->u.ec.publicValue.len + 1); if (rv != SECSuccess) { goto loser; /* err set by ssl3_AppendHandshake* */ } rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data, pubKey->u.ec.publicValue.len, 1); if (rv != SECSuccess) { goto loser; /* err set by ssl3_AppendHandshake* */ } rv = ssl3_InitPendingCipherSpec(ss, pms); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser; } PK11_FreeSymKey(pms); ssl_FreeEphemeralKeyPair(keyPair); return SECSuccess; loser: if (pms) PK11_FreeSymKey(pms); if (keyPair) ssl_FreeEphemeralKeyPair(keyPair); return SECFailure; }