1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "ssl_local.h" 11e1051a39Sopenharmony_ci 12e1051a39Sopenharmony_ciint ssl3_do_change_cipher_spec(SSL *s) 13e1051a39Sopenharmony_ci{ 14e1051a39Sopenharmony_ci int i; 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci if (s->server) 17e1051a39Sopenharmony_ci i = SSL3_CHANGE_CIPHER_SERVER_READ; 18e1051a39Sopenharmony_ci else 19e1051a39Sopenharmony_ci i = SSL3_CHANGE_CIPHER_CLIENT_READ; 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci if (s->s3.tmp.key_block == NULL) { 22e1051a39Sopenharmony_ci if (s->session == NULL || s->session->master_key_length == 0) { 23e1051a39Sopenharmony_ci /* might happen if dtls1_read_bytes() calls this */ 24e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY); 25e1051a39Sopenharmony_ci return 0; 26e1051a39Sopenharmony_ci } 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci s->session->cipher = s->s3.tmp.new_cipher; 29e1051a39Sopenharmony_ci if (!s->method->ssl3_enc->setup_key_block(s)) { 30e1051a39Sopenharmony_ci /* SSLfatal() already called */ 31e1051a39Sopenharmony_ci return 0; 32e1051a39Sopenharmony_ci } 33e1051a39Sopenharmony_ci } 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ci if (!s->method->ssl3_enc->change_cipher_state(s, i)) { 36e1051a39Sopenharmony_ci /* SSLfatal() already called */ 37e1051a39Sopenharmony_ci return 0; 38e1051a39Sopenharmony_ci } 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci return 1; 41e1051a39Sopenharmony_ci} 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ciint ssl3_send_alert(SSL *s, int level, int desc) 44e1051a39Sopenharmony_ci{ 45e1051a39Sopenharmony_ci /* Map tls/ssl alert value to correct one */ 46e1051a39Sopenharmony_ci if (SSL_TREAT_AS_TLS13(s)) 47e1051a39Sopenharmony_ci desc = tls13_alert_code(desc); 48e1051a39Sopenharmony_ci else 49e1051a39Sopenharmony_ci desc = s->method->ssl3_enc->alert_value(desc); 50e1051a39Sopenharmony_ci if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) 51e1051a39Sopenharmony_ci desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have 52e1051a39Sopenharmony_ci * protocol_version alerts */ 53e1051a39Sopenharmony_ci if (desc < 0) 54e1051a39Sopenharmony_ci return -1; 55e1051a39Sopenharmony_ci if (s->shutdown & SSL_SENT_SHUTDOWN && desc != SSL_AD_CLOSE_NOTIFY) 56e1051a39Sopenharmony_ci return -1; 57e1051a39Sopenharmony_ci /* If a fatal one, remove from cache */ 58e1051a39Sopenharmony_ci if ((level == SSL3_AL_FATAL) && (s->session != NULL)) 59e1051a39Sopenharmony_ci SSL_CTX_remove_session(s->session_ctx, s->session); 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_ci s->s3.alert_dispatch = 1; 62e1051a39Sopenharmony_ci s->s3.send_alert[0] = level; 63e1051a39Sopenharmony_ci s->s3.send_alert[1] = desc; 64e1051a39Sopenharmony_ci if (!RECORD_LAYER_write_pending(&s->rlayer)) { 65e1051a39Sopenharmony_ci /* data still being written out? */ 66e1051a39Sopenharmony_ci return s->method->ssl_dispatch_alert(s); 67e1051a39Sopenharmony_ci } 68e1051a39Sopenharmony_ci /* 69e1051a39Sopenharmony_ci * else data is still being written out, we will get written some time in 70e1051a39Sopenharmony_ci * the future 71e1051a39Sopenharmony_ci */ 72e1051a39Sopenharmony_ci return -1; 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ciint ssl3_dispatch_alert(SSL *s) 76e1051a39Sopenharmony_ci{ 77e1051a39Sopenharmony_ci int i, j; 78e1051a39Sopenharmony_ci size_t alertlen; 79e1051a39Sopenharmony_ci void (*cb) (const SSL *ssl, int type, int val) = NULL; 80e1051a39Sopenharmony_ci size_t written; 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci s->s3.alert_dispatch = 0; 83e1051a39Sopenharmony_ci alertlen = 2; 84e1051a39Sopenharmony_ci i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3.send_alert[0], &alertlen, 1, 0, 85e1051a39Sopenharmony_ci &written); 86e1051a39Sopenharmony_ci if (i <= 0) { 87e1051a39Sopenharmony_ci s->s3.alert_dispatch = 1; 88e1051a39Sopenharmony_ci } else { 89e1051a39Sopenharmony_ci /* 90e1051a39Sopenharmony_ci * Alert sent to BIO - now flush. If the message does not get sent due 91e1051a39Sopenharmony_ci * to non-blocking IO, we will not worry too much. 92e1051a39Sopenharmony_ci */ 93e1051a39Sopenharmony_ci (void)BIO_flush(s->wbio); 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ci if (s->msg_callback) 96e1051a39Sopenharmony_ci s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3.send_alert, 97e1051a39Sopenharmony_ci 2, s, s->msg_callback_arg); 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci if (s->info_callback != NULL) 100e1051a39Sopenharmony_ci cb = s->info_callback; 101e1051a39Sopenharmony_ci else if (s->ctx->info_callback != NULL) 102e1051a39Sopenharmony_ci cb = s->ctx->info_callback; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci if (cb != NULL) { 105e1051a39Sopenharmony_ci j = (s->s3.send_alert[0] << 8) | s->s3.send_alert[1]; 106e1051a39Sopenharmony_ci cb(s, SSL_CB_WRITE_ALERT, j); 107e1051a39Sopenharmony_ci } 108e1051a39Sopenharmony_ci } 109e1051a39Sopenharmony_ci return i; 110e1051a39Sopenharmony_ci} 111