#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#ifndef OPENSSL_NO_EC
#ifdef OPENSSL_NO_EC2M
# include <openssl/ec.h>
#endif
+#endif
#include <openssl/ocsp.h>
#include <openssl/rand.h>
#include "ssl_locl.h"
TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
};
-static const unsigned char eccurves_default[] = {
-# ifndef OPENSSL_NO_EC2M
- 0, 14, /* sect571r1 (14) */
- 0, 13, /* sect571k1 (13) */
-# endif
+/* 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, 27, /* brainpoolP384r1 (27) */
+ 0, 24, /* secp384r1 (24) */
+ 0, 26, /* brainpoolP256r1 (26) */
+ 0, 22, /* secp256k1 (22) */
# ifndef OPENSSL_NO_EC2M
+ /* >= 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) */
# endif
+};
+
+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) */
# ifndef OPENSSL_NO_EC2M
+ /* >= 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) */
# endif
- 0, 26, /* brainpoolP256r1 (26) */
- 0, 22, /* secp256k1 (22) */
- 0, 23, /* secp256r1 (23) */
+ /*
+ * 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) */
# ifndef OPENSSL_NO_EC2M
0, 8, /* sect239k1 (8) */
0, 6, /* sect233k1 (6) */
0, 7, /* sect233r1 (7) */
-# endif
- 0, 20, /* secp224k1 (20) */
- 0, 21, /* secp224r1 (21) */
-# ifndef OPENSSL_NO_EC2M
0, 4, /* sect193r1 (4) */
0, 5, /* sect193r2 (5) */
-# endif
- 0, 18, /* secp192k1 (18) */
- 0, 19, /* secp192r1 (19) */
-# ifndef OPENSSL_NO_EC2M
0, 1, /* sect163k1 (1) */
0, 2, /* sect163r1 (2) */
0, 3, /* sect163r2 (3) */
# endif
- 0, 15, /* secp160k1 (15) */
- 0, 16, /* secp160r1 (16) */
- 0, 17, /* secp160r2 (17) */
};
static const unsigned char suiteb_curves[] = {
} else
# endif
{
- *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);
+ }
}
}
}
(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;
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;
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;
+ goto err;
# if 0
fprintf(stderr, "Received extension type %d size %d\n", type, size);
# endif
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
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
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);
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) {
renegotiate_seen = 1;
} 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->cert->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) {
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;
}
}
/*
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;
}
/*
if (s->cert->shared_sigalgs) {
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++) {
if (c->shared_sigalgs) {
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) {
preflen = c->peer_sigalgslen;
}
nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
- if (!nmatch)
- return 1;
- salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
- if (!salgs)
- return 0;
- nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
+ if (nmatch) {
+ salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
+ if (!salgs)
+ return 0;
+ nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
+ } else {
+ salgs = NULL;
+ }
c->shared_sigalgs = salgs;
c->shared_sigalgslen = nmatch;
return 1;
memcpy(bp, pl, payload);
bp += payload;
/* Random padding */
- RAND_pseudo_bytes(bp, padding);
+ if (RAND_pseudo_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_pseudo_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_pseudo_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
} 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;
if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
check_flags = CERT_PKEY_STRICT_FLAGS;