const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT;
-#ifndef OPENSSL_NO_TLSEXT
static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
const unsigned char *sess_id, int sesslen,
SSL_SESSION **psess);
static int ssl_check_clienthello_tlsext_early(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
-#endif
SSL3_ENC_METHOD const TLSv1_enc_data = {
tls1_enc,
void tls1_free(SSL *s)
{
-#ifndef OPENSSL_NO_TLSEXT
- if (s->tlsext_session_ticket) {
- OPENSSL_free(s->tlsext_session_ticket);
- }
-#endif /* OPENSSL_NO_TLSEXT */
+ OPENSSL_free(s->tlsext_session_ticket);
ssl3_free(s);
}
TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
};
-static const unsigned char eccurves_default[] = {
- 0, 14, /* sect571r1 (14) */
- 0, 13, /* sect571k1 (13) */
+/* The client's default curves / the server's 'auto' curves. */
+static const unsigned char eccurves_auto[] = {
+ /* Prefer P-256 which has the fastest and most secure implementations. */
+ 0, 23, /* secp256r1 (23) */
+ /* Other >= 256-bit prime curves. */
0, 25, /* secp521r1 (25) */
0, 28, /* brainpool512r1 (28) */
- 0, 11, /* sect409k1 (11) */
- 0, 12, /* sect409r1 (12) */
0, 27, /* brainpoolP384r1 (27) */
0, 24, /* secp384r1 (24) */
+ 0, 26, /* brainpoolP256r1 (26) */
+ 0, 22, /* secp256k1 (22) */
+ /* >= 256-bit binary curves. */
+ 0, 14, /* sect571r1 (14) */
+ 0, 13, /* sect571k1 (13) */
+ 0, 11, /* sect409k1 (11) */
+ 0, 12, /* sect409r1 (12) */
0, 9, /* sect283k1 (9) */
0, 10, /* sect283r1 (10) */
+};
+
+static const unsigned char eccurves_all[] = {
+ /* Prefer P-256 which has the fastest and most secure implementations. */
+ 0, 23, /* secp256r1 (23) */
+ /* Other >= 256-bit prime curves. */
+ 0, 25, /* secp521r1 (25) */
+ 0, 28, /* brainpool512r1 (28) */
+ 0, 27, /* brainpoolP384r1 (27) */
+ 0, 24, /* secp384r1 (24) */
0, 26, /* brainpoolP256r1 (26) */
0, 22, /* secp256k1 (22) */
- 0, 23, /* secp256r1 (23) */
+ /* >= 256-bit binary curves. */
+ 0, 14, /* sect571r1 (14) */
+ 0, 13, /* sect571k1 (13) */
+ 0, 11, /* sect409k1 (11) */
+ 0, 12, /* sect409r1 (12) */
+ 0, 9, /* sect283k1 (9) */
+ 0, 10, /* sect283r1 (10) */
+ /*
+ * Remaining curves disabled by default but still permitted if set
+ * via an explicit callback or parameters.
+ */
+ 0, 20, /* secp224k1 (20) */
+ 0, 21, /* secp224r1 (21) */
+ 0, 18, /* secp192k1 (18) */
+ 0, 19, /* secp192r1 (19) */
+ 0, 15, /* secp160k1 (15) */
+ 0, 16, /* secp160r1 (16) */
+ 0, 17, /* secp160r2 (17) */
0, 8, /* sect239k1 (8) */
0, 6, /* sect233k1 (6) */
0, 7, /* sect233r1 (7) */
- 0, 20, /* secp224k1 (20) */
- 0, 21, /* secp224r1 (21) */
0, 4, /* sect193r1 (4) */
0, 5, /* sect193r2 (5) */
- 0, 18, /* secp192k1 (18) */
- 0, 19, /* secp192r1 (19) */
0, 1, /* sect163k1 (1) */
0, 2, /* sect163r1 (2) */
0, 3, /* sect163r2 (3) */
- 0, 15, /* secp160k1 (15) */
- 0, 16, /* secp160r1 (16) */
- 0, 17, /* secp160r2 (17) */
};
+
static const unsigned char suiteb_curves[] = {
0, TLSEXT_curve_P_256,
0, TLSEXT_curve_P_384
int tls1_ec_curve_id2nid(int curve_id)
{
/* ECC curves from RFC 4492 and RFC 7027 */
- if ((curve_id < 1) || ((unsigned int)curve_id >
- sizeof(nid_list) / sizeof(nid_list[0])))
+ if ((curve_id < 1) || ((unsigned int)curve_id > OSSL_NELEM(nid_list)))
return 0;
return nid_list[curve_id - 1].nid;
}
pcurveslen = s->tlsext_ellipticcurvelist_length;
}
if (!*pcurves) {
- *pcurves = eccurves_default;
- pcurveslen = sizeof(eccurves_default);
+ if (!s->server || (s->cert && s->cert->ecdh_tmp_auto)) {
+ *pcurves = eccurves_auto;
+ pcurveslen = sizeof(eccurves_auto);
+ } else {
+ *pcurves = eccurves_all;
+ pcurveslen = sizeof(eccurves_all);
+ }
}
}
const tls_curve_info *cinfo;
if (curve[0])
return 1;
- if ((curve[1] < 1) || ((size_t)curve[1] >
- sizeof(nid_list) / sizeof(nid_list[0])))
+ if ((curve[1] < 1) || ((size_t)curve[1] > OSSL_NELEM(nid_list)))
return 0;
cinfo = &nid_list[curve[1] - 1];
# ifdef OPENSSL_NO_EC2M
(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref,
&num_pref))
return nmatch == -1 ? 0 : NID_undef;
+
+ /*
+ * If the client didn't send the elliptic_curves extension all of them
+ * are allowed.
+ */
+ if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) {
+ supp = eccurves_all;
+ num_supp = sizeof(eccurves_all) / 2;
+ } else if (num_pref == 0 &&
+ (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) {
+ pref = eccurves_all;
+ num_pref = sizeof(eccurves_all) / 2;
+ }
+
k = 0;
for (i = 0; i < num_pref; i++, pref += 2) {
const unsigned char *tsupp = supp;
dup_list |= idmask;
s2n(id, p);
}
- if (*pext)
- OPENSSL_free(*pext);
+ OPENSSL_free(*pext);
*pext = clist;
*pextlen = ncurves * 2;
return 1;
for (j = 0; j <= 1; j++) {
if (!tls1_get_curvelist(s, j, &pcurves, &num_curves))
return 0;
+ if (j == 1 && num_curves == 0) {
+ /*
+ * If we've not received any curves then skip this check.
+ * RFC 4492 does not require the supported elliptic curves extension
+ * so if it is not sent we can just choose any curve.
+ * It is invalid to send an empty list in the elliptic curves
+ * extension, so num_curves == 0 always means no extension.
+ */
+ break;
+ }
for (i = 0; i < num_curves; i++, pcurves += 2) {
if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1])
break;
return 0;
if (set_ee_md == 2) {
if (check_md == NID_ecdsa_with_SHA256)
- c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256();
+ s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha256();
else
- c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384();
+ s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha384();
}
}
return rv;
}
-# ifndef OPENSSL_NO_ECDH
+# ifndef OPENSSL_NO_EC
/* Check EC temporary key is compatible with client extensions */
int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
{
return tls1_check_ec_key(s, curve_id, NULL);
# endif
}
-# endif /* OPENSSL_NO_ECDH */
+# endif /* OPENSSL_NO_EC */
#else
#endif /* OPENSSL_NO_EC */
-#ifndef OPENSSL_NO_TLSEXT
-
/*
* List of supported signature algorithms and hashes. Should make this
* customisable at some point, for now include everything we support.
*/
-# ifdef OPENSSL_NO_RSA
-# define tlsext_sigalg_rsa(md) /* */
-# else
-# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
-# endif
+#ifdef OPENSSL_NO_RSA
+# define tlsext_sigalg_rsa(md) /* */
+#else
+# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
+#endif
-# ifdef OPENSSL_NO_DSA
-# define tlsext_sigalg_dsa(md) /* */
-# else
-# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
-# endif
+#ifdef OPENSSL_NO_DSA
+# define tlsext_sigalg_dsa(md) /* */
+#else
+# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
+#endif
-# ifdef OPENSSL_NO_ECDSA
-# define tlsext_sigalg_ecdsa(md)
- /* */
-# else
-# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
-# endif
+#ifdef OPENSSL_NO_EC
+# define tlsext_sigalg_ecdsa(md) /* */
+#else
+# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
+#endif
-# define tlsext_sigalg(md) \
+#define tlsext_sigalg(md) \
tlsext_sigalg_rsa(md) \
tlsext_sigalg_dsa(md) \
tlsext_sigalg_ecdsa(md)
tlsext_sigalg(TLSEXT_hash_sha1)
};
-# ifndef OPENSSL_NO_ECDSA
+#ifndef OPENSSL_NO_EC
static const unsigned char suiteb_sigalgs[] = {
tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
};
-# endif
+#endif
size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
{
/*
* If Suite B mode use Suite B sigalgs only, ignore any other
* preferences.
*/
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
switch (tls1_suiteb(s)) {
case SSL_CERT_FLAG_SUITEB_128_LOS:
*psigs = suiteb_sigalgs;
*psigs = suiteb_sigalgs + 2;
return 2;
}
-# endif
+#endif
/* If server use client authentication sigalgs if not NULL */
if (s->server && s->cert->client_sigalgs) {
*psigs = s->cert->client_sigalgs;
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
}
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC) {
unsigned char curve_id[2], comp_id;
/* Check compression and curve matches extensions */
}
} else if (tls1_suiteb(s))
return 0;
-# endif
+#endif
/* Check signature matches a type we sent */
sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
/*
* Store the digest used so applications can retrieve it if they wish.
*/
- if (s->session && s->session->sess_cert)
- s->session->sess_cert->peer_key->digest = *pmd;
+ s->s3->tmp.peer_md = *pmd;
return 1;
}
*/
void ssl_set_client_disabled(SSL *s)
{
- CERT *c = s->cert;
- c->mask_a = 0;
- c->mask_k = 0;
+ s->s3->tmp.mask_a = 0;
+ s->s3->tmp.mask_k = 0;
/* Don't allow TLS 1.2 only ciphers if we don't suppport them */
if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s))
- c->mask_ssl = SSL_TLSV1_2;
+ s->s3->tmp.mask_ssl = SSL_TLSV1_2;
else
- c->mask_ssl = 0;
- ssl_set_sig_mask(&c->mask_a, s, SSL_SECOP_SIGALG_MASK);
+ s->s3->tmp.mask_ssl = 0;
+ ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
/*
* Disable static DH if we don't include any appropriate signature
* algorithms.
*/
- if (c->mask_a & SSL_aRSA)
- c->mask_k |= SSL_kDHr | SSL_kECDHr;
- if (c->mask_a & SSL_aDSS)
- c->mask_k |= SSL_kDHd;
- if (c->mask_a & SSL_aECDSA)
- c->mask_k |= SSL_kECDHe;
-# ifndef OPENSSL_NO_KRB5
- if (!kssl_tgt_is_available(s->kssl_ctx)) {
- c->mask_a |= SSL_aKRB5;
- c->mask_k |= SSL_kKRB5;
- }
-# endif
+ if (s->s3->tmp.mask_a & SSL_aRSA)
+ s->s3->tmp.mask_k |= SSL_kDHr | SSL_kECDHr;
+ if (s->s3->tmp.mask_a & SSL_aDSS)
+ s->s3->tmp.mask_k |= SSL_kDHd;
+ if (s->s3->tmp.mask_a & SSL_aECDSA)
+ s->s3->tmp.mask_k |= SSL_kECDHe;
# ifndef OPENSSL_NO_PSK
/* with PSK there must be client callback set */
if (!s->psk_client_callback) {
- c->mask_a |= SSL_aPSK;
- c->mask_k |= SSL_kPSK;
+ s->s3->tmp.mask_a |= SSL_aPSK;
+ s->s3->tmp.mask_k |= SSL_kPSK;
}
-# endif /* OPENSSL_NO_PSK */
-# ifndef OPENSSL_NO_SRP
+#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
- c->mask_a |= SSL_aSRP;
- c->mask_k |= SSL_kSRP;
+ s->s3->tmp.mask_a |= SSL_aSRP;
+ s->s3->tmp.mask_k |= SSL_kSRP;
}
-# endif
- c->valid = 1;
+#endif
}
int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
{
- CERT *ct = s->cert;
- if (c->algorithm_ssl & ct->mask_ssl || c->algorithm_mkey & ct->mask_k
- || c->algorithm_auth & ct->mask_a)
+ if (c->algorithm_ssl & s->s3->tmp.mask_ssl
+ || c->algorithm_mkey & s->s3->tmp.mask_k
+ || c->algorithm_auth & s->s3->tmp.mask_a)
return 1;
return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
}
int extdatalen = 0;
unsigned char *orig = buf;
unsigned char *ret = buf;
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
/* See if we support any ECC ciphersuites */
int using_ecc = 0;
if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
}
}
}
-# endif
+#endif
ret += 2;
memcpy(ret, s->tlsext_hostname, size_str);
ret += size_str;
}
-# ifndef OPENSSL_NO_SRP
+#ifndef OPENSSL_NO_SRP
/* Add SRP username if there is one */
if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
* Client Hello message */
memcpy(ret, s->srp_ctx.login, login_len);
ret += login_len;
}
-# endif
+#endif
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
if (using_ecc) {
/*
* Add TLS extension ECPointFormats to the ClientHello message
s2n(curves_list_len, ret);
ret += curves_list_len;
}
-# endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_EC */
if (tls_use_ticket(s)) {
int ticklen;
s2n(salglen, etmp);
ret += salglen;
}
-# ifdef TLSEXT_TYPE_opaque_prf_input
- if (s->s3->client_opaque_prf_input != NULL) {
- size_t col = s->s3->client_opaque_prf_input_len;
-
- if ((long)(limit - ret - 6 - col) < 0)
- return NULL;
- if (col > 0xFFFD) /* can't happen */
- return NULL;
-
- s2n(TLSEXT_TYPE_opaque_prf_input, ret);
- s2n(col + 2, ret);
- s2n(col, ret);
- memcpy(ret, s->s3->client_opaque_prf_input, col);
- ret += col;
- }
-# endif
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
int i;
if (extlen > 0)
i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
}
-# ifndef OPENSSL_NO_HEARTBEATS
+#ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension */
if ((limit - ret - 4 - 1) < 0)
return NULL;
*(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
else
*(ret++) = SSL_TLSEXT_HB_ENABLED;
-# endif
+#endif
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
/*
* The client advertises an emtpy extension to indicate its support
s2n(TLSEXT_TYPE_next_proto_neg, ret);
s2n(0, ret);
}
-# endif
+#endif
if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
ret += s->alpn_client_proto_list_len;
}
-# ifndef OPENSSL_NO_SRTP
+#ifndef OPENSSL_NO_SRTP
if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
int el;
- ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+ /* Returns 0 on success!! */
+ if (ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0)) {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
if ((limit - ret - 4 - el) < 0)
return NULL;
}
ret += el;
}
-# endif
+#endif
custom_ext_init(&s->cert->cli_ext);
/* Add custom TLS Extensions to ClientHello */
if (!custom_ext_add(s, 0, &ret, limit, al))
return NULL;
-# ifdef TLSEXT_TYPE_encrypt_then_mac
+#ifdef TLSEXT_TYPE_encrypt_then_mac
s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
s2n(0, ret);
-# endif
+#endif
+ s2n(TLSEXT_TYPE_extended_master_secret, ret);
+ s2n(0, ret);
/*
* Add padding to workaround bugs in F5 terminators. See
*/
if (s->options & SSL_OP_TLSEXT_PADDING) {
int hlen = ret - (unsigned char *)s->init_buf->data;
- /*
- * The code in s23_clnt.c to build ClientHello messages includes the
- * 5-byte record header in the buffer, while the code in s3_clnt.c
- * does not.
- */
- if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
- hlen -= 5;
+
if (hlen > 0xff && hlen < 0x200) {
hlen = 0x200 - hlen;
if (hlen >= 4)
int extdatalen = 0;
unsigned char *orig = buf;
unsigned char *ret = buf;
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen;
-# endif
-# ifndef OPENSSL_NO_EC
+#endif
+#ifndef OPENSSL_NO_EC
unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
int using_ecc = (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe))
|| (alg_a & SSL_aECDSA);
using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-# endif
+#endif
ret += 2;
if (ret >= limit)
s2n(TLSEXT_TYPE_server_name, ret);
s2n(0, ret);
}
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
if (using_ecc) {
const unsigned char *plist;
size_t plistlen;
* Currently the server should not respond with a SupportedCurves
* extension
*/
-# endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_EC */
if (s->tlsext_ticket_expected && tls_use_ticket(s)) {
if ((long)(limit - ret - 4) < 0)
s2n(TLSEXT_TYPE_status_request, ret);
s2n(0, ret);
}
-# ifdef TLSEXT_TYPE_opaque_prf_input
- if (s->s3->server_opaque_prf_input != NULL) {
- size_t sol = s->s3->server_opaque_prf_input_len;
- if ((long)(limit - ret - 6 - sol) < 0)
- return NULL;
- if (sol > 0xFFFD) /* can't happen */
- return NULL;
-
- s2n(TLSEXT_TYPE_opaque_prf_input, ret);
- s2n(sol + 2, ret);
- s2n(sol, ret);
- memcpy(ret, s->s3->server_opaque_prf_input, sol);
- ret += sol;
- }
-# endif
-
-# ifndef OPENSSL_NO_SRTP
+#ifndef OPENSSL_NO_SRTP
if (SSL_IS_DTLS(s) && s->srtp_profile) {
int el;
- ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
-
+ /* Returns 0 on success!! */
+ if (ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0)) {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
if ((limit - ret - 4 - el) < 0)
return NULL;
}
ret += el;
}
-# endif
+#endif
if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
|| (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
ret += 36;
}
-# ifndef OPENSSL_NO_HEARTBEATS
+#ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension if we've received one */
if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
if ((limit - ret - 4 - 1) < 0)
*(ret++) = SSL_TLSEXT_HB_ENABLED;
}
-# endif
+#endif
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
next_proto_neg_seen = s->s3->next_proto_neg_seen;
s->s3->next_proto_neg_seen = 0;
if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
s->s3->next_proto_neg_seen = 1;
}
}
-# endif
+#endif
if (!custom_ext_add(s, 1, &ret, limit, al))
return NULL;
-# ifdef TLSEXT_TYPE_encrypt_then_mac
+#ifdef TLSEXT_TYPE_encrypt_then_mac
if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) {
/*
* Don't use encrypt_then_mac if AEAD or RC4 might want to disable
s2n(0, ret);
}
}
-# endif
+#endif
+ if (!s->hit && s->session->flags & SSL_SESS_FLAG_EXTMS) {
+ s2n(TLSEXT_TYPE_extended_master_secret, ret);
+ s2n(0, ret);
+ }
if (s->s3->alpn_selected) {
const unsigned char *selected = s->s3->alpn_selected;
r = s->ctx->alpn_select_cb(s, &selected, &selected_len, data, data_len,
s->ctx->alpn_select_cb_arg);
if (r == SSL_TLSEXT_ERR_OK) {
- if (s->s3->alpn_selected)
- OPENSSL_free(s->s3->alpn_selected);
+ OPENSSL_free(s->s3->alpn_selected);
s->s3->alpn_selected = OPENSSL_malloc(selected_len);
if (!s->s3->alpn_selected) {
*al = SSL_AD_INTERNAL_ERROR;
return -1;
}
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
/*-
* ssl_check_for_safari attempts to fingerprint Safari using OS X
* SecureTransport using the TLS extension block in |d|, of length |n|.
s->s3->is_probably_safari = 1;
}
-# endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_EC */
static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
unsigned char *d, int n, int *al)
s->servername_done = 0;
s->tlsext_status_type = -1;
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
s->s3->next_proto_neg_seen = 0;
-# endif
+#endif
- if (s->s3->alpn_selected) {
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
- }
-# ifndef OPENSSL_NO_HEARTBEATS
+ OPENSSL_free(s->s3->alpn_selected);
+ s->s3->alpn_selected = NULL;
+#ifndef OPENSSL_NO_HEARTBEATS
s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
-# endif
+#endif
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
ssl_check_for_safari(s, data, d, n);
-# endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_EC */
/* Clear any signature algorithms extension received */
- if (s->cert->peer_sigalgs) {
- OPENSSL_free(s->cert->peer_sigalgs);
- s->cert->peer_sigalgs = NULL;
- }
-# ifdef TLSEXT_TYPE_encrypt_then_mac
+ OPENSSL_free(s->s3->tmp.peer_sigalgs);
+ s->s3->tmp.peer_sigalgs = NULL;
+#ifdef TLSEXT_TYPE_encrypt_then_mac
s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-# endif
+#endif
-# ifndef OPENSSL_NO_SRP
- if (s->srp_ctx.login != NULL) {
- OPENSSL_free(s->srp_ctx.login);
- s->srp_ctx.login = NULL;
- }
-# endif
+#ifndef OPENSSL_NO_SRP
+ OPENSSL_free(s->srp_ctx.login);
+ s->srp_ctx.login = NULL;
+#endif
s->srtp_profile = NULL;
- if (data >= (d + n - 2))
+ if (data == d + n)
goto ri_check;
+
+ if (data > (d + n - 2))
+ goto err;
+
n2s(data, len);
if (data > (d + n - len))
- goto ri_check;
+ goto err;
while (data <= (d + n - 4)) {
n2s(data, type);
n2s(data, size);
if (data + size > (d + n))
- goto ri_check;
-# if 0
- fprintf(stderr, "Received extension type %d size %d\n", type, size);
-# endif
+ goto err;
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
if (type == TLSEXT_TYPE_renegotiate) {
int servname_type;
int dsize;
- if (size < 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (size < 2)
+ goto err;
n2s(data, dsize);
size -= 2;
- if (dsize > size) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize > size)
+ goto err;
sdata = data;
while (dsize > 3) {
n2s(sdata, len);
dsize -= 3;
- if (len > dsize) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (len > dsize)
+ goto err;
+
if (s->servername_done == 0)
switch (servname_type) {
case TLSEXT_NAMETYPE_host_name:
if (!s->hit) {
- if (s->session->tlsext_hostname) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (s->session->tlsext_hostname)
+ goto err;
+
if (len > TLSEXT_MAXLEN_host_name) {
*al = TLS1_AD_UNRECOGNIZED_NAME;
return 0;
dsize -= len;
}
- if (dsize != 0) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize != 0)
+ goto err;
}
-# ifndef OPENSSL_NO_SRP
+#ifndef OPENSSL_NO_SRP
else if (type == TLSEXT_TYPE_srp) {
- if (size <= 0 || ((len = data[0])) != (size - 1)) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- if (s->srp_ctx.login != NULL) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (size == 0 || ((len = data[0])) != (size - 1))
+ goto err;
+ if (s->srp_ctx.login != NULL)
+ goto err;
if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
return -1;
memcpy(s->srp_ctx.login, &data[1], len);
s->srp_ctx.login[len] = '\0';
- if (strlen(s->srp_ctx.login) != len) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (strlen(s->srp_ctx.login) != len)
+ goto err;
}
-# endif
+#endif
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
else if (type == TLSEXT_TYPE_ec_point_formats) {
unsigned char *sdata = data;
int ecpointformatlist_length = *(sdata++);
if (ecpointformatlist_length != size - 1 ||
- ecpointformatlist_length < 1) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
+ ecpointformatlist_length < 1)
+ goto err;
if (!s->hit) {
- if (s->session->tlsext_ecpointformatlist) {
- OPENSSL_free(s->session->tlsext_ecpointformatlist);
- s->session->tlsext_ecpointformatlist = NULL;
- }
+ OPENSSL_free(s->session->tlsext_ecpointformatlist);
+ s->session->tlsext_ecpointformatlist = NULL;
s->session->tlsext_ecpointformatlist_length = 0;
if ((s->session->tlsext_ecpointformatlist =
OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
memcpy(s->session->tlsext_ecpointformatlist, sdata,
ecpointformatlist_length);
}
-# if 0
- fprintf(stderr,
- "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ",
- s->session->tlsext_ecpointformatlist_length);
- sdata = s->session->tlsext_ecpointformatlist;
- for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
- fprintf(stderr, "%i ", *(sdata++));
- fprintf(stderr, "\n");
-# endif
} else if (type == TLSEXT_TYPE_elliptic_curves) {
unsigned char *sdata = data;
int ellipticcurvelist_length = (*(sdata++) << 8);
if (ellipticcurvelist_length != size - 2 ||
ellipticcurvelist_length < 1 ||
/* Each NamedCurve is 2 bytes. */
- ellipticcurvelist_length & 1) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
+ ellipticcurvelist_length & 1)
+ goto err;
+
if (!s->hit) {
- if (s->session->tlsext_ellipticcurvelist) {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
+ if (s->session->tlsext_ellipticcurvelist)
+ goto err;
+
s->session->tlsext_ellipticcurvelist_length = 0;
if ((s->session->tlsext_ellipticcurvelist =
OPENSSL_malloc(ellipticcurvelist_length)) == NULL) {
memcpy(s->session->tlsext_ellipticcurvelist, sdata,
ellipticcurvelist_length);
}
-# if 0
- fprintf(stderr,
- "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ",
- s->session->tlsext_ellipticcurvelist_length);
- sdata = s->session->tlsext_ellipticcurvelist;
- for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
- fprintf(stderr, "%i ", *(sdata++));
- fprintf(stderr, "\n");
-# endif
}
-# endif /* OPENSSL_NO_EC */
-# ifdef TLSEXT_TYPE_opaque_prf_input
- else if (type == TLSEXT_TYPE_opaque_prf_input) {
- unsigned char *sdata = data;
-
- if (size < 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(sdata, s->s3->client_opaque_prf_input_len);
- if (s->s3->client_opaque_prf_input_len != size - 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (s->s3->client_opaque_prf_input != NULL) {
- /* shouldn't really happen */
- OPENSSL_free(s->s3->client_opaque_prf_input);
- }
-
- /* dummy byte just to get non-NULL */
- if (s->s3->client_opaque_prf_input_len == 0)
- s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
- else
- s->s3->client_opaque_prf_input =
- BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
- if (s->s3->client_opaque_prf_input == NULL) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-# endif
+#endif /* OPENSSL_NO_EC */
else if (type == TLSEXT_TYPE_session_ticket) {
if (s->tls_session_ticket_ext_cb &&
!s->tls_session_ticket_ext_cb(s, data, size,
}
} else if (type == TLSEXT_TYPE_signature_algorithms) {
int dsize;
- if (s->cert->peer_sigalgs || size < 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (s->s3->tmp.peer_sigalgs || size < 2)
+ goto err;
n2s(data, dsize);
size -= 2;
- if (dsize != size || dsize & 1 || !dsize) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- if (!tls1_save_sigalgs(s, data, dsize)) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize != size || dsize & 1 || !dsize)
+ goto err;
+ if (!tls1_save_sigalgs(s, data, dsize))
+ goto err;
} else if (type == TLSEXT_TYPE_status_request) {
- if (size < 5) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (size < 5)
+ goto err;
s->tlsext_status_type = *data++;
size--;
/* Read in responder_id_list */
n2s(data, dsize);
size -= 2;
- if (dsize > size) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize > size)
+ goto err;
while (dsize > 0) {
OCSP_RESPID *id;
int idsize;
- if (dsize < 4) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize < 4)
+ goto err;
n2s(data, idsize);
dsize -= 2 + idsize;
size -= 2 + idsize;
- if (dsize < 0) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize < 0)
+ goto err;
sdata = data;
data += idsize;
id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
- if (!id) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (!id)
+ goto err;
if (data != sdata) {
OCSP_RESPID_free(id);
- *al = SSL_AD_DECODE_ERROR;
- return 0;
+ goto err;
}
if (!s->tlsext_ocsp_ids
&& !(s->tlsext_ocsp_ids =
}
/* Read in request_extensions */
- if (size < 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (size < 2)
+ goto err;
n2s(data, dsize);
size -= 2;
- if (dsize != size) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (dsize != size)
+ goto err;
sdata = data;
if (dsize > 0) {
- if (s->tlsext_ocsp_exts) {
- sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
- X509_EXTENSION_free);
- }
-
+ sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
+ X509_EXTENSION_free);
s->tlsext_ocsp_exts =
d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
- if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (!s->tlsext_ocsp_exts || (data + dsize != sdata))
+ goto err;
}
}
/*
else
s->tlsext_status_type = -1;
}
-# ifndef OPENSSL_NO_HEARTBEATS
+#ifndef OPENSSL_NO_HEARTBEATS
else if (type == TLSEXT_TYPE_heartbeat) {
switch (data[0]) {
case 0x01: /* Client allows us to send HB requests */
return 0;
}
}
-# endif
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
else if (type == TLSEXT_TYPE_next_proto_neg &&
s->s3->tmp.finish_md_len == 0 &&
s->s3->alpn_selected == NULL) {
*/
s->s3->next_proto_neg_seen = 1;
}
-# endif
+#endif
else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
s->ctx->alpn_select_cb && s->s3->tmp.finish_md_len == 0) {
if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
return 0;
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
/* ALPN takes precedence over NPN. */
s->s3->next_proto_neg_seen = 0;
-# endif
+#endif
}
/* session ticket processed earlier */
-# ifndef OPENSSL_NO_SRTP
+#ifndef OPENSSL_NO_SRTP
else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
&& type == TLSEXT_TYPE_use_srtp) {
if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al))
return 0;
}
-# endif
-# ifdef TLSEXT_TYPE_encrypt_then_mac
+#endif
+#ifdef TLSEXT_TYPE_encrypt_then_mac
else if (type == TLSEXT_TYPE_encrypt_then_mac)
s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-# endif
+#endif
+ else if (type == TLSEXT_TYPE_extended_master_secret) {
+ if (!s->hit)
+ s->session->flags |= SSL_SESS_FLAG_EXTMS;
+ }
/*
* If this ClientHello extension was unhandled and this is a
* nonresumed connection, check whether the extension is a custom
data += size;
}
+ /* Spurious data on the end */
+ if (data != d + n)
+ goto err;
+
*p = data;
ri_check:
}
return 1;
+err:
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
}
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
return 1;
}
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
* elements of zero length are allowed and the set of elements must exactly
return off == len;
}
-# endif
+#endif
static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
unsigned char *d, int n, int *al)
int tlsext_servername = 0;
int renegotiate_seen = 0;
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
s->s3->next_proto_neg_seen = 0;
-# endif
+#endif
s->tlsext_ticket_expected = 0;
- if (s->s3->alpn_selected) {
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
- }
-# ifndef OPENSSL_NO_HEARTBEATS
+ OPENSSL_free(s->s3->alpn_selected);
+ s->s3->alpn_selected = NULL;
+#ifndef OPENSSL_NO_HEARTBEATS
s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
-# endif
+#endif
-# ifdef TLSEXT_TYPE_encrypt_then_mac
+#ifdef TLSEXT_TYPE_encrypt_then_mac
s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-# endif
+#endif
if (data >= (d + n - 2))
goto ri_check;
}
tlsext_servername = 1;
}
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
else if (type == TLSEXT_TYPE_ec_point_formats) {
unsigned char *sdata = data;
int ecpointformatlist_length = *(sdata++);
}
if (!s->hit) {
s->session->tlsext_ecpointformatlist_length = 0;
- if (s->session->tlsext_ecpointformatlist != NULL)
- OPENSSL_free(s->session->tlsext_ecpointformatlist);
+ OPENSSL_free(s->session->tlsext_ecpointformatlist);
if ((s->session->tlsext_ecpointformatlist =
OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
*al = TLS1_AD_INTERNAL_ERROR;
memcpy(s->session->tlsext_ecpointformatlist, sdata,
ecpointformatlist_length);
}
-# if 0
- fprintf(stderr,
- "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
- sdata = s->session->tlsext_ecpointformatlist;
- for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
- fprintf(stderr, "%i ", *(sdata++));
- fprintf(stderr, "\n");
-# endif
}
-# endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_EC */
else if (type == TLSEXT_TYPE_session_ticket) {
if (s->tls_session_ticket_ext_cb &&
}
s->tlsext_ticket_expected = 1;
}
-# ifdef TLSEXT_TYPE_opaque_prf_input
- else if (type == TLSEXT_TYPE_opaque_prf_input) {
- unsigned char *sdata = data;
-
- if (size < 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(sdata, s->s3->server_opaque_prf_input_len);
- if (s->s3->server_opaque_prf_input_len != size - 2) {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (s->s3->server_opaque_prf_input != NULL) {
- /* shouldn't really happen */
- OPENSSL_free(s->s3->server_opaque_prf_input);
- }
- if (s->s3->server_opaque_prf_input_len == 0) {
- /* dummy byte just to get non-NULL */
- s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
- } else {
- s->s3->server_opaque_prf_input =
- BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
- }
-
- if (s->s3->server_opaque_prf_input == NULL) {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-# endif
else if (type == TLSEXT_TYPE_status_request) {
/*
* MUST be empty and only sent if we've requested a status
/* Set flag to expect CertificateStatus message */
s->tlsext_status_expected = 1;
}
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
else if (type == TLSEXT_TYPE_next_proto_neg &&
s->s3->tmp.finish_md_len == 0) {
unsigned char *selected;
s->next_proto_negotiated_len = selected_len;
s->s3->next_proto_neg_seen = 1;
}
-# endif
+#endif
else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
unsigned len;
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
- if (s->s3->alpn_selected)
- OPENSSL_free(s->s3->alpn_selected);
+ OPENSSL_free(s->s3->alpn_selected);
s->s3->alpn_selected = OPENSSL_malloc(len);
if (!s->s3->alpn_selected) {
*al = TLS1_AD_INTERNAL_ERROR;
memcpy(s->s3->alpn_selected, data + 3, len);
s->s3->alpn_selected_len = len;
}
-# ifndef OPENSSL_NO_HEARTBEATS
+#ifndef OPENSSL_NO_HEARTBEATS
else if (type == TLSEXT_TYPE_heartbeat) {
switch (data[0]) {
case 0x01: /* Server allows us to send HB requests */
return 0;
}
}
-# endif
-# ifndef OPENSSL_NO_SRTP
+#endif
+#ifndef OPENSSL_NO_SRTP
else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al))
return 0;
}
-# endif
-# ifdef TLSEXT_TYPE_encrypt_then_mac
+#endif
+#ifdef TLSEXT_TYPE_encrypt_then_mac
else if (type == TLSEXT_TYPE_encrypt_then_mac) {
/* Ignore if inappropriate ciphersuite */
if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
&& s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
}
-# endif
+#endif
+ else if (type == TLSEXT_TYPE_extended_master_secret) {
+ if (!s->hit)
+ s->session->flags |= SSL_SESS_FLAG_EXTMS;
+ }
/*
* If this extension type was not otherwise handled, but matches a
* custom_cli_ext_record, then send it to the c callback
int ssl_prepare_clienthello_tlsext(SSL *s)
{
-# ifdef TLSEXT_TYPE_opaque_prf_input
- {
- int r = 1;
-
- if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
- r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
- s->
- ctx->tlsext_opaque_prf_input_callback_arg);
- if (!r)
- return -1;
- }
-
- if (s->tlsext_opaque_prf_input != NULL) {
- if (s->s3->client_opaque_prf_input != NULL) {
- /* shouldn't really happen */
- OPENSSL_free(s->s3->client_opaque_prf_input);
- }
-
- if (s->tlsext_opaque_prf_input_len == 0) {
- /* dummy byte just to get non-NULL */
- s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
- } else {
- s->s3->client_opaque_prf_input =
- BUF_memdup(s->tlsext_opaque_prf_input,
- s->tlsext_opaque_prf_input_len);
- }
- if (s->s3->client_opaque_prf_input == NULL) {
- SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,
- ERR_R_MALLOC_FAILURE);
- return -1;
- }
- s->s3->client_opaque_prf_input_len =
- s->tlsext_opaque_prf_input_len;
- }
-
- if (r == 2)
- /*
- * at callback's request, insist on receiving an appropriate
- * server opaque PRF input
- */
- s->s3->server_opaque_prf_input_len =
- s->tlsext_opaque_prf_input_len;
- }
-# endif
-
return 1;
}
int ret = SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
/*
* The handling of the ECPointFormats extension is done elsewhere, namely
* in ssl3_choose_cipher in s3_lib.c.
* The handling of the EllipticCurves extension is done elsewhere, namely
* in ssl3_choose_cipher in s3_lib.c.
*/
-# endif
+#endif
if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
ret =
s->
initial_ctx->tlsext_servername_arg);
-# ifdef TLSEXT_TYPE_opaque_prf_input
- {
- /*
- * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we
- * might be sending an alert in response to the client hello, so this
- * has to happen here in ssl_check_clienthello_tlsext_early().
- */
-
- int r = 1;
-
- if (s->ctx->tlsext_opaque_prf_input_callback != 0) {
- r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0,
- s->
- ctx->tlsext_opaque_prf_input_callback_arg);
- if (!r) {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- }
-
- if (s->s3->server_opaque_prf_input != NULL) {
- /* shouldn't really happen */
- OPENSSL_free(s->s3->server_opaque_prf_input);
- }
- s->s3->server_opaque_prf_input = NULL;
-
- if (s->tlsext_opaque_prf_input != NULL) {
- if (s->s3->client_opaque_prf_input != NULL &&
- s->s3->client_opaque_prf_input_len ==
- s->tlsext_opaque_prf_input_len) {
- /*
- * can only use this extension if we have a server opaque PRF
- * input of the same length as the client opaque PRF input!
- */
-
- if (s->tlsext_opaque_prf_input_len == 0) {
- /* dummy byte just to get non-NULL */
- s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
- } else {
- s->s3->server_opaque_prf_input =
- BUF_memdup(s->tlsext_opaque_prf_input,
- s->tlsext_opaque_prf_input_len);
- }
- if (s->s3->server_opaque_prf_input == NULL) {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- s->s3->server_opaque_prf_input_len =
- s->tlsext_opaque_prf_input_len;
- }
- }
-
- if (r == 2 && s->s3->server_opaque_prf_input == NULL) {
- /*
- * The callback wants to enforce use of the extension, but we
- * can't do that with the client opaque PRF input; abort the
- * handshake.
- */
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_HANDSHAKE_FAILURE;
- }
- }
-
- err:
-# endif
switch (ret) {
case SSL_TLSEXT_ERR_ALERT_FATAL:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
return 1;
}
}
+/* Initialise digests to default values */
+static void ssl_set_default_md(SSL *s)
+{
+ const EVP_MD **pmd = s->s3->tmp.md;
+#ifndef OPENSSL_NO_DSA
+ pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_RSA
+ pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1();
+ pmd[SSL_PKEY_RSA_ENC] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_EC
+ pmd[SSL_PKEY_ECC] = EVP_sha1();
+#endif
+}
int tls1_set_server_sigalgs(SSL *s)
{
int al;
size_t i;
/* Clear any shared sigtnature algorithms */
- if (s->cert->shared_sigalgs) {
- OPENSSL_free(s->cert->shared_sigalgs);
- s->cert->shared_sigalgs = NULL;
- }
+ OPENSSL_free(s->cert->shared_sigalgs);
+ s->cert->shared_sigalgs = NULL;
+ s->cert->shared_sigalgslen = 0;
/* Clear certificate digests and validity flags */
for (i = 0; i < SSL_PKEY_NUM; i++) {
- s->cert->pkeys[i].digest = NULL;
- s->cert->pkeys[i].valid_flags = 0;
+ s->s3->tmp.md[i] = NULL;
+ s->s3->tmp.valid_flags[i] = 0;
}
/* If sigalgs received process it. */
- if (s->cert->peer_sigalgs) {
+ if (s->s3->tmp.peer_sigalgs) {
if (!tls1_process_sigalgs(s)) {
SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
al = SSL_AD_INTERNAL_ERROR;
al = SSL_AD_ILLEGAL_PARAMETER;
goto err;
}
- } else
- ssl_cert_set_default_md(s->cert);
+ } else {
+ ssl_set_default_md(s);
+ }
return 1;
err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
int ssl_check_clienthello_tlsext_late(SSL *s)
{
int ret = SSL_TLSEXT_ERR_OK;
- int al;
+ int al = SSL_AD_INTERNAL_ERROR;
/*
* If status request then ask callback what to do. Note: this must be
int ret = SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
/*
* If we are client and using an elliptic curve cryptography cipher
* suite, then if server returns an EC point formats lists extension it
}
}
ret = SSL_TLSEXT_ERR_OK;
-# endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_EC */
if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
ret =
s->
initial_ctx->tlsext_servername_arg);
-# ifdef TLSEXT_TYPE_opaque_prf_input
- if (s->s3->server_opaque_prf_input_len > 0) {
- /*
- * This case may indicate that we, as a client, want to insist on
- * using opaque PRF inputs. So first verify that we really have a
- * value from the server too.
- */
-
- if (s->s3->server_opaque_prf_input == NULL) {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_HANDSHAKE_FAILURE;
- }
-
- /*
- * Anytime the server *has* sent an opaque PRF input, we need to
- * check that we have a client opaque PRF input of the same size.
- */
- if (s->s3->client_opaque_prf_input == NULL ||
- s->s3->client_opaque_prf_input_len !=
- s->s3->server_opaque_prf_input_len) {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_ILLEGAL_PARAMETER;
- }
- }
-# endif
-
/*
* If we've requested certificate status and we wont get one tell the
* callback
* Set resp to NULL, resplen to -1 so callback knows there is no
* response.
*/
- if (s->tlsext_ocsp_resp) {
- OPENSSL_free(s->tlsext_ocsp_resp);
- s->tlsext_ocsp_resp = NULL;
- }
+ OPENSSL_free(s->tlsext_ocsp_resp);
+ s->tlsext_ocsp_resp = NULL;
s->tlsext_ocsp_resplen = -1;
r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
if (r == 0) {
int sig_id, md_id;
if (!md)
return 0;
- md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
+ md_id = tls12_find_id(EVP_MD_type(md), tls12_md, OSSL_NELEM(tls12_md));
if (md_id == -1)
return 0;
sig_id = tls12_get_sigid(pk);
int tls12_get_sigid(const EVP_PKEY *pk)
{
- return tls12_find_id(pk->type, tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
+ return tls12_find_id(pk->type, tls12_sig, OSSL_NELEM(tls12_sig));
}
typedef struct {
} tls12_hash_info;
static const tls12_hash_info tls12_md_info[] = {
-# ifdef OPENSSL_NO_MD5
+#ifdef OPENSSL_NO_MD5
{NID_md5, 64, 0},
-# else
+#else
{NID_md5, 64, EVP_md5},
-# endif
+#endif
{NID_sha1, 80, EVP_sha1},
{NID_sha224, 112, EVP_sha224},
{NID_sha256, 128, EVP_sha256},
{
if (hash_alg == 0)
return NULL;
- if (hash_alg > sizeof(tls12_md_info) / sizeof(tls12_md_info[0]))
+ if (hash_alg > OSSL_NELEM(tls12_md_info))
return NULL;
return tls12_md_info + hash_alg - 1;
}
static int tls12_get_pkey_idx(unsigned char sig_alg)
{
switch (sig_alg) {
-# ifndef OPENSSL_NO_RSA
+#ifndef OPENSSL_NO_RSA
case TLSEXT_signature_rsa:
return SSL_PKEY_RSA_SIGN;
-# endif
-# ifndef OPENSSL_NO_DSA
+#endif
+#ifndef OPENSSL_NO_DSA
case TLSEXT_signature_dsa:
return SSL_PKEY_DSA_SIGN;
-# endif
-# ifndef OPENSSL_NO_ECDSA
+#endif
+#ifndef OPENSSL_NO_EC
case TLSEXT_signature_ecdsa:
return SSL_PKEY_ECC;
-# endif
+#endif
}
return -1;
}
if (!phash_nid && !psign_nid && !psignhash_nid)
return;
if (phash_nid || psignhash_nid) {
- hash_nid = tls12_find_nid(data[0], tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
+ hash_nid = tls12_find_nid(data[0], tls12_md, OSSL_NELEM(tls12_md));
if (phash_nid)
*phash_nid = hash_nid;
}
if (psign_nid || psignhash_nid) {
- sign_nid = tls12_find_nid(data[1], tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
+ sign_nid = tls12_find_nid(data[1], tls12_sig, OSSL_NELEM(tls12_sig));
if (psign_nid)
*psign_nid = sign_nid;
}
sigalgslen = tls12_get_psigalgs(s, &sigalgs);
for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
switch (sigalgs[1]) {
-# ifndef OPENSSL_NO_RSA
+#ifndef OPENSSL_NO_RSA
case TLSEXT_signature_rsa:
if (!have_rsa && tls12_sigalg_allowed(s, op, sigalgs))
have_rsa = 1;
break;
-# endif
-# ifndef OPENSSL_NO_DSA
+#endif
+#ifndef OPENSSL_NO_DSA
case TLSEXT_signature_dsa:
if (!have_dsa && tls12_sigalg_allowed(s, op, sigalgs))
have_dsa = 1;
break;
-# endif
-# ifndef OPENSSL_NO_ECDSA
+#endif
+#ifndef OPENSSL_NO_EC
case TLSEXT_signature_ecdsa:
if (!have_ecdsa && tls12_sigalg_allowed(s, op, sigalgs))
have_ecdsa = 1;
break;
-# endif
+#endif
}
}
if (!have_rsa)
TLS_SIGALGS *salgs = NULL;
CERT *c = s->cert;
unsigned int is_suiteb = tls1_suiteb(s);
- if (c->shared_sigalgs) {
- OPENSSL_free(c->shared_sigalgs);
- c->shared_sigalgs = NULL;
- }
+
+ OPENSSL_free(c->shared_sigalgs);
+ c->shared_sigalgs = NULL;
+ c->shared_sigalgslen = 0;
/* If client use client signature algorithms if not NULL */
if (!s->server && c->client_sigalgs && !is_suiteb) {
conf = c->client_sigalgs;
if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
pref = conf;
preflen = conflen;
- allow = c->peer_sigalgs;
- allowlen = c->peer_sigalgslen;
+ allow = s->s3->tmp.peer_sigalgs;
+ allowlen = s->s3->tmp.peer_sigalgslen;
} else {
allow = conf;
allowlen = conflen;
- pref = c->peer_sigalgs;
- preflen = c->peer_sigalgslen;
+ pref = s->s3->tmp.peer_sigalgs;
+ preflen = s->s3->tmp.peer_sigalgslen;
}
nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
- if (!nmatch)
- return 1;
- salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
- if (!salgs)
- return 0;
- nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
+ if (nmatch) {
+ salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
+ if (!salgs)
+ return 0;
+ nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
+ } else {
+ salgs = NULL;
+ }
c->shared_sigalgs = salgs;
c->shared_sigalgslen = nmatch;
return 1;
if (!c)
return 0;
- if (c->peer_sigalgs)
- OPENSSL_free(c->peer_sigalgs);
- c->peer_sigalgs = OPENSSL_malloc(dsize);
- if (!c->peer_sigalgs)
+ OPENSSL_free(s->s3->tmp.peer_sigalgs);
+ s->s3->tmp.peer_sigalgs = OPENSSL_malloc(dsize);
+ if (s->s3->tmp.peer_sigalgs == NULL)
return 0;
- c->peer_sigalgslen = dsize;
- memcpy(c->peer_sigalgs, data, dsize);
+ s->s3->tmp.peer_sigalgslen = dsize;
+ memcpy(s->s3->tmp.peer_sigalgs, data, dsize);
return 1;
}
int idx;
size_t i;
const EVP_MD *md;
+ const EVP_MD **pmd = s->s3->tmp.md;
+ int *pvalid = s->s3->tmp.valid_flags;
CERT *c = s->cert;
TLS_SIGALGS *sigptr;
if (!tls1_set_shared_sigalgs(s))
return 0;
-# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
/*
* Use first set signature preference to force message digest,
if (sigs) {
idx = tls12_get_pkey_idx(sigs[1]);
md = tls12_get_hash(sigs[0]);
- c->pkeys[idx].digest = md;
- c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
+ pmd[idx] = md;
+ pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
if (idx == SSL_PKEY_RSA_SIGN) {
- c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
- CERT_PKEY_EXPLICIT_SIGN;
- c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
+ pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN;
+ pmd[SSL_PKEY_RSA_ENC] = md;
}
}
}
-# endif
+#endif
for (i = 0, sigptr = c->shared_sigalgs;
i < c->shared_sigalgslen; i++, sigptr++) {
idx = tls12_get_pkey_idx(sigptr->rsign);
- if (idx > 0 && c->pkeys[idx].digest == NULL) {
+ if (idx > 0 && pmd[idx] == NULL) {
md = tls12_get_hash(sigptr->rhash);
- c->pkeys[idx].digest = md;
- c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
+ pmd[idx] = md;
+ pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
if (idx == SSL_PKEY_RSA_SIGN) {
- c->pkeys[SSL_PKEY_RSA_ENC].valid_flags =
- CERT_PKEY_EXPLICIT_SIGN;
- c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
+ pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN;
+ pmd[SSL_PKEY_RSA_ENC] = md;
}
}
* Set any remaining keys to default values. NOTE: if alg is not
* supported it stays as NULL.
*/
-# ifndef OPENSSL_NO_DSA
- if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
- c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
-# endif
-# ifndef OPENSSL_NO_RSA
- if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
- c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
- c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
+#ifndef OPENSSL_NO_DSA
+ if (pmd[SSL_PKEY_DSA_SIGN] == NULL)
+ pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_RSA
+ if (pmd[SSL_PKEY_RSA_SIGN] == NULL) {
+ pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1();
+ pmd[SSL_PKEY_RSA_ENC] = EVP_sha1();
}
-# endif
-# ifndef OPENSSL_NO_ECDSA
- if (!c->pkeys[SSL_PKEY_ECC].digest)
- c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
-# endif
+#endif
+#ifndef OPENSSL_NO_EC
+ if (pmd[SSL_PKEY_ECC] == NULL)
+ pmd[SSL_PKEY_ECC] = EVP_sha1();
+#endif
}
return 1;
}
int *psign, int *phash, int *psignhash,
unsigned char *rsig, unsigned char *rhash)
{
- const unsigned char *psig = s->cert->peer_sigalgs;
+ const unsigned char *psig = s->s3->tmp.peer_sigalgs;
if (psig == NULL)
return 0;
if (idx >= 0) {
idx <<= 1;
- if (idx >= (int)s->cert->peer_sigalgslen)
+ if (idx >= (int)s->s3->tmp.peer_sigalgslen)
return 0;
psig += idx;
if (rhash)
*rsig = psig[1];
tls1_lookup_sigalg(phash, psign, psignhash, psig);
}
- return s->cert->peer_sigalgslen / 2;
+ return s->s3->tmp.peer_sigalgslen / 2;
}
int SSL_get_shared_sigalgs(SSL *s, int idx,
return s->cert->shared_sigalgslen;
}
-# ifndef OPENSSL_NO_HEARTBEATS
-int tls1_process_heartbeat(SSL *s)
+#ifndef OPENSSL_NO_HEARTBEATS
+int tls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
{
- unsigned char *p = &s->s3->rrec.data[0], *pl;
+ unsigned char *pl;
unsigned short hbtype;
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */
if (s->msg_callback)
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
- &s->s3->rrec.data[0], s->s3->rrec.length,
+ p, length,
s, s->msg_callback_arg);
/* Read type and payload length first */
- if (1 + 2 + 16 > s->s3->rrec.length)
+ if (1 + 2 + 16 > length)
return 0; /* silently discard */
hbtype = *p++;
n2s(p, payload);
- if (1 + 2 + payload + 16 > s->s3->rrec.length)
+ if (1 + 2 + payload + 16 > length)
return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;
memcpy(bp, pl, payload);
bp += payload;
/* Random padding */
- RAND_pseudo_bytes(bp, padding);
+ if (RAND_bytes(bp, padding) <= 0) {
+ OPENSSL_free(buffer);
+ return -1;
+ }
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
3 + payload + padding);
int tls1_heartbeat(SSL *s)
{
unsigned char *buf, *p;
- int ret;
+ int ret = -1;
unsigned int payload = 18; /* Sequence number + random bytes */
unsigned int padding = 16; /* Use minimum padding */
/* Sequence number */
s2n(s->tlsext_hb_seq, p);
/* 16 random bytes */
- RAND_pseudo_bytes(p, 16);
+ if (RAND_bytes(p, 16) <= 0) {
+ SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
p += 16;
/* Random padding */
- RAND_pseudo_bytes(p, padding);
+ if (RAND_bytes(p, padding) <= 0) {
+ SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
if (ret >= 0) {
s->tlsext_hb_pending = 1;
}
+ err:
OPENSSL_free(buf);
-
return ret;
}
-# endif
+#endif
-# define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2)
+#define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2)
typedef struct {
size_t sigalgcnt;
if (!*p)
return 0;
- if (!strcmp(etmp, "RSA"))
+ if (strcmp(etmp, "RSA") == 0)
sig_alg = EVP_PKEY_RSA;
- else if (!strcmp(etmp, "DSA"))
+ else if (strcmp(etmp, "DSA") == 0)
sig_alg = EVP_PKEY_DSA;
- else if (!strcmp(etmp, "ECDSA"))
+ else if (strcmp(etmp, "ECDSA") == 0)
sig_alg = EVP_PKEY_EC;
else
return 0;
if (sigalgs == NULL)
return 0;
for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
- rhash = tls12_find_id(*psig_nids++, tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
- rsign = tls12_find_id(*psig_nids++, tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
+ rhash = tls12_find_id(*psig_nids++, tls12_md, OSSL_NELEM(tls12_md));
+ rsign = tls12_find_id(*psig_nids++, tls12_sig, OSSL_NELEM(tls12_sig));
if (rhash == -1 || rsign == -1)
goto err;
}
if (client) {
- if (c->client_sigalgs)
- OPENSSL_free(c->client_sigalgs);
+ OPENSSL_free(c->client_sigalgs);
c->client_sigalgs = sigalgs;
c->client_sigalgslen = salglen;
} else {
- if (c->conf_sigalgs)
- OPENSSL_free(c->conf_sigalgs);
+ OPENSSL_free(c->conf_sigalgs);
c->conf_sigalgs = sigalgs;
c->conf_sigalgslen = salglen;
}
/* Flags which need to be set for a certificate when stict mode not set */
-# define CERT_PKEY_VALID_FLAGS \
+#define CERT_PKEY_VALID_FLAGS \
(CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
/* Strict mode flags */
-# define CERT_PKEY_STRICT_FLAGS \
+#define CERT_PKEY_STRICT_FLAGS \
(CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
| CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
int check_flags = 0, strict_mode;
CERT_PKEY *cpk = NULL;
CERT *c = s->cert;
+ int *pvalid;
unsigned int suiteb_flags = tls1_suiteb(s);
/* idx == -1 means checking server chains */
if (idx != -1) {
idx = cpk - c->pkeys;
} else
cpk = c->pkeys + idx;
+ pvalid = s->s3->tmp.valid_flags + idx;
x = cpk->x509;
pk = cpk->privatekey;
chain = cpk->chain;
/* If no cert or key, forget it */
if (!x || !pk)
goto end;
-# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
/* Allow any certificate to pass test */
if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) {
rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN |
CERT_PKEY_VALID | CERT_PKEY_SIGN;
- cpk->valid_flags = rv;
+ *pvalid = rv;
return rv;
}
-# endif
+#endif
} else {
if (!x || !pk)
- goto end;
+ return 0;
idx = ssl_cert_type(x, pk);
if (idx == -1)
- goto end;
+ return 0;
cpk = c->pkeys + idx;
+ pvalid = s->s3->tmp.valid_flags + idx;
+
if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
check_flags = CERT_PKEY_STRICT_FLAGS;
else
if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
int default_nid;
unsigned char rsign = 0;
- if (c->peer_sigalgs)
+ if (s->s3->tmp.peer_sigalgs)
default_nid = 0;
/* If no sigalgs extension use defaults from RFC5246 */
else {
end:
if (TLS1_get_version(s) >= TLS1_2_VERSION) {
- if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN)
+ if (*pvalid & CERT_PKEY_EXPLICIT_SIGN)
rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
- else if (cpk->digest)
+ else if (s->s3->tmp.md[idx] != NULL)
rv |= CERT_PKEY_SIGN;
} else
rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
*/
if (!check_flags) {
if (rv & CERT_PKEY_VALID)
- cpk->valid_flags = rv;
+ *pvalid = rv;
else {
/* Preserve explicit sign flag, clear rest */
- cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
+ *pvalid &= CERT_PKEY_EXPLICIT_SIGN;
return 0;
}
}
return tls1_check_chain(s, x, pk, chain, -1);
}
-#endif
#ifndef OPENSSL_NO_DH
DH *ssl_get_auto_dh(SSL *s)