/* Find the "weakest link". Get the strength of the signature and symmetric * keys and choose a curve based on the weakest of those two. */ const sslNamedGroupDef * ssl_GetECGroupForServerSocket(sslSocket *ss) { const sslServerCert *cert = ss->sec.serverCert; unsigned int certKeySize; const ssl3BulkCipherDef *bulkCipher; unsigned int requiredECCbits; PORT_Assert(cert); if (!cert || !cert->serverKeyPair || !cert->serverKeyPair->pubKey) { PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); return NULL; } if (cert->certType.authType == ssl_auth_rsa_sign) { certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey); certKeySize = SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize); } else if (cert->certType.authType == ssl_auth_ecdsa || cert->certType.authType == ssl_auth_ecdh_rsa || cert->certType.authType == ssl_auth_ecdh_ecdsa) { const sslNamedGroupDef *groupDef = cert->certType.namedCurve; /* We won't select a certificate unless the named curve has been * negotiated (or supported_curves was absent), double check that. */ PORT_Assert(groupDef->keaType == ssl_kea_ecdh); PORT_Assert(ssl_NamedGroupEnabled(ss, groupDef)); if (!ssl_NamedGroupEnabled(ss, groupDef)) { return NULL; } certKeySize = groupDef->bits; } else { PORT_Assert(0); return NULL; } bulkCipher = ssl_GetBulkCipherDef(ss->ssl3.hs.suite_def); requiredECCbits = bulkCipher->key_size * BPB * 2; PORT_Assert(requiredECCbits || ss->ssl3.hs.suite_def->bulk_cipher_alg == cipher_null); if (requiredECCbits > certKeySize) { requiredECCbits = certKeySize; } return ssl_GetECGroupWithStrength(ss, requiredECCbits); }
/* Find the "weakest link". Get the strength of the signature and symmetric * keys and choose a curve based on the weakest of those two. */ const namedGroupDef * ssl_GetECGroupForServerSocket(sslSocket *ss) { const sslServerCert *cert = ss->sec.serverCert; int certKeySize; int requiredECCbits = ss->sec.secretKeyBits * 2; PORT_Assert(cert); if (!cert || !cert->serverKeyPair || !cert->serverKeyPair->pubKey) { PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); return NULL; } if (cert->certType.authType == ssl_auth_rsa_sign) { certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey); certKeySize = SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize); } else if (cert->certType.authType == ssl_auth_ecdsa || cert->certType.authType == ssl_auth_ecdh_rsa || cert->certType.authType == ssl_auth_ecdh_ecdsa) { const namedGroupDef *groupDef = cert->certType.namedCurve; /* We won't select a certificate unless the named curve has been * negotiated (or supported_curves was absent), double check that. */ PORT_Assert(groupDef->type == group_type_ec); PORT_Assert(ssl_NamedGroupEnabled(ss, groupDef)); if (!ssl_NamedGroupEnabled(ss, groupDef)) { return NULL; } certKeySize = groupDef->bits; } else { PORT_Assert(0); return NULL; } if (requiredECCbits > certKeySize) { requiredECCbits = certKeySize; } return ssl_GetECGroupWithStrength(ss->namedGroups, requiredECCbits); }
SECStatus tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; PRUint32 tmp; const sslNamedGroupDef *group; PORT_Assert(!ss->sec.isServer); PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3); SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension in HRR", SSL_GETPID(), ss->fd)); rv = ssl3_ExtConsumeHandshakeNumber(ss, &tmp, 2, &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; /* error code already set */ } if (data->len) { ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); return SECFailure; } group = ssl_LookupNamedGroup((SSLNamedGroup)tmp); /* If the group is not enabled, or we already have a share for the * requested group, abort. */ if (!ssl_NamedGroupEnabled(ss, group) || ssl_HaveEphemeralKeyPair(ss, group)) { ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); return SECFailure; } /* Now delete all the key shares per [draft-ietf-tls-tls13 S 4.1.2] */ ssl_FreeEphemeralKeyPairs(CONST_CAST(sslSocket, ss)); /* And replace with our new share. */ rv = tls13_CreateKeyShare(CONST_CAST(sslSocket, ss), group); if (rv != SECSuccess) { ssl3_ExtSendAlert(ss, alert_fatal, internal_error); PORT_SetError(SEC_ERROR_KEYGEN_FAIL); return SECFailure; } return SECSuccess; }
/* Send our Supported Groups extension. */ PRInt32 ssl_SendSupportedGroupsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; unsigned char enabledGroups[64]; unsigned int enabledGroupsLen = 0; unsigned int i; PRBool ec; PRBool ff = PR_FALSE; if (!ss) return 0; ec = ssl_IsECCEnabled(ss); /* We only send FF supported groups if we require DH named groups or if TLS * 1.3 is a possibility. */ if (ss->opt.requireDHENamedGroups || ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) { ff = ssl_IsSuiteEnabled(ss, ssl_dhe_suites); } if (!ec && !ff) { return 0; } PORT_Assert(sizeof(enabledGroups) > ssl_named_group_count * 2); for (i = 0; i < ssl_named_group_count; ++i) { if (ssl_named_groups[i].type == group_type_ec && !ec) { continue; } if (ssl_named_groups[i].type == group_type_ff && !ff) { continue; } if (!ssl_NamedGroupEnabled(ss, &ssl_named_groups[i])) { continue; } if (append) { enabledGroups[enabledGroupsLen++] = ssl_named_groups[i].name >> 8; enabledGroups[enabledGroupsLen++] = ssl_named_groups[i].name & 0xff; } else { enabledGroupsLen += 2; } }