clear_ciphers(s);
s->first_packet = 0;
+ s->key_update = SSL_KEY_UPDATE_NONE;
+
/* Reset DANE verification result state */
s->dane.mdpth = -1;
s->dane.pdpth = -1;
s->ext.ocsp.resp = NULL;
s->ext.ocsp.resp_len = 0;
SSL_CTX_up_ref(ctx);
- s->initial_ctx = ctx;
+ s->session_ctx = ctx;
#ifndef OPENSSL_NO_EC
if (ctx->ext.ecpointformats) {
s->ext.ecpointformats =
s->method = ctx->method;
+ s->key_update = SSL_KEY_UPDATE_NONE;
+
if (!s->method->ssl_new(s))
goto err;
/* Free up if allocated */
OPENSSL_free(s->ext.hostname);
- SSL_CTX_free(s->initial_ctx);
+ SSL_CTX_free(s->session_ctx);
#ifndef OPENSSL_NO_EC
OPENSSL_free(s->ext.ecpointformats);
OPENSSL_free(s->ext.supportedgroups);
}
}
+int SSL_key_update(SSL *s, SSL_KEY_UPDATE updatetype)
+{
+ /*
+ * TODO(TLS1.3): How will applications know whether TLSv1.3+ has been
+ * negotiated, and that it is appropriate to call SSL_key_update() instead
+ * of SSL_renegotiate().
+ */
+ if (!SSL_IS_TLS13(s)) {
+ SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_WRONG_SSL_VERSION);
+ return 0;
+ }
+
+ if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
+ && updatetype != SSL_KEY_UPDATE_REQUESTED) {
+ SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_INVALID_KEY_UPDATE_TYPE);
+ return 0;
+ }
+
+ if (!SSL_is_init_finished(s)) {
+ SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_STILL_IN_INIT);
+ return 0;
+ }
+
+ ossl_statem_set_in_init(s, 1);
+ s->key_update = updatetype;
+ return 1;
+}
+
+SSL_KEY_UPDATE SSL_get_key_update_type(SSL *s)
+{
+ return s->key_update;
+}
+
int SSL_renegotiate(SSL *s)
{
- /* Do nothing in TLS1.3 */
- if (SSL_IS_TLS13(s))
- return 1;
+ if (SSL_IS_TLS13(s)) {
+ SSLerr(SSL_F_SSL_RENEGOTIATE, SSL_R_WRONG_SSL_VERSION);
+ return 0;
+ }
if (s->renegotiate == 0)
s->renegotiate = 1;
int SSL_renegotiate_abbreviated(SSL *s)
{
- /* Do nothing in TLS1.3 */
if (SSL_IS_TLS13(s))
- return 1;
+ return 0;
if (s->renegotiate == 0)
s->renegotiate = 1;
static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
+ const unsigned char *session_id = a->session_id;
unsigned long l;
+ unsigned char tmp_storage[4];
+
+ if (a->session_id_length < sizeof(tmp_storage)) {
+ memset(tmp_storage, 0, sizeof(tmp_storage));
+ memcpy(tmp_storage, a->session_id, a->session_id_length);
+ session_id = tmp_storage;
+ }
l = (unsigned long)
- ((unsigned int)a->session_id[0]) |
- ((unsigned int)a->session_id[1] << 8L) |
- ((unsigned long)a->session_id[2] << 16L) |
- ((unsigned long)a->session_id[3] << 24L);
+ ((unsigned long)session_id[0]) |
+ ((unsigned long)session_id[1] << 8L) |
+ ((unsigned long)session_id[2] << 16L) |
+ ((unsigned long)session_id[3] << 24L);
return (l);
}
void ssl_set_masks(SSL *s)
{
-#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_GOST)
- CERT_PKEY *cpk;
-#endif
CERT *c = s->cert;
uint32_t *pvalid = s->s3->tmp.valid_flags;
int rsa_enc, rsa_sign, dh_tmp, dsa_sign;
unsigned long mask_k, mask_a;
#ifndef OPENSSL_NO_EC
int have_ecc_cert, ecdsa_ok;
- X509 *x = NULL;
#endif
if (c == NULL)
return;
dh_tmp = 0;
#endif
- rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID;
- rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN;
+ rsa_enc = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID;
+ rsa_sign = pvalid[SSL_PKEY_RSA] & CERT_PKEY_SIGN;
dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN;
#ifndef OPENSSL_NO_EC
have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
#endif
#ifndef OPENSSL_NO_GOST
- cpk = &(c->pkeys[SSL_PKEY_GOST12_512]);
- if (cpk->x509 != NULL && cpk->privatekey != NULL) {
+ if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) {
mask_k |= SSL_kGOST;
mask_a |= SSL_aGOST12;
}
- cpk = &(c->pkeys[SSL_PKEY_GOST12_256]);
- if (cpk->x509 != NULL && cpk->privatekey != NULL) {
+ if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) {
mask_k |= SSL_kGOST;
mask_a |= SSL_aGOST12;
}
- cpk = &(c->pkeys[SSL_PKEY_GOST01]);
- if (cpk->x509 != NULL && cpk->privatekey != NULL) {
+ if (ssl_has_cert(s, SSL_PKEY_GOST01)) {
mask_k |= SSL_kGOST;
mask_a |= SSL_aGOST01;
}
#ifndef OPENSSL_NO_EC
if (have_ecc_cert) {
uint32_t ex_kusage;
- cpk = &c->pkeys[SSL_PKEY_ECC];
- x = cpk->x509;
- ex_kusage = X509_get_key_usage(x);
+ ex_kusage = X509_get_key_usage(c->pkeys[SSL_PKEY_ECC].x509);
ecdsa_ok = ex_kusage & X509v3_KU_DIGITAL_SIGNATURE;
if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
ecdsa_ok = 0;
#endif
-static int ssl_get_server_cert_index(const SSL *s)
-{
- int idx;
-
- /*
- * TODO(TLS1.3): In TLS1.3 the selected certificate is not based on the
- * ciphersuite. For now though it still is. Our only TLS1.3 ciphersuite
- * forces the use of an RSA cert. This will need to change.
- */
- idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509)
- idx = SSL_PKEY_RSA_SIGN;
- if (idx == SSL_PKEY_GOST_EC) {
- if (s->cert->pkeys[SSL_PKEY_GOST12_512].x509)
- idx = SSL_PKEY_GOST12_512;
- else if (s->cert->pkeys[SSL_PKEY_GOST12_256].x509)
- idx = SSL_PKEY_GOST12_256;
- else if (s->cert->pkeys[SSL_PKEY_GOST01].x509)
- idx = SSL_PKEY_GOST01;
- else
- idx = -1;
- }
- if (idx == -1)
- SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR);
- return idx;
-}
-
-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_masks(s);
-
- i = ssl_get_server_cert_index(s);
-
- /* This may or may not be an error. */
- if (i < 0)
- return NULL;
-
- /* May be NULL. */
- return &c->pkeys[i];
-}
-
-EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher,
- const EVP_MD **pmd)
-{
- unsigned long alg_a;
- CERT *c;
- int idx = -1;
-
- alg_a = cipher->algorithm_auth;
- c = s->cert;
-
- if ((alg_a & SSL_aDSS) && (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
- idx = SSL_PKEY_DSA_SIGN;
- else if (alg_a & SSL_aRSA) {
- if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
- idx = SSL_PKEY_RSA_SIGN;
- else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
- idx = SSL_PKEY_RSA_ENC;
- } else if ((alg_a & SSL_aECDSA) &&
- (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
- idx = SSL_PKEY_ECC;
- if (idx == -1) {
- SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR);
- return (NULL);
- }
- if (pmd)
- *pmd = s->s3->tmp.md[idx];
- return c->pkeys[idx].privatekey;
-}
-
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length)
{
- CERT *c = NULL;
- int i = 0;
+ CERT_PKEY *cpk = s->s3->tmp.cert;
*serverinfo_length = 0;
- c = s->cert;
- i = ssl_get_server_cert_index(s);
-
- if (i == -1)
- return 0;
- if (c->pkeys[i].serverinfo == NULL)
+ if (cpk == NULL || cpk->serverinfo == NULL)
return 0;
- *serverinfo = c->pkeys[i].serverinfo;
- *serverinfo_length = c->pkeys[i].serverinfo_length;
+ *serverinfo = cpk->serverinfo;
+ *serverinfo_length = cpk->serverinfo_length;
return 1;
}
if (ssl->ctx == ctx)
return ssl->ctx;
if (ctx == NULL)
- ctx = ssl->initial_ctx;
+ ctx = ssl->session_ctx;
new_cert = ssl_cert_dup(ctx->cert);
if (new_cert == NULL) {
return NULL;
premaster_len);
}
-int ssl_log_master_secret(SSL *ssl,
- const uint8_t *client_random,
- size_t client_random_len,
- const uint8_t *master,
- size_t master_len)
+int ssl_log_secret(SSL *ssl,
+ const char *label,
+ const uint8_t *secret,
+ size_t secret_len)
{
- /*
- * TLSv1.3 changes the derivation of the master secret compared to earlier
- * TLS versions, meaning that logging it out is less useful. Instead we
- * want to log out other secrets: specifically, the handshake and
- * application traffic secrets. For this reason, if this function is called
- * for TLSv1.3 we don't bother logging, and just return success
- * immediately.
- */
- if (SSL_IS_TLS13(ssl)) return 1;
-
- if (client_random_len != 32) {
- SSLerr(SSL_F_SSL_LOG_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- return nss_keylog_int("CLIENT_RANDOM",
+ return nss_keylog_int(label,
ssl,
- client_random,
- client_random_len,
- master,
- master_len);
+ ssl->s3->client_random,
+ SSL3_RANDOM_SIZE,
+ secret,
+ secret_len);
}