Adding code to send session as PSK Identity.
BUG=75
Change-Id: Ied864cfccbc0e68d71c55c5ab563da27b7253463
Reviewed-on: https://boringssl-review.googlesource.com/9043
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c
index 61e1414..d58f72d 100644
--- a/ssl/tls13_client.c
+++ b/ssl/tls13_client.c
@@ -151,8 +151,8 @@
}
/* Parse out the extensions. */
- int have_key_share = 0;
- CBS key_share;
+ int have_key_share = 0, have_pre_shared_key = 0;
+ CBS key_share, pre_shared_key;
while (CBS_len(&extensions) != 0) {
uint16_t type;
CBS extension;
@@ -173,6 +173,15 @@
key_share = extension;
have_key_share = 1;
break;
+ case TLSEXT_TYPE_pre_shared_key:
+ if (have_pre_shared_key) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+ pre_shared_key = extension;
+ have_pre_shared_key = 1;
+ break;
default:
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
@@ -183,10 +192,48 @@
assert(ssl->s3->have_version);
memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
- SSL_set_session(ssl, NULL);
- if (!ssl_get_new_session(ssl, 0)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (have_pre_shared_key) {
+ if (ssl->session == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ return ssl_hs_error;
+ }
+
+ if (!ssl_ext_pre_shared_key_parse_serverhello(ssl, &alert,
+ &pre_shared_key)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return ssl_hs_error;
+ }
+
+ if (ssl->session->ssl_version != ssl->version) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+
+ if (!ssl_session_is_context_valid(ssl, ssl->session)) {
+ /* This is actually a client application bug. */
+ OPENSSL_PUT_ERROR(SSL,
+ SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+
+ ssl->s3->session_reused = 1;
+ /* Only authentication information carries over in TLS 1.3. */
+ ssl->s3->new_session =
+ SSL_SESSION_dup(ssl->session, SSL_SESSION_DUP_AUTH_ONLY);
+ if (ssl->s3->new_session == NULL) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+ SSL_set_session(ssl, NULL);
+ } else {
+ if (!ssl_get_new_session(ssl, 0)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
}
const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite);
@@ -196,15 +243,26 @@
return ssl_hs_error;
}
- /* Check if the cipher is disabled. */
- if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
- (cipher->algorithm_auth & ssl->cert->mask_a) ||
- SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
- SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
- !sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
- return ssl_hs_error;
+ if (!ssl->s3->session_reused) {
+ /* Check if the cipher is disabled. */
+ if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
+ (cipher->algorithm_auth & ssl->cert->mask_a) ||
+ SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
+ SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
+ !sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+ } else {
+ uint16_t resumption_cipher;
+ if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
+ &resumption_cipher) ||
+ resumption_cipher != ssl_cipher_get_value(cipher)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
}
ssl->s3->new_session->cipher = cipher;
@@ -212,18 +270,35 @@
/* The PRF hash is now known. Set up the key schedule. */
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
- size_t hash_len =
+ size_t resumption_ctx_len =
EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
- if (!tls13_init_key_schedule(ssl, kZeroes, hash_len)) {
+ if (ssl->s3->session_reused) {
+ uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
+ if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
+ ssl->s3->new_session) ||
+ !tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
+ return ssl_hs_error;
+ }
+ } else if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
return ssl_hs_error;
}
/* Resolve PSK and incorporate it into the secret. */
if (cipher->algorithm_auth == SSL_aPSK) {
- /* TODO(davidben): Support PSK. */
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return ssl_hs_error;
- } else if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) {
+ if (!ssl->s3->session_reused) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return ssl_hs_error;
+ }
+
+ uint8_t resumption_psk[EVP_MAX_MD_SIZE];
+ if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
+ ssl->s3->new_session) ||
+ !tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+ } else if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
return ssl_hs_error;
}
@@ -237,7 +312,6 @@
uint8_t *dhe_secret;
size_t dhe_secret_len;
- uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ssl_ext_key_share_parse_serverhello(ssl, &dhe_secret, &dhe_secret_len,
&alert, &key_share)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
@@ -255,7 +329,7 @@
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return ssl_hs_error;
}
- if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) {
+ if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
return ssl_hs_error;
}
}
@@ -568,8 +642,9 @@
}
int tls13_process_new_session_ticket(SSL *ssl) {
- SSL_SESSION *session = SSL_SESSION_dup(ssl->s3->established_session,
- 0 /* don't include ticket */);
+ SSL_SESSION *session =
+ SSL_SESSION_dup(ssl->s3->established_session,
+ SSL_SESSION_INCLUDE_NONAUTH);
if (session == NULL) {
return 0;
}