summaryrefslogtreecommitdiffstats
path: root/src/ssl/s3_both.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl/s3_both.c')
-rw-r--r--src/ssl/s3_both.c75
1 files changed, 36 insertions, 39 deletions
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index a34d221..b78f6d3 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -116,6 +116,7 @@
#include <string.h>
#include <openssl/buf.h>
+#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/md5.h>
@@ -124,7 +125,7 @@
#include <openssl/sha.h>
#include <openssl/x509.h>
-#include "ssl_locl.h"
+#include "internal.h"
/* ssl3_do_write sends |s->init_buf| in records of type 'type'
@@ -173,8 +174,7 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) {
return 0;
}
- /* Copy the finished so we can use it for
- * renegotiation checks */
+ /* Copy the finished so we can use it for renegotiation checks */
if (s->server) {
assert(n <= EVP_MAX_MD_SIZE);
memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, n);
@@ -185,7 +185,9 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) {
s->s3->previous_client_finished_len = n;
}
- ssl_set_handshake_header(s, SSL3_MT_FINISHED, n);
+ if (!ssl_set_handshake_header(s, SSL3_MT_FINISHED, n)) {
+ return 0;
+ }
s->state = b;
}
@@ -224,7 +226,7 @@ int ssl3_get_finished(SSL *s, int a, int b) {
message_len =
s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, EVP_MAX_MD_SIZE,
- SSL_GET_MESSAGE_DONT_HASH_MESSAGE, &ok);
+ ssl_dont_hash_message, &ok);
if (!ok) {
return message_len;
@@ -232,7 +234,9 @@ int ssl3_get_finished(SSL *s, int a, int b) {
/* Snapshot the finished hash before incorporating the new message. */
ssl3_take_mac(s);
- ssl3_hash_current_message(s);
+ if (!ssl3_hash_current_message(s)) {
+ goto err;
+ }
/* If this occurs, we have missed a message.
* TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */
@@ -273,6 +277,7 @@ int ssl3_get_finished(SSL *s, int a, int b) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
+err:
return 0;
}
@@ -296,11 +301,17 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b) {
return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
}
-unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) {
+int ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) {
uint8_t *p;
unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
- if (!ssl_add_cert_chain(s, cpk, &l)) {
+ if (cpk == NULL) {
+ /* TLSv1 sends a chain with nothing in it, instead of an alert. */
+ if (!BUF_MEM_grow_clean(s->init_buf, l)) {
+ OPENSSL_PUT_ERROR(SSL, ssl3_output_cert_chain, ERR_R_BUF_LIB);
+ return 0;
+ }
+ } else if (!ssl_add_cert_chain(s, cpk, &l)) {
return 0;
}
@@ -308,25 +319,24 @@ unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) {
p = ssl_handshake_start(s);
l2n3(l, p);
l += 3;
- ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l);
- return l + SSL_HM_HEADER_LENGTH(s);
+ return ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l);
}
/* Obtain handshake message of message type |msg_type| (any if |msg_type| == -1),
* maximum acceptable body length |max|. The first four bytes (msg_type and
* length) are read in state |header_state|, the body is read in state |body_state|. */
long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
- long max, int hash_message, int *ok) {
+ long max, enum ssl_hash_message_t hash_message, int *ok) {
uint8_t *p;
unsigned long l;
long n;
int al;
if (s->s3->tmp.reuse_message) {
- /* A SSL_GET_MESSAGE_DONT_HASH_MESSAGE call cannot be combined with
- * reuse_message; the SSL_GET_MESSAGE_DONT_HASH_MESSAGE would have to have
- * been applied to the previous call. */
- assert(hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE);
+ /* A ssl_dont_hash_message call cannot be combined with reuse_message; the
+ * ssl_dont_hash_message would have to have been applied to the previous
+ * call. */
+ assert(hash_message == ssl_hash_message);
s->s3->tmp.reuse_message = 0;
if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -350,7 +360,6 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
int bytes_read = s->method->ssl_read_bytes(
s, SSL3_RT_HANDSHAKE, &p[s->init_num], 4 - s->init_num, 0);
if (bytes_read <= 0) {
- s->rwstate = SSL_READING;
*ok = 0;
return bytes_read;
}
@@ -416,8 +425,8 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
}
/* Feed this message into MAC computation. */
- if (hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE) {
- ssl3_hash_current_message(s);
+ if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) {
+ goto err;
}
if (s->msg_callback) {
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
@@ -434,11 +443,12 @@ err:
return -1;
}
-void ssl3_hash_current_message(SSL *s) {
+int ssl3_hash_current_message(SSL *s) {
/* The handshake header (different size between DTLS and TLS) is included in
* the hash. */
size_t header_len = s->init_msg - (uint8_t *)s->init_buf->data;
- ssl3_finish_mac(s, (uint8_t *)s->init_buf->data, s->init_num + header_len);
+ return ssl3_finish_mac(s, (uint8_t *)s->init_buf->data,
+ s->init_num + header_len);
}
/* ssl3_cert_verify_hash is documented as needing EVP_MAX_MD_SIZE because that
@@ -586,8 +596,7 @@ int ssl3_setup_read_buffer(SSL *s) {
#endif
if (s->s3->rbuf.buf == NULL) {
- len = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_ENCRYPTED_OVERHEAD +
- headerlen + align;
+ len = SSL3_RT_MAX_ENCRYPTED_LENGTH + headerlen + align;
if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
s->s3->init_extra = 1;
len += SSL3_RT_MAX_EXTRA;
@@ -645,28 +654,16 @@ err:
return 0;
}
-
-int ssl3_setup_buffers(SSL *s) {
- if (!ssl3_setup_read_buffer(s) ||
- !ssl3_setup_write_buffer(s)) {
- return 0;
- }
- return 1;
-}
-
int ssl3_release_write_buffer(SSL *s) {
- if (s->s3->wbuf.buf != NULL) {
- OPENSSL_free(s->s3->wbuf.buf);
- s->s3->wbuf.buf = NULL;
- }
+ OPENSSL_free(s->s3->wbuf.buf);
+ s->s3->wbuf.buf = NULL;
return 1;
}
int ssl3_release_read_buffer(SSL *s) {
- if (s->s3->rbuf.buf != NULL) {
- OPENSSL_free(s->s3->rbuf.buf);
- s->s3->rbuf.buf = NULL;
- }
+ OPENSSL_free(s->s3->rbuf.buf);
+ s->s3->rbuf.buf = NULL;
+ s->packet = NULL;
return 1;
}