-/* ssl/t1_lib.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
void tls1_clear(SSL *s)
{
ssl3_clear(s);
- s->version = s->method->version;
+ if (s->method->version == TLS_ANY_VERSION)
+ s->version = TLS_MAX_VERSION;
+ else
+ s->version = s->method->version;
}
#ifndef OPENSSL_NO_EC
unsigned char comp_id, curve_id[2];
EVP_PKEY *pkey;
int rv;
- pkey = X509_get_pubkey(x);
+ pkey = X509_get0_pubkey(x);
if (!pkey)
return 0;
/* If not EC nothing to do */
- if (pkey->type != EVP_PKEY_EC) {
- EVP_PKEY_free(pkey);
+ if (EVP_PKEY_id(pkey) != EVP_PKEY_EC)
return 1;
- }
- rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec);
- EVP_PKEY_free(pkey);
+ rv = tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey));
if (!rv)
return 0;
/*
return 0;
}
#ifndef OPENSSL_NO_EC
- if (pkey->type == EVP_PKEY_EC) {
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
unsigned char curve_id[2], comp_id;
/* Check compression and curve matches extensions */
- if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec))
+ if (!tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey)))
return 0;
if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
- SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+ const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
alg_k = c->algorithm_mkey;
alg_a = c->algorithm_auth;
i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
}
#ifndef OPENSSL_NO_HEARTBEATS
- /* Add Heartbeat extension */
- if ((limit - ret - 4 - 1) < 0)
- return NULL;
- s2n(TLSEXT_TYPE_heartbeat, ret);
- s2n(1, ret);
- /*-
- * Set mode:
- * 1: peer may send requests
- * 2: peer not allowed to send requests
- */
- if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
- *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
- else
- *(ret++) = SSL_TLSEXT_HB_ENABLED;
+ if (SSL_IS_DTLS(s)) {
+ /* Add Heartbeat extension */
+ if ((limit - ret - 4 - 1) < 0)
+ return NULL;
+ s2n(TLSEXT_TYPE_heartbeat, ret);
+ s2n(1, ret);
+ /*-
+ * Set mode:
+ * 1: peer may send requests
+ * 2: peer not allowed to send requests
+ */
+ if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
+ *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+ else
+ *(ret++) = SSL_DTLSEXT_HB_ENABLED;
+ }
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
}
#ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension if we've received one */
- if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
+ if (SSL_IS_DTLS(s) && (s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED)) {
if ((limit - ret - 4 - 1) < 0)
return NULL;
s2n(TLSEXT_TYPE_heartbeat, ret);
* 1: peer may send requests
* 2: peer not allowed to send requests
*/
- if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
- *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
+ *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
else
- *(ret++) = SSL_TLSEXT_HB_ENABLED;
+ *(ret++) = SSL_DTLSEXT_HB_ENABLED;
}
#endif
unsigned int data_len;
unsigned int proto_len;
const unsigned char *selected;
- unsigned char *data;
+ const unsigned char *data;
unsigned char selected_len;
int r;
static void ssl_check_for_safari(SSL *s, const PACKET *pkt)
{
unsigned int type, size;
- unsigned char *eblock1, *eblock2;
+ const unsigned char *eblock1, *eblock2;
PACKET tmppkt;
static const unsigned char kSafariExtensionsBlock[] = {
unsigned int type;
unsigned int size;
unsigned int len;
- unsigned char *data;
+ const unsigned char *data;
int renegotiate_seen = 0;
s->servername_done = 0;
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);
+ s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
+ SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
#endif
#ifndef OPENSSL_NO_EC
*/
else if (type == TLSEXT_TYPE_server_name) {
- unsigned char *sdata;
+ const unsigned char *sdata;
unsigned int servname_type;
unsigned int dsize;
PACKET ssubpkt;
s->tlsext_status_type = -1;
}
#ifndef OPENSSL_NO_HEARTBEATS
- else if (type == TLSEXT_TYPE_heartbeat) {
+ else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
unsigned int hbtype;
if (!PACKET_get_1(&subpkt, &hbtype)
}
switch (hbtype) {
case 0x01: /* Client allows us to send HB requests */
- s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+ s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
break;
case 0x02: /* Client doesn't accept HB requests */
- s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
- s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+ s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
break;
default:
*al = SSL_AD_ILLEGAL_PARAMETER;
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);
+ s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
+ SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
#endif
#ifdef TLSEXT_TYPE_encrypt_then_mac
}
while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) {
- unsigned char *data;
+ const unsigned char *data;
PACKET spkt;
if (!PACKET_get_sub_packet(pkt, &spkt, size)
s->s3->alpn_selected_len = len;
}
#ifndef OPENSSL_NO_HEARTBEATS
- else if (type == TLSEXT_TYPE_heartbeat) {
+ else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
unsigned int hbtype;
if (!PACKET_get_1(&spkt, &hbtype)) {
*al = SSL_AD_DECODE_ERROR;
}
switch (hbtype) {
case 0x01: /* Server allows us to send HB requests */
- s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
+ s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
break;
case 0x02: /* Server doesn't accept HB requests */
- s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
- s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
+ s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+ s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
break;
default:
*al = SSL_AD_ILLEGAL_PARAMETER;
s->
initial_ctx->tlsext_servername_arg);
+ /*
+ * Ensure we get sensible values passed to tlsext_status_cb in the event
+ * that we don't receive a status message
+ */
OPENSSL_free(s->tlsext_ocsp_resp);
s->tlsext_ocsp_resp = NULL;
s->tlsext_ocsp_resplen = -1;
- /*
- * If we've requested certificate status and we wont get one tell the
- * callback
- */
- if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
- && s->ctx && s->ctx->tlsext_status_cb) {
- int r;
- /*
- * Call callback with resp == NULL and resplen == -1 so callback
- * knows there is no response
- */
- r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
- if (r == 0) {
- al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- }
- if (r < 0) {
- al = SSL_AD_INTERNAL_ERROR;
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- }
- }
switch (ret) {
case SSL_TLSEXT_ERR_ALERT_FATAL:
}
if (type == TLSEXT_TYPE_session_ticket && use_ticket) {
int r;
- unsigned char *etick;
+ const unsigned char *etick;
/* Duplicate extension */
if (have_ticket != 0) {
int slen, mlen, renew_ticket = 0;
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
HMAC_CTX *hctx = NULL;
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
SSL_CTX *tctx = s->initial_ctx;
/* Need at least keyname + iv + some encrypted data */
if (eticklen < 48)
hctx = HMAC_CTX_new();
if (hctx == NULL)
return -2;
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
if (tctx->tlsext_ticket_key_cb) {
unsigned char *nctick = (unsigned char *)etick;
int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
- &ctx, hctx, 0);
+ ctx, hctx, 0);
if (rv < 0)
return -1;
if (rv == 0)
return 2;
if (HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, 16,
EVP_sha256(), NULL) <= 0
- || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ || EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL,
tctx->tlsext_tick_aes_key,
etick + 16) <= 0) {
goto err;
}
HMAC_CTX_free(hctx);
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return 2;
}
/* Attempt to decrypt session data */
/* Move p after IV to start of encrypted ticket, update length */
- p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+ p = etick + 16 + EVP_CIPHER_CTX_iv_length(ctx);
+ eticklen -= 16 + EVP_CIPHER_CTX_iv_length(ctx);
sdec = OPENSSL_malloc(eticklen);
if (sdec == NULL
- || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
- EVP_CIPHER_CTX_cleanup(&ctx);
+ || EVP_DecryptUpdate(ctx, sdec, &slen, p, eticklen) <= 0) {
+ EVP_CIPHER_CTX_free(ctx);
return -1;
}
- if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
- EVP_CIPHER_CTX_cleanup(&ctx);
+ if (EVP_DecryptFinal(ctx, sdec + slen, &mlen) <= 0) {
+ EVP_CIPHER_CTX_free(ctx);
OPENSSL_free(sdec);
return 2;
}
slen += mlen;
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
+ ctx = NULL;
p = sdec;
sess = d2i_SSL_SESSION(NULL, &p, slen);
*/
return 2;
err:
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
HMAC_CTX_free(hctx);
return -1;
}
int tls12_get_sigid(const EVP_PKEY *pk)
{
- return tls12_find_id(pk->type, tls12_sig, OSSL_NELEM(tls12_sig));
+ return tls12_find_id(EVP_PKEY_id(pk), tls12_sig, OSSL_NELEM(tls12_sig));
}
typedef struct {
return s->cert->shared_sigalgslen;
}
-#ifndef OPENSSL_NO_HEARTBEATS
-int tls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
-{
- 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,
- p, length,
- s, s->msg_callback_arg);
-
- /* Read type and payload length first */
- if (1 + 2 + 16 > length)
- return 0; /* silently discard */
- hbtype = *p++;
- n2s(p, payload);
- if (1 + 2 + payload + 16 > length)
- return 0; /* silently discard per RFC 6520 sec. 4 */
- pl = p;
-
- if (hbtype == TLS1_HB_REQUEST) {
- unsigned char *buffer, *bp;
- int r;
-
- /*
- * Allocate memory for the response, size is 1 bytes message type,
- * plus 2 bytes payload length, plus payload, plus padding
- */
- buffer = OPENSSL_malloc(1 + 2 + payload + padding);
- if (buffer == NULL) {
- SSLerr(SSL_F_TLS1_PROCESS_HEARTBEAT, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- bp = buffer;
-
- /* Enter response type, length and copy payload */
- *bp++ = TLS1_HB_RESPONSE;
- s2n(payload, bp);
- memcpy(bp, pl, payload);
- bp += payload;
- /* Random padding */
- if (RAND_bytes(bp, padding) <= 0) {
- OPENSSL_free(buffer);
- return -1;
- }
-
- r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
- 3 + payload + padding);
-
- if (r >= 0 && s->msg_callback)
- s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
- buffer, 3 + payload + padding,
- s, s->msg_callback_arg);
-
- OPENSSL_free(buffer);
-
- if (r < 0)
- return r;
- } else if (hbtype == TLS1_HB_RESPONSE) {
- unsigned int seq;
-
- /*
- * We only send sequence numbers (2 bytes unsigned int), and 16
- * random bytes, so we just try to read the sequence number
- */
- n2s(pl, seq);
-
- if (payload == 18 && seq == s->tlsext_hb_seq) {
- s->tlsext_hb_seq++;
- s->tlsext_hb_pending = 0;
- }
- }
-
- return 0;
-}
-
-int tls1_heartbeat(SSL *s)
-{
- unsigned char *buf, *p;
- int ret = -1;
- unsigned int payload = 18; /* Sequence number + random bytes */
- unsigned int padding = 16; /* Use minimum padding */
-
- /* Only send if peer supports and accepts HB requests... */
- if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
- s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
- SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
- return -1;
- }
-
- /* ...and there is none in flight yet... */
- if (s->tlsext_hb_pending) {
- SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
- return -1;
- }
-
- /* ...and no handshake in progress. */
- if (SSL_in_init(s) || ossl_statem_get_in_handshake(s)) {
- SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- /*-
- * Create HeartBeat message, we just use a sequence number
- * as payload to distuingish different messages and add
- * some random stuff.
- * - Message Type, 1 byte
- * - Payload Length, 2 bytes (unsigned int)
- * - Payload, the sequence number (2 bytes uint)
- * - Payload, random bytes (16 bytes uint)
- * - Padding
- */
- buf = OPENSSL_malloc(1 + 2 + payload + padding);
- if (buf == NULL) {
- SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- p = buf;
- /* Message Type */
- *p++ = TLS1_HB_REQUEST;
- /* Payload length (18 bytes here) */
- s2n(payload, p);
- /* Sequence number */
- s2n(s->tlsext_hb_seq, p);
- /* 16 random bytes */
- if (RAND_bytes(p, 16) <= 0) {
- SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- p += 16;
- /* Random 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) {
- if (s->msg_callback)
- s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
- buf, 3 + payload + padding,
- s, s->msg_callback_arg);
-
- s->tlsext_hb_pending = 1;
- }
-
- err:
- OPENSSL_free(buf);
- return ret;
-}
-#endif
-
#define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2)
typedef struct {
if (!s->server && strict_mode) {
STACK_OF(X509_NAME) *ca_dn;
int check_type = 0;
- switch (pk->type) {
+ switch (EVP_PKEY_id(pk)) {
case EVP_PKEY_RSA:
check_type = TLS_CT_RSA_SIGN;
break;
static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
{
- int secbits;
- EVP_PKEY *pkey = X509_get_pubkey(x);
+ int secbits = -1;
+ EVP_PKEY *pkey = X509_get0_pubkey(x);
if (pkey) {
+ /*
+ * If no parameters this will return -1 and fail using the default
+ * security callback for any non-zero security level. This will
+ * reject keys which omit parameters but this only affects DSA and
+ * omission of parameters is never (?) done in practice.
+ */
secbits = EVP_PKEY_security_bits(pkey);
- EVP_PKEY_free(pkey);
- } else
- secbits = -1;
+ }
if (s)
return ssl_security(s, op, secbits, 0, x);
else