/* Return enum socket_error on error, bytes written on success. */ ssize_t ssl_write(struct socket *socket, unsigned char *data, int len) { ssize_t wr = ssl_do_write(socket, data, len); if (wr <= 0) { #ifdef USE_OPENSSL int err = SSL_get_error((SSL *)socket->ssl, wr); #elif defined(CONFIG_GNUTLS) int err = wr; #endif if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_WRITE2) { return -1; } if (!wr) return SOCKET_CANT_WRITE; if (err == SSL_ERROR_SYSCALL) return SOCKET_SYSCALL_ERROR; errno = S_SSL_ERROR; return SOCKET_INTERNAL_ERROR; } return wr; }
int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) { uint8_t *p; int i; unsigned long l; if (s->state == a) { p = ssl_handshake_start(s); i = s->method->ssl3_enc->final_finish_mac(s, sender, slen, s->s3->tmp.finish_md); if (i <= 0) return 0; s->s3->tmp.finish_md_len = i; memcpy(p, s->s3->tmp.finish_md, i); l = i; /* Copy the finished so we can use it for renegotiation checks */ if (s->type == SSL_ST_CONNECT) { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); s->s3->previous_client_finished_len = i; } else { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); s->s3->previous_server_finished_len = i; } ssl_set_handshake_header(s, SSL3_MT_FINISHED, l); s->state = b; } /* SSL3_ST_SEND_xxxxxx_HELLO_B */ return ssl_do_write(s); }
int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) { unsigned char *p; int i; unsigned long l; if (s->state == a) { p = ssl_handshake_start(s); i=s->method->ssl3_enc->final_finish_mac(s, sender,slen,s->s3->tmp.finish_md); if (i == 0) return 0; s->s3->tmp.finish_md_len = i; memcpy(p, s->s3->tmp.finish_md, i); l=i; /* Copy the finished so we can use it for renegotiation checks */ if(s->type == SSL_ST_CONNECT) { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); s->s3->previous_client_finished_len=i; } else { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); s->s3->previous_server_finished_len=i; } #ifdef OPENSSL_SYS_WIN16 /* MSVC 1.5 does not clear the top bytes of the word unless * I do this. */ l&=0xffff; #endif ssl_set_handshake_header(s, SSL3_MT_FINISHED, l); s->state=b; } /* SSL3_ST_SEND_xxxxxx_HELLO_B */ return ssl_do_write(s); }
int ssl3_send_finished(SSL *ssl, int a, int b) { uint8_t *p; int n; if (ssl->state == a) { p = ssl_handshake_start(ssl); n = ssl->s3->enc_method->final_finish_mac(ssl, ssl->server, ssl->s3->tmp.finish_md); if (n == 0) { return 0; } ssl->s3->tmp.finish_md_len = n; memcpy(p, ssl->s3->tmp.finish_md, n); /* Log the master secret, if logging is enabled. */ if (!ssl_log_master_secret(ssl, ssl->s3->client_random, SSL3_RANDOM_SIZE, ssl->session->master_key, ssl->session->master_key_length)) { return 0; } /* Copy the finished so we can use it for renegotiation checks */ if (ssl->server) { assert(n <= EVP_MAX_MD_SIZE); memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.finish_md, n); ssl->s3->previous_server_finished_len = n; } else { assert(n <= EVP_MAX_MD_SIZE); memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.finish_md, n); ssl->s3->previous_client_finished_len = n; } if (!ssl_set_handshake_header(ssl, SSL3_MT_FINISHED, n)) { return 0; } ssl->state = b; } /* SSL3_ST_SEND_xxxxxx_HELLO_B */ return ssl_do_write(ssl); }