| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. | 
|  | 3 | * Copyright 2005 Nokia. All rights reserved. | 
|  | 4 | * | 
|  | 5 | * Licensed under the OpenSSL license (the "License").  You may not use | 
|  | 6 | * this file except in compliance with the License.  You can obtain a copy | 
|  | 7 | * in the file LICENSE in the source distribution or at | 
|  | 8 | * https://www.openssl.org/source/license.html | 
|  | 9 | */ | 
|  | 10 |  | 
|  | 11 | #include <stdio.h> | 
|  | 12 | #include "ssl_local.h" | 
|  | 13 | #include <openssl/evp.h> | 
|  | 14 | #include <openssl/md5.h> | 
|  | 15 | #include "internal/cryptlib.h" | 
|  | 16 |  | 
|  | 17 | static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) | 
|  | 18 | { | 
|  | 19 | EVP_MD_CTX *m5; | 
|  | 20 | EVP_MD_CTX *s1; | 
|  | 21 | unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; | 
|  | 22 | unsigned char c = 'A'; | 
|  | 23 | unsigned int i, j, k; | 
|  | 24 | int ret = 0; | 
|  | 25 |  | 
|  | 26 | #ifdef CHARSET_EBCDIC | 
|  | 27 | c = os_toascii[c];          /* 'A' in ASCII */ | 
|  | 28 | #endif | 
|  | 29 | k = 0; | 
|  | 30 | m5 = EVP_MD_CTX_new(); | 
|  | 31 | s1 = EVP_MD_CTX_new(); | 
|  | 32 | if (m5 == NULL || s1 == NULL) { | 
|  | 33 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, | 
|  | 34 | ERR_R_MALLOC_FAILURE); | 
|  | 35 | goto err; | 
|  | 36 | } | 
|  | 37 | EVP_MD_CTX_set_flags(m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); | 
|  | 38 | for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { | 
|  | 39 | k++; | 
|  | 40 | if (k > sizeof(buf)) { | 
|  | 41 | /* bug: 'buf' is too small for this ciphersuite */ | 
|  | 42 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, | 
|  | 43 | ERR_R_INTERNAL_ERROR); | 
|  | 44 | goto err; | 
|  | 45 | } | 
|  | 46 |  | 
|  | 47 | for (j = 0; j < k; j++) | 
|  | 48 | buf[j] = c; | 
|  | 49 | c++; | 
|  | 50 | if (!EVP_DigestInit_ex(s1, EVP_sha1(), NULL) | 
|  | 51 | || !EVP_DigestUpdate(s1, buf, k) | 
|  | 52 | || !EVP_DigestUpdate(s1, s->session->master_key, | 
|  | 53 | s->session->master_key_length) | 
|  | 54 | || !EVP_DigestUpdate(s1, s->s3->server_random, SSL3_RANDOM_SIZE) | 
|  | 55 | || !EVP_DigestUpdate(s1, s->s3->client_random, SSL3_RANDOM_SIZE) | 
|  | 56 | || !EVP_DigestFinal_ex(s1, smd, NULL) | 
|  | 57 | || !EVP_DigestInit_ex(m5, EVP_md5(), NULL) | 
|  | 58 | || !EVP_DigestUpdate(m5, s->session->master_key, | 
|  | 59 | s->session->master_key_length) | 
|  | 60 | || !EVP_DigestUpdate(m5, smd, SHA_DIGEST_LENGTH)) { | 
|  | 61 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, | 
|  | 62 | ERR_R_INTERNAL_ERROR); | 
|  | 63 | goto err; | 
|  | 64 | } | 
|  | 65 | if ((int)(i + MD5_DIGEST_LENGTH) > num) { | 
|  | 66 | if (!EVP_DigestFinal_ex(m5, smd, NULL)) { | 
|  | 67 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, | 
|  | 68 | SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); | 
|  | 69 | goto err; | 
|  | 70 | } | 
|  | 71 | memcpy(km, smd, (num - i)); | 
|  | 72 | } else { | 
|  | 73 | if (!EVP_DigestFinal_ex(m5, km, NULL)) { | 
|  | 74 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, | 
|  | 75 | SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); | 
|  | 76 | goto err; | 
|  | 77 | } | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | km += MD5_DIGEST_LENGTH; | 
|  | 81 | } | 
|  | 82 | OPENSSL_cleanse(smd, sizeof(smd)); | 
|  | 83 | ret = 1; | 
|  | 84 | err: | 
|  | 85 | EVP_MD_CTX_free(m5); | 
|  | 86 | EVP_MD_CTX_free(s1); | 
|  | 87 | return ret; | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | int ssl3_change_cipher_state(SSL *s, int which) | 
|  | 91 | { | 
|  | 92 | unsigned char *p, *mac_secret; | 
|  | 93 | unsigned char *ms, *key, *iv; | 
|  | 94 | EVP_CIPHER_CTX *dd; | 
|  | 95 | const EVP_CIPHER *c; | 
|  | 96 | #ifndef OPENSSL_NO_COMP | 
|  | 97 | COMP_METHOD *comp; | 
|  | 98 | #endif | 
|  | 99 | const EVP_MD *m; | 
|  | 100 | int mdi; | 
|  | 101 | size_t n, i, j, k, cl; | 
|  | 102 | int reuse_dd = 0; | 
|  | 103 |  | 
|  | 104 | c = s->s3->tmp.new_sym_enc; | 
|  | 105 | m = s->s3->tmp.new_hash; | 
|  | 106 | /* m == NULL will lead to a crash later */ | 
|  | 107 | if (!ossl_assert(m != NULL)) { | 
|  | 108 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 109 | ERR_R_INTERNAL_ERROR); | 
|  | 110 | goto err; | 
|  | 111 | } | 
|  | 112 | #ifndef OPENSSL_NO_COMP | 
|  | 113 | if (s->s3->tmp.new_compression == NULL) | 
|  | 114 | comp = NULL; | 
|  | 115 | else | 
|  | 116 | comp = s->s3->tmp.new_compression->method; | 
|  | 117 | #endif | 
|  | 118 |  | 
|  | 119 | if (which & SSL3_CC_READ) { | 
|  | 120 | if (s->enc_read_ctx != NULL) { | 
|  | 121 | reuse_dd = 1; | 
|  | 122 | } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { | 
|  | 123 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 124 | ERR_R_MALLOC_FAILURE); | 
|  | 125 | goto err; | 
|  | 126 | } else { | 
|  | 127 | /* | 
|  | 128 | * make sure it's initialised in case we exit later with an error | 
|  | 129 | */ | 
|  | 130 | EVP_CIPHER_CTX_reset(s->enc_read_ctx); | 
|  | 131 | } | 
|  | 132 | dd = s->enc_read_ctx; | 
|  | 133 |  | 
|  | 134 | if (ssl_replace_hash(&s->read_hash, m) == NULL) { | 
|  | 135 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 136 | ERR_R_INTERNAL_ERROR); | 
|  | 137 | goto err; | 
|  | 138 | } | 
|  | 139 | #ifndef OPENSSL_NO_COMP | 
|  | 140 | /* COMPRESS */ | 
|  | 141 | COMP_CTX_free(s->expand); | 
|  | 142 | s->expand = NULL; | 
|  | 143 | if (comp != NULL) { | 
|  | 144 | s->expand = COMP_CTX_new(comp); | 
|  | 145 | if (s->expand == NULL) { | 
|  | 146 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, | 
|  | 147 | SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 148 | SSL_R_COMPRESSION_LIBRARY_ERROR); | 
|  | 149 | goto err; | 
|  | 150 | } | 
|  | 151 | } | 
|  | 152 | #endif | 
|  | 153 | RECORD_LAYER_reset_read_sequence(&s->rlayer); | 
|  | 154 | mac_secret = &(s->s3->read_mac_secret[0]); | 
|  | 155 | } else { | 
|  | 156 | s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; | 
|  | 157 | if (s->enc_write_ctx != NULL) { | 
|  | 158 | reuse_dd = 1; | 
|  | 159 | } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { | 
|  | 160 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 161 | ERR_R_MALLOC_FAILURE); | 
|  | 162 | goto err; | 
|  | 163 | } else { | 
|  | 164 | /* | 
|  | 165 | * make sure it's initialised in case we exit later with an error | 
|  | 166 | */ | 
|  | 167 | EVP_CIPHER_CTX_reset(s->enc_write_ctx); | 
|  | 168 | } | 
|  | 169 | dd = s->enc_write_ctx; | 
|  | 170 | if (ssl_replace_hash(&s->write_hash, m) == NULL) { | 
|  | 171 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 172 | ERR_R_MALLOC_FAILURE); | 
|  | 173 | goto err; | 
|  | 174 | } | 
|  | 175 | #ifndef OPENSSL_NO_COMP | 
|  | 176 | /* COMPRESS */ | 
|  | 177 | COMP_CTX_free(s->compress); | 
|  | 178 | s->compress = NULL; | 
|  | 179 | if (comp != NULL) { | 
|  | 180 | s->compress = COMP_CTX_new(comp); | 
|  | 181 | if (s->compress == NULL) { | 
|  | 182 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, | 
|  | 183 | SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 184 | SSL_R_COMPRESSION_LIBRARY_ERROR); | 
|  | 185 | goto err; | 
|  | 186 | } | 
|  | 187 | } | 
|  | 188 | #endif | 
|  | 189 | RECORD_LAYER_reset_write_sequence(&s->rlayer); | 
|  | 190 | mac_secret = &(s->s3->write_mac_secret[0]); | 
|  | 191 | } | 
|  | 192 |  | 
|  | 193 | if (reuse_dd) | 
|  | 194 | EVP_CIPHER_CTX_reset(dd); | 
|  | 195 |  | 
|  | 196 | p = s->s3->tmp.key_block; | 
|  | 197 | mdi = EVP_MD_size(m); | 
|  | 198 | if (mdi < 0) { | 
|  | 199 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 200 | ERR_R_INTERNAL_ERROR); | 
|  | 201 | goto err; | 
|  | 202 | } | 
|  | 203 | i = mdi; | 
|  | 204 | cl = EVP_CIPHER_key_length(c); | 
|  | 205 | j = cl; | 
|  | 206 | k = EVP_CIPHER_iv_length(c); | 
|  | 207 | if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || | 
|  | 208 | (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { | 
|  | 209 | ms = &(p[0]); | 
|  | 210 | n = i + i; | 
|  | 211 | key = &(p[n]); | 
|  | 212 | n += j + j; | 
|  | 213 | iv = &(p[n]); | 
|  | 214 | n += k + k; | 
|  | 215 | } else { | 
|  | 216 | n = i; | 
|  | 217 | ms = &(p[n]); | 
|  | 218 | n += i + j; | 
|  | 219 | key = &(p[n]); | 
|  | 220 | n += j + k; | 
|  | 221 | iv = &(p[n]); | 
|  | 222 | n += k; | 
|  | 223 | } | 
|  | 224 |  | 
|  | 225 | if (n > s->s3->tmp.key_block_length) { | 
|  | 226 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 227 | ERR_R_INTERNAL_ERROR); | 
|  | 228 | goto err; | 
|  | 229 | } | 
|  | 230 |  | 
|  | 231 | memcpy(mac_secret, ms, i); | 
|  | 232 |  | 
|  | 233 | if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { | 
|  | 234 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, | 
|  | 235 | ERR_R_INTERNAL_ERROR); | 
|  | 236 | goto err; | 
|  | 237 | } | 
|  | 238 |  | 
|  | 239 | s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | 
|  | 240 | return 1; | 
|  | 241 | err: | 
|  | 242 | return 0; | 
|  | 243 | } | 
|  | 244 |  | 
|  | 245 | int ssl3_setup_key_block(SSL *s) | 
|  | 246 | { | 
|  | 247 | unsigned char *p; | 
|  | 248 | const EVP_CIPHER *c; | 
|  | 249 | const EVP_MD *hash; | 
|  | 250 | int num; | 
|  | 251 | int ret = 0; | 
|  | 252 | SSL_COMP *comp; | 
|  | 253 |  | 
|  | 254 | if (s->s3->tmp.key_block_length != 0) | 
|  | 255 | return 1; | 
|  | 256 |  | 
|  | 257 | if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) { | 
|  | 258 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_SETUP_KEY_BLOCK, | 
|  | 259 | SSL_R_CIPHER_OR_HASH_UNAVAILABLE); | 
|  | 260 | return 0; | 
|  | 261 | } | 
|  | 262 |  | 
|  | 263 | s->s3->tmp.new_sym_enc = c; | 
|  | 264 | s->s3->tmp.new_hash = hash; | 
|  | 265 | #ifdef OPENSSL_NO_COMP | 
|  | 266 | s->s3->tmp.new_compression = NULL; | 
|  | 267 | #else | 
|  | 268 | s->s3->tmp.new_compression = comp; | 
|  | 269 | #endif | 
|  | 270 |  | 
|  | 271 | num = EVP_MD_size(hash); | 
|  | 272 | if (num < 0) | 
|  | 273 | return 0; | 
|  | 274 |  | 
|  | 275 | num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c); | 
|  | 276 | num *= 2; | 
|  | 277 |  | 
|  | 278 | ssl3_cleanup_key_block(s); | 
|  | 279 |  | 
|  | 280 | if ((p = OPENSSL_malloc(num)) == NULL) { | 
|  | 281 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_SETUP_KEY_BLOCK, | 
|  | 282 | ERR_R_MALLOC_FAILURE); | 
|  | 283 | return 0; | 
|  | 284 | } | 
|  | 285 |  | 
|  | 286 | s->s3->tmp.key_block_length = num; | 
|  | 287 | s->s3->tmp.key_block = p; | 
|  | 288 |  | 
|  | 289 | /* Calls SSLfatal() as required */ | 
|  | 290 | ret = ssl3_generate_key_block(s, p, num); | 
|  | 291 |  | 
|  | 292 | if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { | 
|  | 293 | /* | 
|  | 294 | * enable vulnerability countermeasure for CBC ciphers with known-IV | 
|  | 295 | * problem (http://www.openssl.org/~bodo/tls-cbc.txt) | 
|  | 296 | */ | 
|  | 297 | s->s3->need_empty_fragments = 1; | 
|  | 298 |  | 
|  | 299 | if (s->session->cipher != NULL) { | 
|  | 300 | if (s->session->cipher->algorithm_enc == SSL_eNULL) | 
|  | 301 | s->s3->need_empty_fragments = 0; | 
|  | 302 |  | 
|  | 303 | #ifndef OPENSSL_NO_RC4 | 
|  | 304 | if (s->session->cipher->algorithm_enc == SSL_RC4) | 
|  | 305 | s->s3->need_empty_fragments = 0; | 
|  | 306 | #endif | 
|  | 307 | } | 
|  | 308 | } | 
|  | 309 |  | 
|  | 310 | return ret; | 
|  | 311 | } | 
|  | 312 |  | 
|  | 313 | void ssl3_cleanup_key_block(SSL *s) | 
|  | 314 | { | 
|  | 315 | OPENSSL_clear_free(s->s3->tmp.key_block, s->s3->tmp.key_block_length); | 
|  | 316 | s->s3->tmp.key_block = NULL; | 
|  | 317 | s->s3->tmp.key_block_length = 0; | 
|  | 318 | } | 
|  | 319 |  | 
|  | 320 | int ssl3_init_finished_mac(SSL *s) | 
|  | 321 | { | 
|  | 322 | BIO *buf = BIO_new(BIO_s_mem()); | 
|  | 323 |  | 
|  | 324 | if (buf == NULL) { | 
|  | 325 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_INIT_FINISHED_MAC, | 
|  | 326 | ERR_R_MALLOC_FAILURE); | 
|  | 327 | return 0; | 
|  | 328 | } | 
|  | 329 | ssl3_free_digest_list(s); | 
|  | 330 | s->s3->handshake_buffer = buf; | 
|  | 331 | (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); | 
|  | 332 | return 1; | 
|  | 333 | } | 
|  | 334 |  | 
|  | 335 | /* | 
|  | 336 | * Free digest list. Also frees handshake buffer since they are always freed | 
|  | 337 | * together. | 
|  | 338 | */ | 
|  | 339 |  | 
|  | 340 | void ssl3_free_digest_list(SSL *s) | 
|  | 341 | { | 
|  | 342 | BIO_free(s->s3->handshake_buffer); | 
|  | 343 | s->s3->handshake_buffer = NULL; | 
|  | 344 | EVP_MD_CTX_free(s->s3->handshake_dgst); | 
|  | 345 | s->s3->handshake_dgst = NULL; | 
|  | 346 | } | 
|  | 347 |  | 
|  | 348 | int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len) | 
|  | 349 | { | 
|  | 350 | int ret; | 
|  | 351 |  | 
|  | 352 | if (s->s3->handshake_dgst == NULL) { | 
|  | 353 | /* Note: this writes to a memory BIO so a failure is a fatal error */ | 
|  | 354 | if (len > INT_MAX) { | 
|  | 355 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINISH_MAC, | 
|  | 356 | SSL_R_OVERFLOW_ERROR); | 
|  | 357 | return 0; | 
|  | 358 | } | 
|  | 359 | ret = BIO_write(s->s3->handshake_buffer, (void *)buf, (int)len); | 
|  | 360 | if (ret <= 0 || ret != (int)len) { | 
|  | 361 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINISH_MAC, | 
|  | 362 | ERR_R_INTERNAL_ERROR); | 
|  | 363 | return 0; | 
|  | 364 | } | 
|  | 365 | } else { | 
|  | 366 | ret = EVP_DigestUpdate(s->s3->handshake_dgst, buf, len); | 
|  | 367 | if (!ret) { | 
|  | 368 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINISH_MAC, | 
|  | 369 | ERR_R_INTERNAL_ERROR); | 
|  | 370 | return 0; | 
|  | 371 | } | 
|  | 372 | } | 
|  | 373 | return 1; | 
|  | 374 | } | 
|  | 375 |  | 
|  | 376 | int ssl3_digest_cached_records(SSL *s, int keep) | 
|  | 377 | { | 
|  | 378 | const EVP_MD *md; | 
|  | 379 | long hdatalen; | 
|  | 380 | void *hdata; | 
|  | 381 |  | 
|  | 382 | if (s->s3->handshake_dgst == NULL) { | 
|  | 383 | hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); | 
|  | 384 | if (hdatalen <= 0) { | 
|  | 385 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, | 
|  | 386 | SSL_R_BAD_HANDSHAKE_LENGTH); | 
|  | 387 | return 0; | 
|  | 388 | } | 
|  | 389 |  | 
|  | 390 | s->s3->handshake_dgst = EVP_MD_CTX_new(); | 
|  | 391 | if (s->s3->handshake_dgst == NULL) { | 
|  | 392 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, | 
|  | 393 | ERR_R_MALLOC_FAILURE); | 
|  | 394 | return 0; | 
|  | 395 | } | 
|  | 396 |  | 
|  | 397 | md = ssl_handshake_md(s); | 
|  | 398 | if (md == NULL || !EVP_DigestInit_ex(s->s3->handshake_dgst, md, NULL) | 
|  | 399 | || !EVP_DigestUpdate(s->s3->handshake_dgst, hdata, hdatalen)) { | 
|  | 400 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, | 
|  | 401 | ERR_R_INTERNAL_ERROR); | 
|  | 402 | return 0; | 
|  | 403 | } | 
|  | 404 | } | 
|  | 405 | if (keep == 0) { | 
|  | 406 | BIO_free(s->s3->handshake_buffer); | 
|  | 407 | s->s3->handshake_buffer = NULL; | 
|  | 408 | } | 
|  | 409 |  | 
|  | 410 | return 1; | 
|  | 411 | } | 
|  | 412 |  | 
|  | 413 | size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, | 
|  | 414 | unsigned char *p) | 
|  | 415 | { | 
|  | 416 | int ret; | 
|  | 417 | EVP_MD_CTX *ctx = NULL; | 
|  | 418 |  | 
|  | 419 | if (!ssl3_digest_cached_records(s, 0)) { | 
|  | 420 | /* SSLfatal() already called */ | 
|  | 421 | return 0; | 
|  | 422 | } | 
|  | 423 |  | 
|  | 424 | if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) { | 
|  | 425 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, | 
|  | 426 | SSL_R_NO_REQUIRED_DIGEST); | 
|  | 427 | return 0; | 
|  | 428 | } | 
|  | 429 |  | 
|  | 430 | ctx = EVP_MD_CTX_new(); | 
|  | 431 | if (ctx == NULL) { | 
|  | 432 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, | 
|  | 433 | ERR_R_MALLOC_FAILURE); | 
|  | 434 | return 0; | 
|  | 435 | } | 
|  | 436 | if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) { | 
|  | 437 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, | 
|  | 438 | ERR_R_INTERNAL_ERROR); | 
|  | 439 | ret = 0; | 
|  | 440 | goto err; | 
|  | 441 | } | 
|  | 442 |  | 
|  | 443 | ret = EVP_MD_CTX_size(ctx); | 
|  | 444 | if (ret < 0) { | 
|  | 445 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, | 
|  | 446 | ERR_R_INTERNAL_ERROR); | 
|  | 447 | ret = 0; | 
|  | 448 | goto err; | 
|  | 449 | } | 
|  | 450 |  | 
|  | 451 | if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0) | 
|  | 452 | || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET, | 
|  | 453 | (int)s->session->master_key_length, | 
|  | 454 | s->session->master_key) <= 0 | 
|  | 455 | || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) { | 
|  | 456 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, | 
|  | 457 | ERR_R_INTERNAL_ERROR); | 
|  | 458 | ret = 0; | 
|  | 459 | } | 
|  | 460 |  | 
|  | 461 | err: | 
|  | 462 | EVP_MD_CTX_free(ctx); | 
|  | 463 |  | 
|  | 464 | return ret; | 
|  | 465 | } | 
|  | 466 |  | 
|  | 467 | int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, | 
|  | 468 | size_t len, size_t *secret_size) | 
|  | 469 | { | 
|  | 470 | static const unsigned char *salt[3] = { | 
|  | 471 | #ifndef CHARSET_EBCDIC | 
|  | 472 | (const unsigned char *)"A", | 
|  | 473 | (const unsigned char *)"BB", | 
|  | 474 | (const unsigned char *)"CCC", | 
|  | 475 | #else | 
|  | 476 | (const unsigned char *)"\x41", | 
|  | 477 | (const unsigned char *)"\x42\x42", | 
|  | 478 | (const unsigned char *)"\x43\x43\x43", | 
|  | 479 | #endif | 
|  | 480 | }; | 
|  | 481 | unsigned char buf[EVP_MAX_MD_SIZE]; | 
|  | 482 | EVP_MD_CTX *ctx = EVP_MD_CTX_new(); | 
|  | 483 | int i, ret = 1; | 
|  | 484 | unsigned int n; | 
|  | 485 | size_t ret_secret_size = 0; | 
|  | 486 |  | 
|  | 487 | if (ctx == NULL) { | 
|  | 488 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_MASTER_SECRET, | 
|  | 489 | ERR_R_MALLOC_FAILURE); | 
|  | 490 | return 0; | 
|  | 491 | } | 
|  | 492 | for (i = 0; i < 3; i++) { | 
|  | 493 | if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0 | 
|  | 494 | || EVP_DigestUpdate(ctx, salt[i], | 
|  | 495 | strlen((const char *)salt[i])) <= 0 | 
|  | 496 | || EVP_DigestUpdate(ctx, p, len) <= 0 | 
|  | 497 | || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]), | 
|  | 498 | SSL3_RANDOM_SIZE) <= 0 | 
|  | 499 | || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]), | 
|  | 500 | SSL3_RANDOM_SIZE) <= 0 | 
|  | 501 | /* TODO(size_t) : convert me */ | 
|  | 502 | || EVP_DigestFinal_ex(ctx, buf, &n) <= 0 | 
|  | 503 | || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0 | 
|  | 504 | || EVP_DigestUpdate(ctx, p, len) <= 0 | 
|  | 505 | || EVP_DigestUpdate(ctx, buf, n) <= 0 | 
|  | 506 | || EVP_DigestFinal_ex(ctx, out, &n) <= 0) { | 
|  | 507 | SSLfatal(s, SSL_AD_INTERNAL_ERROR, | 
|  | 508 | SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); | 
|  | 509 | ret = 0; | 
|  | 510 | break; | 
|  | 511 | } | 
|  | 512 | out += n; | 
|  | 513 | ret_secret_size += n; | 
|  | 514 | } | 
|  | 515 | EVP_MD_CTX_free(ctx); | 
|  | 516 |  | 
|  | 517 | OPENSSL_cleanse(buf, sizeof(buf)); | 
|  | 518 | if (ret) | 
|  | 519 | *secret_size = ret_secret_size; | 
|  | 520 | return ret; | 
|  | 521 | } | 
|  | 522 |  | 
|  | 523 | int ssl3_alert_code(int code) | 
|  | 524 | { | 
|  | 525 | switch (code) { | 
|  | 526 | case SSL_AD_CLOSE_NOTIFY: | 
|  | 527 | return SSL3_AD_CLOSE_NOTIFY; | 
|  | 528 | case SSL_AD_UNEXPECTED_MESSAGE: | 
|  | 529 | return SSL3_AD_UNEXPECTED_MESSAGE; | 
|  | 530 | case SSL_AD_BAD_RECORD_MAC: | 
|  | 531 | return SSL3_AD_BAD_RECORD_MAC; | 
|  | 532 | case SSL_AD_DECRYPTION_FAILED: | 
|  | 533 | return SSL3_AD_BAD_RECORD_MAC; | 
|  | 534 | case SSL_AD_RECORD_OVERFLOW: | 
|  | 535 | return SSL3_AD_BAD_RECORD_MAC; | 
|  | 536 | case SSL_AD_DECOMPRESSION_FAILURE: | 
|  | 537 | return SSL3_AD_DECOMPRESSION_FAILURE; | 
|  | 538 | case SSL_AD_HANDSHAKE_FAILURE: | 
|  | 539 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 540 | case SSL_AD_NO_CERTIFICATE: | 
|  | 541 | return SSL3_AD_NO_CERTIFICATE; | 
|  | 542 | case SSL_AD_BAD_CERTIFICATE: | 
|  | 543 | return SSL3_AD_BAD_CERTIFICATE; | 
|  | 544 | case SSL_AD_UNSUPPORTED_CERTIFICATE: | 
|  | 545 | return SSL3_AD_UNSUPPORTED_CERTIFICATE; | 
|  | 546 | case SSL_AD_CERTIFICATE_REVOKED: | 
|  | 547 | return SSL3_AD_CERTIFICATE_REVOKED; | 
|  | 548 | case SSL_AD_CERTIFICATE_EXPIRED: | 
|  | 549 | return SSL3_AD_CERTIFICATE_EXPIRED; | 
|  | 550 | case SSL_AD_CERTIFICATE_UNKNOWN: | 
|  | 551 | return SSL3_AD_CERTIFICATE_UNKNOWN; | 
|  | 552 | case SSL_AD_ILLEGAL_PARAMETER: | 
|  | 553 | return SSL3_AD_ILLEGAL_PARAMETER; | 
|  | 554 | case SSL_AD_UNKNOWN_CA: | 
|  | 555 | return SSL3_AD_BAD_CERTIFICATE; | 
|  | 556 | case SSL_AD_ACCESS_DENIED: | 
|  | 557 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 558 | case SSL_AD_DECODE_ERROR: | 
|  | 559 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 560 | case SSL_AD_DECRYPT_ERROR: | 
|  | 561 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 562 | case SSL_AD_EXPORT_RESTRICTION: | 
|  | 563 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 564 | case SSL_AD_PROTOCOL_VERSION: | 
|  | 565 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 566 | case SSL_AD_INSUFFICIENT_SECURITY: | 
|  | 567 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 568 | case SSL_AD_INTERNAL_ERROR: | 
|  | 569 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 570 | case SSL_AD_USER_CANCELLED: | 
|  | 571 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 572 | case SSL_AD_NO_RENEGOTIATION: | 
|  | 573 | return -1;            /* Don't send it :-) */ | 
|  | 574 | case SSL_AD_UNSUPPORTED_EXTENSION: | 
|  | 575 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 576 | case SSL_AD_CERTIFICATE_UNOBTAINABLE: | 
|  | 577 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 578 | case SSL_AD_UNRECOGNIZED_NAME: | 
|  | 579 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 580 | case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: | 
|  | 581 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 582 | case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: | 
|  | 583 | return SSL3_AD_HANDSHAKE_FAILURE; | 
|  | 584 | case SSL_AD_UNKNOWN_PSK_IDENTITY: | 
|  | 585 | return TLS1_AD_UNKNOWN_PSK_IDENTITY; | 
|  | 586 | case SSL_AD_INAPPROPRIATE_FALLBACK: | 
|  | 587 | return TLS1_AD_INAPPROPRIATE_FALLBACK; | 
|  | 588 | case SSL_AD_NO_APPLICATION_PROTOCOL: | 
|  | 589 | return TLS1_AD_NO_APPLICATION_PROTOCOL; | 
|  | 590 | case SSL_AD_CERTIFICATE_REQUIRED: | 
|  | 591 | return SSL_AD_HANDSHAKE_FAILURE; | 
|  | 592 | case SSL_AD_MISSING_EXTENSION: | 
|  | 593 | return SSL_AD_HANDSHAKE_FAILURE; | 
|  | 594 | default: | 
|  | 595 | return -1; | 
|  | 596 | } | 
|  | 597 | } |