int ssl_check_serverhello_tlsext(SSL *s);
#endif
-SSL3_ENC_METHOD TLSv1_enc_data={
+SSL3_ENC_METHOD const TLSv1_enc_data={
tls1_enc,
tls1_mac,
tls1_setup_key_block,
ssl3_handshake_write
};
-SSL3_ENC_METHOD TLSv1_1_enc_data={
+SSL3_ENC_METHOD const TLSv1_1_enc_data={
tls1_enc,
tls1_mac,
tls1_setup_key_block,
ssl3_handshake_write
};
-SSL3_ENC_METHOD TLSv1_2_enc_data={
+SSL3_ENC_METHOD const TLSv1_2_enc_data={
tls1_enc,
tls1_mac,
tls1_setup_key_block,
#define TLS_CURVE_CHAR2 0x1
#define TLS_CURVE_PRIME 0x0
-static tls_curve_info nid_list[] =
+static const tls_curve_info nid_list[] =
{
{NID_sect163k1, 80, TLS_CURVE_CHAR2},/* sect163k1 (1) */
{NID_sect163r1, 80, TLS_CURVE_CHAR2},/* sect163r1 (2) */
int tls1_ec_curve_id2nid(int curve_id)
{
- /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+ /* ECC curves from RFC 4492 and RFC 7027 */
if ((curve_id < 1) || ((unsigned int)curve_id >
sizeof(nid_list)/sizeof(nid_list[0])))
return 0;
int tls1_ec_nid2curve_id(int nid)
{
- /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+ /* ECC curves from RFC 4492 and RFC 7027 */
switch (nid)
{
case NID_sect163k1: /* sect163k1 (1) */
/* See if curve is allowed by security callback */
static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
{
- tls_curve_info *cinfo;
+ 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])))
return 0;
cinfo = &nid_list[curve[1]-1];
+#ifdef OPENSSL_NO_EC2M
+ if (cinfo->flags & TLS_CURVE_CHAR2)
+ return 0;
+#endif
return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);
}
c->mask_k |= SSL_kPSK;
}
#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;
+ }
+#endif
c->valid = 1;
}
return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
}
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al)
{
int extdatalen=0;
- unsigned char *ret = p;
+ unsigned char *orig = buf;
+ unsigned char *ret = buf;
#ifndef OPENSSL_NO_EC
/* See if we support any ECC ciphersuites */
int using_ecc = 0;
}
#endif
- /* don't add extensions for SSLv3 unless doing secure renegotiation */
- if (s->client_version == SSL3_VERSION
- && !s->s3->send_connection_binding)
- return p;
-
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
+ /* Add RI if renegotiating */
+ if (s->renegotiate)
+ {
+ int el;
+
+ if(!ssl_add_clienthello_renegotiate_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;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+
+ if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ ret += el;
+ }
+ /* Only add RI for SSLv3 */
+ if (s->client_version == SSL3_VERSION)
+ goto done;
+
if (s->tlsext_hostname != NULL)
{
/* Add TLS extension servername to the Client Hello message */
ret+=size_str;
}
- /* Add RI if renegotiating */
- if (s->renegotiate)
- {
- int el;
-
- if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- if((limit - p - 4 - el) < 0) return NULL;
-
- s2n(TLSEXT_TYPE_renegotiate,ret);
- s2n(el,ret);
-
- if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- ret += el;
- }
-
#ifndef OPENSSL_NO_SRP
/* Add SRP username if there is one */
if (s->srp_ctx.login != NULL)
plistlen = etmp - ret - 4;
- /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
- * elliptic_curve_list, but the examples use two bytes.
- * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
- * resolves this to two bytes.
- */
s2n(plistlen + 2, ret);
s2n(plistlen, ret);
ret+=plistlen;
etmp = ret;
/* Skip over lengths for now */
ret += 4;
- salglen = tls12_copy_sigalgs(s, etmp, salg, salglen);
+ salglen = tls12_copy_sigalgs(s, ret, salg, salglen);
/* Fill in lengths */
s2n(salglen + 2, etmp);
s2n(salglen, etmp);
{
size_t col = s->s3->client_opaque_prf_input_len;
- if ((long)(limit - ret - 6 - col < 0))
+ if ((long)(limit - ret - 6 - col) < 0)
return NULL;
if (col > 0xFFFD) /* can't happen */
return NULL;
#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:
ret += s->alpn_client_proto_list_len;
}
- if(SSL_get_srtp_profiles(s))
+ if(SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s))
{
int el;
ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_use_srtp,ret);
s2n(el,ret);
}
ret += el;
}
-
+ custom_ext_init(&s->cert->cli_ext);
/* Add custom TLS Extensions to ClientHello */
- if (s->ctx->custom_cli_ext_records_count)
- {
- size_t i;
- custom_cli_ext_record* record;
-
- for (i = 0; i < s->ctx->custom_cli_ext_records_count; i++)
- {
- const unsigned char* out = NULL;
- unsigned short outlen = 0;
-
- record = &s->ctx->custom_cli_ext_records[i];
- /* NULL callback sends empty extension */
- /* -1 from callback omits extension */
- if (record->fn1)
- {
- int cb_retval = 0;
- cb_retval = record->fn1(s, record->ext_type,
- &out, &outlen, al,
- record->arg);
- if (cb_retval == 0)
- return NULL; /* error */
- if (cb_retval == -1)
- continue; /* skip this extension */
- }
- if (limit < ret + 4 + outlen)
- return NULL;
- s2n(record->ext_type, ret);
- s2n(outlen, ret);
- memcpy(ret, out, outlen);
- ret += outlen;
- }
- }
+ if (!custom_ext_add(s, 0, &ret, limit, al))
+ return NULL;
#ifdef TLSEXT_TYPE_encrypt_then_mac
s2n(TLSEXT_TYPE_encrypt_then_mac,ret);
s2n(0,ret);
#endif
-#ifdef TLSEXT_TYPE_padding
+
/* Add padding to workaround bugs in F5 terminators.
* See https://tools.ietf.org/html/draft-agl-tls-padding-03
*
* NB: because this code works out the length of all existing
* extensions it MUST always appear last.
*/
- {
- 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)
- hlen -= 4;
- else
- hlen = 0;
+ 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)
+ hlen -= 4;
+ else
+ hlen = 0;
- s2n(TLSEXT_TYPE_padding, ret);
- s2n(hlen, ret);
- memset(ret, 0, hlen);
- ret += hlen;
+ s2n(TLSEXT_TYPE_padding, ret);
+ s2n(hlen, ret);
+ memset(ret, 0, hlen);
+ ret += hlen;
+ }
}
- }
-#endif
- if ((extdatalen = ret-p-2) == 0)
- return p;
+ done:
- s2n(extdatalen,p);
+ if ((extdatalen = ret-orig-2)== 0)
+ return orig;
+
+ s2n(extdatalen, orig);
return ret;
}
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al)
{
int extdatalen=0;
- unsigned char *ret = p;
- size_t i;
- custom_srv_ext_record *record;
+ unsigned char *orig = buf;
+ unsigned char *ret = buf;
#ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen;
#endif
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
- /* don't add extensions for SSLv3, unless doing secure renegotiation */
- if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
- return p;
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
- if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
- {
- if ((long)(limit - ret - 4) < 0) return NULL;
-
- s2n(TLSEXT_TYPE_server_name,ret);
- s2n(0,ret);
- }
-
if(s->s3->send_connection_binding)
{
int el;
return NULL;
}
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
ret += el;
}
+ /* Only add RI for SSLv3 */
+ if (s->version == SSL3_VERSION)
+ goto done;
+
+ if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
+ {
+ if ((long)(limit - ret - 4) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_server_name,ret);
+ s2n(0,ret);
+ }
+
#ifndef OPENSSL_NO_EC
if (using_ecc)
{
}
#endif
- if(s->srtp_profile)
+ if(SSL_IS_DTLS(s) && s->srtp_profile)
{
int el;
ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_use_srtp,ret);
s2n(el,ret);
/* Add Heartbeat extension if we've received one */
if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
{
+ if ((limit - ret - 4 - 1) < 0)
+ return NULL;
s2n(TLSEXT_TYPE_heartbeat,ret);
s2n(1,ret);
/* Set mode:
}
}
#endif
-
- for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++)
- {
- const unsigned char *out = NULL;
- unsigned short outlen = 0;
- int cb_retval = 0;
-
- record = &s->ctx->custom_srv_ext_records[i];
-
- /* NULL callback or -1 omits extension */
- if (!record->fn2)
- continue;
- cb_retval = record->fn2(s, record->ext_type,
- &out, &outlen, al,
- record->arg);
- if (cb_retval == 0)
- return NULL; /* error */
- if (cb_retval == -1)
- continue; /* skip this extension */
- if (limit < ret + 4 + outlen)
- return NULL;
- s2n(record->ext_type, ret);
- s2n(outlen, ret);
- memcpy(ret, out, outlen);
- ret += outlen;
- }
+ if (!custom_ext_add(s, 1, &ret, limit, al))
+ return NULL;
#ifdef TLSEXT_TYPE_encrypt_then_mac
if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC)
{
- /* Don't use encrypt_then_mac if AEAD: might want
- * to disable for other ciphersuites too.
+ /* Don't use encrypt_then_mac if AEAD or RC4
+ * might want to disable for other cases too.
*/
- if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD)
+ 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;
else
{
ret += len;
}
- if ((extdatalen = ret-p-2)== 0)
- return p;
+ done:
+
+ if ((extdatalen = ret-orig-2)== 0)
+ return orig;
- s2n(extdatalen,p);
+ s2n(extdatalen, orig);
return ret;
}
}
#endif /* !OPENSSL_NO_EC */
+
static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
{
unsigned short type;
unsigned short len;
unsigned char *data = *p;
int renegotiate_seen = 0;
- size_t i;
s->servername_done = 0;
s->tlsext_status_type = -1;
s->s3->alpn_selected = NULL;
}
- /* Clear observed custom extensions */
- s->s3->serverinfo_client_tlsext_custom_types_count = 0;
- if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
- {
- OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
- s->s3->serverinfo_client_tlsext_custom_types = NULL;
- }
-
#ifndef OPENSSL_NO_HEARTBEATS
s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
OPENSSL_free(s->cert->peer_sigalgs);
s->cert->peer_sigalgs = NULL;
}
- /* Clear any shared sigtnature algorithms */
- if (s->cert->shared_sigalgs)
- {
- OPENSSL_free(s->cert->shared_sigalgs);
- s->cert->shared_sigalgs = NULL;
- }
- /* 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;
- }
#ifdef TLSEXT_TYPE_encrypt_then_mac
s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 0, type, data, size,
s->tlsext_debug_arg);
+ if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+ return 0;
+ renegotiate_seen = 1;
+ }
+ else if (s->version == SSL3_VERSION)
+ {}
/* The servername extension is treated as follows:
- Only the hostname type is supported with a maximum length of 255.
*/
- if (type == TLSEXT_TYPE_server_name)
+ else if (type == TLSEXT_TYPE_server_name)
{
unsigned char *sdata;
int servname_type;
return 0;
}
}
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
- return 0;
- renegotiate_seen = 1;
- }
else if (type == TLSEXT_TYPE_signature_algorithms)
{
int dsize;
*al = SSL_AD_DECODE_ERROR;
return 0;
}
- if (!tls1_process_sigalgs(s, data, dsize))
+ if (!tls1_save_sigalgs(s, data, dsize))
{
*al = SSL_AD_DECODE_ERROR;
return 0;
}
- /* If sigalgs received and no shared algorithms fatal
- * error.
- */
- if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs)
- {
- SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
- SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
- *al = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
}
else if (type == TLSEXT_TYPE_status_request)
{
}
/* session ticket processed earlier */
- else if (type == TLSEXT_TYPE_use_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;
}
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+ else if (type == TLSEXT_TYPE_encrypt_then_mac)
+ s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
+#endif
/* If this ClientHello extension was unhandled and this is
* a nonresumed connection, check whether the extension is a
* custom TLS Extension (has a custom_srv_ext_record), and if
* so call the callback and record the extension number so that
* an appropriate ServerHello may be later returned.
*/
- else if (!s->hit && s->ctx->custom_srv_ext_records_count)
+ else if (!s->hit)
{
- custom_srv_ext_record *record;
-
- for (i=0; i < s->ctx->custom_srv_ext_records_count; i++)
- {
- record = &s->ctx->custom_srv_ext_records[i];
- if (type == record->ext_type)
- {
- if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
- return 0;
- }
- }
+ if (custom_ext_parse(s, 1, type, data, size, al) <= 0)
+ return 0;
}
-#ifdef TLSEXT_TYPE_encrypt_then_mac
- else if (type == TLSEXT_TYPE_encrypt_then_mac)
- s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-#endif
data+=size;
}
SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
return 0;
}
- /* If no signature algorithms extension set default values */
- if (!s->cert->peer_sigalgs)
- ssl_cert_set_default_md(s->cert);
return 1;
}
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n)
{
int al = -1;
+ custom_ext_init(&s->cert->srv_ext);
if (ssl_scan_clienthello_tlsext(s, p, d, n, &al) <= 0)
{
ssl3_send_alert(s,SSL3_AL_FATAL,al);
#ifndef OPENSSL_NO_NEXTPROTONEG
s->s3->next_proto_neg_seen = 0;
#endif
+ s->tlsext_ticket_expected = 0;
if (s->s3->alpn_selected)
{
s->tlsext_debug_cb(s, 1, type, data, size,
s->tlsext_debug_arg);
- if (type == TLSEXT_TYPE_server_name)
+
+ if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+ return 0;
+ renegotiate_seen = 1;
+ }
+ else if (s->version == SSL3_VERSION)
+ {}
+ else if (type == TLSEXT_TYPE_server_name)
{
if (s->tlsext_hostname == NULL || size > 0)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
- s->session->tlsext_ecpointformatlist_length = 0;
- if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
- if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+ if (!s->hit)
{
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
+ s->session->tlsext_ecpointformatlist_length = 0;
+ if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+ if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+ memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
}
- s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
- 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;
memcpy(s->s3->alpn_selected, data + 3, len);
s->s3->alpn_selected_len = len;
}
-
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
- return 0;
- renegotiate_seen = 1;
- }
#ifndef OPENSSL_NO_HEARTBEATS
else if (type == TLSEXT_TYPE_heartbeat)
{
}
}
#endif
- else if (type == TLSEXT_TYPE_use_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;
}
- /* If this extension type was not otherwise handled, but
- * matches a custom_cli_ext_record, then send it to the c
- * callback */
- else if (s->ctx->custom_cli_ext_records_count)
- {
- size_t i;
- custom_cli_ext_record* record;
-
- for (i = 0; i < s->ctx->custom_cli_ext_records_count; i++)
- {
- record = &s->ctx->custom_cli_ext_records[i];
- if (record->ext_type == type)
- {
- if (record->fn2 && !record->fn2(s, type, data, size, al, record->arg))
- return 0;
- break;
- }
- }
- }
#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)
+ 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
+ /* If this extension type was not otherwise handled, but
+ * matches a custom_cli_ext_record, then send it to the c
+ * callback */
+ else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
+ return 0;
data += size;
}
}
}
+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;
+ }
+ /* 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;
+ }
+
+ /* If sigalgs received process it. */
+ if (s->cert->peer_sigalgs)
+ {
+ if (!tls1_process_sigalgs(s))
+ {
+ SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+ ERR_R_MALLOC_FAILURE);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ /* Fatal error is no shared signature algorithms */
+ if (!s->cert->shared_sigalgs)
+ {
+ SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+ SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ goto err;
+ }
+ }
+ else
+ ssl_cert_set_default_md(s->cert);
+ return 1;
+ err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return 0;
+ }
+
int ssl_check_clienthello_tlsext_late(SSL *s)
{
int ret = SSL_TLSEXT_ERR_OK;
HMAC_Final(&hctx, tick_hmac, NULL);
HMAC_CTX_cleanup(&hctx);
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
+ {
+ EVP_CIPHER_CTX_cleanup(&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);
}
EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
+ {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ OPENSSL_free(sdec);
return 2;
+ }
slen += mlen;
EVP_CIPHER_CTX_cleanup(&ctx);
p = sdec;
/* Set preferred digest for each key type */
-int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
+int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
{
- int idx;
- size_t i;
- const EVP_MD *md;
CERT *c = s->cert;
- TLS_SIGALGS *sigptr;
/* Extension ignored for inappropriate versions */
if (!SSL_USE_SIGALGS(s))
return 1;
return 0;
c->peer_sigalgslen = dsize;
memcpy(c->peer_sigalgs, data, dsize);
+ return 1;
+ }
- tls1_set_shared_sigalgs(s);
+int tls1_process_sigalgs(SSL *s)
+ {
+ int idx;
+ size_t i;
+ const EVP_MD *md;
+ CERT *c = s->cert;
+ TLS_SIGALGS *sigptr;
+ if (!tls1_set_shared_sigalgs(s))
+ return 0;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
if (check_flags)
check_flags |= CERT_PKEY_SUITEB;
ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
- if (ok != X509_V_OK)
- {
- if (check_flags)
- rv |= CERT_PKEY_SUITEB;
- else
- goto end;
- }
+ if (ok == X509_V_OK)
+ rv |= CERT_PKEY_SUITEB;
+ else if (!check_flags)
+ goto end;
}
/* Check all signature algorithms are consistent with