int use_context))ssl_undefined_function,
};
+static void clear_ciphers(SSL *s)
+{
+ /* clear the current cipher */
+ ssl_clear_cipher_ctx(s);
+ ssl_clear_hash_ctx(&s->read_hash);
+ ssl_clear_hash_ctx(&s->write_hash);
+}
+
int SSL_clear(SSL *s)
{
if (s->method == NULL) {
BUF_MEM_free(s->init_buf);
s->init_buf = NULL;
- ssl_clear_cipher_ctx(s);
- ssl_clear_hash_ctx(&s->read_hash);
- ssl_clear_hash_ctx(&s->write_hash);
+ clear_ciphers(s);
s->first_packet = 0;
/*
CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
s->ctx = ctx;
-#ifndef OPENSSL_NO_TLSEXT
s->tlsext_debug_cb = 0;
s->tlsext_debug_arg = NULL;
s->tlsext_ticket_expected = 0;
s->ctx->alpn_client_proto_list_len);
s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
}
-#endif
s->verify_result = X509_V_OK;
SSL_SESSION_free(s->session);
}
- ssl_clear_cipher_ctx(s);
- ssl_clear_hash_ctx(&s->read_hash);
- ssl_clear_hash_ctx(&s->write_hash);
+ clear_ciphers(s);
ssl_cert_free(s->cert);
/* Free up if allocated */
-#ifndef OPENSSL_NO_TLSEXT
OPENSSL_free(s->tlsext_hostname);
SSL_CTX_free(s->initial_ctx);
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
OPENSSL_free(s->tlsext_ecpointformatlist);
OPENSSL_free(s->tlsext_ellipticcurvelist);
-# endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_EC */
sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
OPENSSL_free(s->tlsext_ocsp_resp);
OPENSSL_free(s->alpn_client_proto_list);
-#endif
sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
SSL_CTX_free(s->ctx);
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
OPENSSL_free(s->next_proto_negotiated);
#endif
if (r == NULL)
return (r);
- CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(r);
return (r);
}
{
STACK_OF(X509) *r;
- if ((s == NULL) || (s->session == NULL)
- || (s->session->sess_cert == NULL))
+ if ((s == NULL) || (s->session == NULL))
r = NULL;
else
- r = s->session->sess_cert->cert_chain;
+ r = s->session->peer_chain;
/*
* If we are a client, cert_chain includes the peer's own certificate; if
case SSL_CTRL_GET_RAW_CIPHERLIST:
if (parg) {
- if (s->cert->ciphers_raw == NULL)
+ if (s->s3->tmp.ciphers_raw == NULL)
return 0;
- *(unsigned char **)parg = s->cert->ciphers_raw;
- return (int)s->cert->ciphers_rawlen;
+ *(unsigned char **)parg = s->s3->tmp.ciphers_raw;
+ return (int)s->s3->tmp.ciphers_rawlen;
} else
return ssl_put_cipher_by_char(s, NULL, NULL);
case SSL_CTRL_GET_EXTMS_SUPPORT:
return (NULL);
}
+STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s)
+{
+ if ((s == NULL) || (s->session == NULL) || !s->server)
+ return NULL;
+ return s->session->ciphers;
+}
+
STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
{
STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
return (buf);
}
-#ifndef OPENSSL_NO_TLSEXT
/** return a servername extension value if provided in Client Hello, or NULL.
* So far, only host_name types are defined (RFC 3546).
*/
return status;
}
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* SSL_get0_next_proto_negotiated sets *data and *len to point to the
* client's requested protocol for this connection and returns 0. If the
ctx->next_proto_select_cb = cb;
ctx->next_proto_select_cb_arg = arg;
}
-# endif
+#endif
/*
* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
*len = ssl->s3->alpn_selected_len;
}
-#endif /* !OPENSSL_NO_TLSEXT */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen,
ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
-#ifndef OPENSSL_NO_TLSEXT
ret->tlsext_servername_callback = 0;
ret->tlsext_servername_arg = NULL;
/* Setup RFC4507 ticket keys */
ret->tlsext_status_cb = 0;
ret->tlsext_status_arg = NULL;
-# ifndef OPENSSL_NO_NEXTPROTONEG
+#ifndef OPENSSL_NO_NEXTPROTONEG
ret->next_protos_advertised_cb = 0;
ret->next_proto_select_cb = 0;
-# endif
#endif
#ifndef OPENSSL_NO_PSK
ret->psk_identity_hint = NULL;
ENGINE_finish(a->client_cert_engine);
#endif
-#ifndef OPENSSL_NO_TLSEXT
-# ifndef OPENSSL_NO_EC
+#ifndef OPENSSL_NO_EC
OPENSSL_free(a->tlsext_ecpointformatlist);
OPENSSL_free(a->tlsext_ellipticcurvelist);
-# endif
- OPENSSL_free(a->alpn_client_proto_list);
#endif
+ OPENSSL_free(a->alpn_client_proto_list);
OPENSSL_free(a);
}
ssl_cert_set_cert_cb(s->cert, cb, arg);
}
-void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
+void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
{
CERT_PKEY *cpk;
+ CERT *c = s->cert;
+ uint32_t *pvalid = s->s3->tmp.valid_flags;
int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign;
int rsa_enc_export, dh_rsa_export, dh_dsa_export;
int rsa_tmp_export, dh_tmp_export, kl;
have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto);
#endif
cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]);
- rsa_enc = cpk->valid_flags & CERT_PKEY_VALID;
+ rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID;
rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]);
- rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN;
+ rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN;
cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]);
- dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN;
+ dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN;
cpk = &(c->pkeys[SSL_PKEY_DH_RSA]);
- dh_rsa = cpk->valid_flags & CERT_PKEY_VALID;
+ dh_rsa = pvalid[SSL_PKEY_DH_RSA] & CERT_PKEY_VALID;
dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
cpk = &(c->pkeys[SSL_PKEY_DH_DSA]);
-/* FIX THIS EAY EAY EAY */
- dh_dsa = cpk->valid_flags & CERT_PKEY_VALID;
+ dh_dsa = pvalid[SSL_PKEY_DH_DSA] & CERT_PKEY_VALID;
dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
cpk = &(c->pkeys[SSL_PKEY_ECC]);
#ifndef OPENSSL_NO_EC
- have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID;
+ have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
#endif
mask_k = 0;
mask_a = 0;
mask_k |= SSL_kGOST;
mask_a |= SSL_aGOST01;
}
- cpk = &(c->pkeys[SSL_PKEY_GOST94]);
- if (cpk->x509 != NULL && cpk->privatekey != NULL) {
- mask_k |= SSL_kGOST;
- mask_a |= SSL_aGOST94;
- }
if (rsa_enc || (rsa_tmp && rsa_sign))
mask_k |= SSL_kRSA;
if (dh_dsa_export)
emask_k |= SSL_kDHd;
- if (emask_k & (SSL_kDHr | SSL_kDHd))
+ if (mask_k & (SSL_kDHr | SSL_kDHd))
mask_a |= SSL_aDH;
if (rsa_enc || rsa_sign) {
(x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
- if (!(cpk->valid_flags & CERT_PKEY_SIGN))
+ if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
ecdsa_ok = 0;
ecc_pkey = X509_get_pubkey(x);
ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0;
mask_a |= SSL_aPSK;
emask_k |= SSL_kPSK;
emask_a |= SSL_aPSK;
+ if (mask_k & SSL_kRSA)
+ mask_k |= SSL_kRSAPSK;
+ if (mask_k & SSL_kDHE)
+ mask_k |= SSL_kDHEPSK;
+ if (mask_k & SSL_kECDHE)
+ mask_k |= SSL_kECDHEPSK;
#endif
- c->mask_k = mask_k;
- c->mask_a = mask_a;
- c->export_mask_k = emask_k;
- c->export_mask_a = emask_a;
- c->valid = 1;
+ s->s3->tmp.mask_k = mask_k;
+ s->s3->tmp.mask_a = mask_a;
+ s->s3->tmp.export_mask_k = emask_k;
+ s->s3->tmp.export_mask_a = emask_a;
}
/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
return idx;
}
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
+CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
{
CERT *c;
int i;
c = s->cert;
if (!s->s3 || !s->s3->tmp.new_cipher)
return NULL;
- ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
+ ssl_set_masks(s, s->s3->tmp.new_cipher);
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
/*
return (NULL);
}
if (pmd)
- *pmd = c->pkeys[idx].digest;
+ *pmd = s->s3->tmp.md[idx];
return c->pkeys[idx].privatekey;
}
-#ifndef OPENSSL_NO_TLSEXT
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length)
{
*serverinfo_length = c->pkeys[i].serverinfo_length;
return 1;
}
-#endif
void ssl_update_cache(SSL *s, int mode)
{
return (ret);
}
-/*
- * For the next 2 functions, SSL_clear() sets shutdown and so one of these
- * calls will reset it
- */
void SSL_set_accept_state(SSL *s)
{
s->server = 1;
s->shutdown = 0;
s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
s->handshake_func = s->method->ssl_accept;
- /* clear the current cipher */
- ssl_clear_cipher_ctx(s);
- ssl_clear_hash_ctx(&s->read_hash);
- ssl_clear_hash_ctx(&s->write_hash);
+ clear_ciphers(s);
}
void SSL_set_connect_state(SSL *s)
s->shutdown = 0;
s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
s->handshake_func = s->method->ssl_connect;
- /* clear the current cipher */
- ssl_clear_cipher_ctx(s);
- ssl_clear_hash_ctx(&s->read_hash);
- ssl_clear_hash_ctx(&s->write_hash);
+ clear_ciphers(s);
}
int ssl_undefined_function(SSL *s)
CERT *new_cert;
if (ssl->ctx == ctx)
return ssl->ctx;
-#ifndef OPENSSL_NO_TLSEXT
if (ctx == NULL)
ctx = ssl->initial_ctx;
-#endif
new_cert = ssl_cert_dup(ctx->cert);
if (new_cert == NULL) {
return NULL;
}
- /* Preserve any already negotiated parameters */
- if (ssl->server) {
- new_cert->peer_sigalgs = ssl->cert->peer_sigalgs;
- new_cert->peer_sigalgslen = ssl->cert->peer_sigalgslen;
- ssl->cert->peer_sigalgs = NULL;
- new_cert->ciphers_raw = ssl->cert->ciphers_raw;
- new_cert->ciphers_rawlen = ssl->cert->ciphers_rawlen;
- ssl->cert->ciphers_raw = NULL;
- }
ssl_cert_free(ssl->cert);
ssl->cert = new_cert;
return (ssl->verify_result);
}
+size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen)
+{
+ if (outlen == 0)
+ return sizeof(ssl->s3->client_random);
+ if (outlen > sizeof(ssl->s3->client_random))
+ outlen = sizeof(ssl->s3->client_random);
+ memcpy(out, ssl->s3->client_random, outlen);
+ return outlen;
+}
+
+size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen)
+{
+ if (outlen == 0)
+ return sizeof(ssl->s3->server_random);
+ if (outlen > sizeof(ssl->s3->server_random))
+ outlen = sizeof(ssl->s3->server_random);
+ memcpy(out, ssl->s3->server_random, outlen);
+ return outlen;
+}
+
+size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
+ unsigned char *out, size_t outlen)
+{
+ if (session->master_key_length < 0) {
+ /* Should never happen */
+ return 0;
+ }
+ if (outlen == 0)
+ return session->master_key_length;
+ if (outlen > (size_t)session->master_key_length)
+ outlen = session->master_key_length;
+ memcpy(out, session->master_key, outlen);
+ return outlen;
+}
+
int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{