Loading ssl/s3_srvr.c +48 −30 Original line number Diff line number Diff line Loading @@ -3295,14 +3295,16 @@ int ssl3_send_server_certificate(SSL *s) /* send a new session ticket (not necessarily for a new session) */ int ssl3_send_newsession_ticket(SSL *s) { unsigned char *senc = NULL; EVP_CIPHER_CTX ctx; HMAC_CTX hctx; if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { unsigned char *p, *senc, *macstart; unsigned char *p, *macstart; const unsigned char *const_p; int len, slen_full, slen; SSL_SESSION *sess; unsigned int hlen; EVP_CIPHER_CTX ctx; HMAC_CTX hctx; SSL_CTX *tctx = s->initial_ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key_name[16]; Loading @@ -3313,32 +3315,38 @@ int ssl3_send_newsession_ticket(SSL *s) * Some length values are 16 bits, so forget it if session is too * long */ if (slen_full > 0xFF00) if (slen_full == 0 || slen_full > 0xFF00) return -1; senc = OPENSSL_malloc(slen_full); if (!senc) return -1; EVP_CIPHER_CTX_init(&ctx); HMAC_CTX_init(&hctx); p = senc; i2d_SSL_SESSION(s->session, &p); if (!i2d_SSL_SESSION(s->session, &p)) goto err; /* * create a fresh copy (not shared with other threads) to clean up */ const_p = senc; sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); if (sess == NULL) { OPENSSL_free(senc); return -1; } if (sess == NULL) goto err; sess->session_id_length = 0; /* ID is irrelevant for the ticket */ slen = i2d_SSL_SESSION(sess, NULL); if (slen > slen_full) { /* shouldn't ever happen */ OPENSSL_free(senc); return -1; if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ SSL_SESSION_free(sess); goto err; } p = senc; i2d_SSL_SESSION(sess, &p); if (!i2d_SSL_SESSION(sess, &p)) { SSL_SESSION_free(sess); goto err; } SSL_SESSION_free(sess); /*- Loading @@ -3352,31 +3360,30 @@ int ssl3_send_newsession_ticket(SSL *s) if (!BUF_MEM_grow(s->init_buf, 26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) return -1; goto err; p = (unsigned char *)s->init_buf->data; /* do the header */ *(p++) = SSL3_MT_NEWSESSION_TICKET; /* Skip message length for now */ p += 3; EVP_CIPHER_CTX_init(&ctx); HMAC_CTX_init(&hctx); /* * Initialize HMAC and cipher contexts. If callback present it does * all the work otherwise use generated values from parent ctx. */ if (tctx->tlsext_ticket_key_cb) { if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, &hctx, 1) < 0) { OPENSSL_free(senc); return -1; } &hctx, 1) < 0) goto err; } else { RAND_pseudo_bytes(iv, 16); EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, iv); HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL); if (RAND_bytes(iv, 16) <= 0) goto err; if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, iv)) goto err; if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL)) goto err; memcpy(key_name, tctx->tlsext_tick_key_name, 16); } Loading @@ -3397,14 +3404,19 @@ int ssl3_send_newsession_ticket(SSL *s) memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); p += EVP_CIPHER_CTX_iv_length(&ctx); /* Encrypt session data */ EVP_EncryptUpdate(&ctx, p, &len, senc, slen); if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) goto err; p += len; EVP_EncryptFinal(&ctx, p, &len); if (!EVP_EncryptFinal(&ctx, p, &len)) goto err; p += len; EVP_CIPHER_CTX_cleanup(&ctx); HMAC_Update(&hctx, macstart, p - macstart); HMAC_Final(&hctx, p, &hlen); if (!HMAC_Update(&hctx, macstart, p - macstart)) goto err; if (!HMAC_Final(&hctx, p, &hlen)) goto err; EVP_CIPHER_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&hctx); p += hlen; Loading @@ -3425,6 +3437,12 @@ int ssl3_send_newsession_ticket(SSL *s) /* SSL3_ST_SW_SESSION_TICKET_B */ return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); err: if (senc) OPENSSL_free(senc); EVP_CIPHER_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&hctx); return -1; } int ssl3_send_cert_status(SSL *s) Loading Loading
ssl/s3_srvr.c +48 −30 Original line number Diff line number Diff line Loading @@ -3295,14 +3295,16 @@ int ssl3_send_server_certificate(SSL *s) /* send a new session ticket (not necessarily for a new session) */ int ssl3_send_newsession_ticket(SSL *s) { unsigned char *senc = NULL; EVP_CIPHER_CTX ctx; HMAC_CTX hctx; if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { unsigned char *p, *senc, *macstart; unsigned char *p, *macstart; const unsigned char *const_p; int len, slen_full, slen; SSL_SESSION *sess; unsigned int hlen; EVP_CIPHER_CTX ctx; HMAC_CTX hctx; SSL_CTX *tctx = s->initial_ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key_name[16]; Loading @@ -3313,32 +3315,38 @@ int ssl3_send_newsession_ticket(SSL *s) * Some length values are 16 bits, so forget it if session is too * long */ if (slen_full > 0xFF00) if (slen_full == 0 || slen_full > 0xFF00) return -1; senc = OPENSSL_malloc(slen_full); if (!senc) return -1; EVP_CIPHER_CTX_init(&ctx); HMAC_CTX_init(&hctx); p = senc; i2d_SSL_SESSION(s->session, &p); if (!i2d_SSL_SESSION(s->session, &p)) goto err; /* * create a fresh copy (not shared with other threads) to clean up */ const_p = senc; sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); if (sess == NULL) { OPENSSL_free(senc); return -1; } if (sess == NULL) goto err; sess->session_id_length = 0; /* ID is irrelevant for the ticket */ slen = i2d_SSL_SESSION(sess, NULL); if (slen > slen_full) { /* shouldn't ever happen */ OPENSSL_free(senc); return -1; if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ SSL_SESSION_free(sess); goto err; } p = senc; i2d_SSL_SESSION(sess, &p); if (!i2d_SSL_SESSION(sess, &p)) { SSL_SESSION_free(sess); goto err; } SSL_SESSION_free(sess); /*- Loading @@ -3352,31 +3360,30 @@ int ssl3_send_newsession_ticket(SSL *s) if (!BUF_MEM_grow(s->init_buf, 26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) return -1; goto err; p = (unsigned char *)s->init_buf->data; /* do the header */ *(p++) = SSL3_MT_NEWSESSION_TICKET; /* Skip message length for now */ p += 3; EVP_CIPHER_CTX_init(&ctx); HMAC_CTX_init(&hctx); /* * Initialize HMAC and cipher contexts. If callback present it does * all the work otherwise use generated values from parent ctx. */ if (tctx->tlsext_ticket_key_cb) { if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, &hctx, 1) < 0) { OPENSSL_free(senc); return -1; } &hctx, 1) < 0) goto err; } else { RAND_pseudo_bytes(iv, 16); EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, iv); HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL); if (RAND_bytes(iv, 16) <= 0) goto err; if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, iv)) goto err; if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL)) goto err; memcpy(key_name, tctx->tlsext_tick_key_name, 16); } Loading @@ -3397,14 +3404,19 @@ int ssl3_send_newsession_ticket(SSL *s) memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); p += EVP_CIPHER_CTX_iv_length(&ctx); /* Encrypt session data */ EVP_EncryptUpdate(&ctx, p, &len, senc, slen); if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) goto err; p += len; EVP_EncryptFinal(&ctx, p, &len); if (!EVP_EncryptFinal(&ctx, p, &len)) goto err; p += len; EVP_CIPHER_CTX_cleanup(&ctx); HMAC_Update(&hctx, macstart, p - macstart); HMAC_Final(&hctx, p, &hlen); if (!HMAC_Update(&hctx, macstart, p - macstart)) goto err; if (!HMAC_Final(&hctx, p, &hlen)) goto err; EVP_CIPHER_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&hctx); p += hlen; Loading @@ -3425,6 +3437,12 @@ int ssl3_send_newsession_ticket(SSL *s) /* SSL3_ST_SW_SESSION_TICKET_B */ return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); err: if (senc) OPENSSL_free(senc); EVP_CIPHER_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&hctx); return -1; } int ssl3_send_cert_status(SSL *s) Loading