-/* ssl/s3_srvr.c */
+/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
static const SSL_METHOD *ssl3_get_server_method(int ver);
-#ifndef OPENSSL_NO_ECDH
-static int nid2curve_id(int nid);
-#endif
-
static const SSL_METHOD *ssl3_get_server_method(int ver)
{
if (ver == SSL3_VERSION)
case SSL3_ST_SW_CERT_A:
case SSL3_ST_SW_CERT_B:
- /* Check if it is anon DH or anon ECDH */
- /* or normal PSK */
+ /* Check if it is anon DH or anon ECDH, */
+ /* normal PSK or KRB5 */
if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)
- && !(s->s3->tmp.new_cipher->algorithms & SSL_kPSK))
+ && !(s->s3->tmp.new_cipher->algorithms & SSL_kPSK)
+ && !(s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
{
ret=ssl3_send_server_certificate(s);
if (ret <= 0) goto end;
* For ECC ciphersuites, we send a serverKeyExchange
* message only if the cipher suite is either
* ECDH-anon or ECDHE. In other cases, the
- * server certificate contains the server's
+ * server certificate contains the server's
* public key for key exchange.
*/
if (s->s3->tmp.use_rsa_tmp
#ifndef OPENSSL_NO_PSK
|| ((l & SSL_kPSK) && s->ctx->psk_identity_hint)
#endif
- || (l & SSL_kECDHE)
- || (l & (SSL_DH|SSL_kFZA))
+ || (l & SSL_DH)
+ || (l & SSL_kEECDH)
|| ((l & SSL_kRSA)
&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
|| (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
case SSL3_ST_SR_KEY_EXCH_A:
case SSL3_ST_SR_KEY_EXCH_B:
ret=ssl3_get_client_key_exchange(s);
- if (ret <= 0)
+ if (ret <= 0)
goto end;
if (ret == 2)
{
s->state=SSL3_ST_SR_FINISHED_A;
s->init_num = 0;
}
- else
+ else
{
s->state=SSL3_ST_SR_CERT_VRFY_A;
s->init_num=0;
/* We need to get hashes here so if there is
* a client cert, it can be verified
- */
+ */
s->method->ssl3_enc->cert_verify_mac(s,
&(s->s3->finish_dgst1),
&(s->s3->tmp.cert_verify_md[0]));
*/
if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
{
- s->first_packet=1;
s->state=SSL3_ST_SR_CLNT_HELLO_B;
}
+ s->first_packet=1;
n=s->method->ssl_get_message(s,
SSL3_ST_SR_CLNT_HELLO_B,
SSL3_ST_SR_CLNT_HELLO_C,
&ok);
if (!ok) return((int)n);
+ s->first_packet=0;
d=p=(unsigned char *)s->init_msg;
/* use version from inside client hello, not from record header
if (s->client_version < s->version)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
- if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
+ if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
{
/* similar to ssl3_get_record, send alert using remote version number */
s->version = s->client_version;
else
#endif
#ifndef OPENSSL_NO_ECDH
- if (type & SSL_kECDHE)
+ if (type & SSL_kEECDH)
{
const EC_GROUP *group;
* supported named curves, curve_id is non-zero.
*/
if ((curve_id =
- nid2curve_id(EC_GROUP_get_curve_name(group)))
+ tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
== 0)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
}
#ifndef OPENSSL_NO_ECDH
- if (type & SSL_kECDHE)
+ if (type & SSL_kEECDH)
{
/* XXX: For now, we only support named (not generic) curves.
* In this situation, the serverKeyExchange message has:
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
+ if (!((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
+ {
+ /* The premaster secret must contain the same version number as the
+ * ClientHello to detect version rollback attacks (strangely, the
+ * protocol does not offer such protection for DH ciphersuites).
+ * However, buggy clients exist that send random bytes instead of
+ * the protocol version.
+ * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients.
+ * (Perhaps we should have a separate BUG value for the Kerberos cipher)
+ */
+ if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
+ (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+ SSL_AD_DECODE_ERROR);
+ goto err;
+ }
+ }
+
EVP_CIPHER_CTX_cleanup(&ciph_ctx);
s->session->master_key_length=
if (kssl_ctx->client_princ)
{
- int len = strlen(kssl_ctx->client_princ);
+ size_t len = strlen(kssl_ctx->client_princ);
if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH )
{
s->session->krb5_client_princ_len = len;
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_ECDH
- if ((l & SSL_kECDH) || (l & SSL_kECDHE))
+ if ((l & SSL_kECDH) || (l & SSL_kEECDH))
{
int ret = 1;
int field_size = 0;
if (l & SSL_kECDH)
{
/* use the certificate */
- tkey = s->cert->key->privatekey->pkey.ec;
+ tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
}
else
{
{
/* Client Publickey was in Client Certificate */
- if (l & SSL_kECDHE)
+ if (l & SSL_kEECDH)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
/* SSL3_ST_SW_CERT_B */
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
}
-
-
-#ifndef OPENSSL_NO_ECDH
-/* This is the complement of curve_id2nid in s3_clnt.c. */
-static int nid2curve_id(int nid)
-{
- /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001)
- * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */
- switch (nid) {
- case NID_sect163k1: /* sect163k1 (1) */
- return 1;
- case NID_sect163r1: /* sect163r1 (2) */
- return 2;
- case NID_sect163r2: /* sect163r2 (3) */
- return 3;
- case NID_sect193r1: /* sect193r1 (4) */
- return 4;
- case NID_sect193r2: /* sect193r2 (5) */
- return 5;
- case NID_sect233k1: /* sect233k1 (6) */
- return 6;
- case NID_sect233r1: /* sect233r1 (7) */
- return 7;
- case NID_sect239k1: /* sect239k1 (8) */
- return 8;
- case NID_sect283k1: /* sect283k1 (9) */
- return 9;
- case NID_sect283r1: /* sect283r1 (10) */
- return 10;
- case NID_sect409k1: /* sect409k1 (11) */
- return 11;
- case NID_sect409r1: /* sect409r1 (12) */
- return 12;
- case NID_sect571k1: /* sect571k1 (13) */
- return 13;
- case NID_sect571r1: /* sect571r1 (14) */
- return 14;
- case NID_secp160k1: /* secp160k1 (15) */
- return 15;
- case NID_secp160r1: /* secp160r1 (16) */
- return 16;
- case NID_secp160r2: /* secp160r2 (17) */
- return 17;
- case NID_secp192k1: /* secp192k1 (18) */
- return 18;
- case NID_X9_62_prime192v1: /* secp192r1 (19) */
- return 19;
- case NID_secp224k1: /* secp224k1 (20) */
- return 20;
- case NID_secp224r1: /* secp224r1 (21) */
- return 21;
- case NID_secp256k1: /* secp256k1 (22) */
- return 22;
- case NID_X9_62_prime256v1: /* secp256r1 (23) */
- return 23;
- case NID_secp384r1: /* secp384r1 (24) */
- return 24;
- case NID_secp521r1: /* secp521r1 (25) */
- return 25;
- default:
- return 0;
- }
-}
-#endif