size_t i;
int nid;
char etmp[20];
+ if (elem == NULL)
+ return 0;
if (narg->nidcnt == MAX_CURVELIST)
return 0;
if (len > (int)(sizeof(etmp) - 1))
tlsext_sigalg_ecdsa(md)
static const unsigned char tls12_sigalgs[] = {
-# ifndef OPENSSL_NO_SHA512
tlsext_sigalg(TLSEXT_hash_sha512)
tlsext_sigalg(TLSEXT_hash_sha384)
-# endif
-# ifndef OPENSSL_NO_SHA256
tlsext_sigalg(TLSEXT_hash_sha256)
tlsext_sigalg(TLSEXT_hash_sha224)
-# endif
-# ifndef OPENSSL_NO_SHA
tlsext_sigalg(TLSEXT_hash_sha1)
-# endif
};
# ifndef OPENSSL_NO_ECDSA
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;
s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
s2n(0, ret);
# endif
+ s2n(TLSEXT_TYPE_extended_master_secret, ret);
+ s2n(0, ret);
/*
* Add padding to workaround bugs in F5 terminators. See
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
if (SSL_IS_DTLS(s) && s->srtp_profile) {
}
}
# 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;
if (data + size > (d + n))
goto ri_check;
-# if 0
- fprintf(stderr, "Received extension type %d size %d\n", type, size);
-# endif
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
if (type == TLSEXT_TYPE_renegotiate) {
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);
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
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_encrypt_then_mac)
s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
# 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
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 */
}
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
s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
}
# 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;
}
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);
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
if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
return 2;
HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
- tlsext_tick_md(), NULL);
+ EVP_sha256(), NULL);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
tctx->tlsext_tick_aes_key, etick + 16);
}
# else
{NID_md5, 64, EVP_md5},
# endif
-# ifdef OPENSSL_NO_SHA
- {NID_sha1, 80, 0},
-# else
{NID_sha1, 80, EVP_sha1},
-# endif
-# ifdef OPENSSL_NO_SHA256
- {NID_sha224, 112, 0},
- {NID_sha256, 128, 0},
-# else
{NID_sha224, 112, EVP_sha224},
{NID_sha256, 128, EVP_sha256},
-# endif
-# ifdef OPENSSL_NO_SHA512
- {NID_sha384, 192, 0},
- {NID_sha512, 256, 0}
-# else
{NID_sha384, 192, EVP_sha384},
{NID_sha512, 256, EVP_sha512}
-# endif
};
static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg)
size_t i;
char etmp[20], *p;
int sig_alg, hash_alg;
+ if (elem == NULL)
+ return 0;
if (sarg->sigalgcnt == MAX_SIGALGLEN)
return 0;
if (len > (int)(sizeof(etmp) - 1))