X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=ad590e5116103dcc54ff0a474b3bd486888403a6;hp=2bb1866b8c216dd43484fdb9f684cbb25f64aa9f;hb=fe3a329117dbb04a17ca2cb9fc9e3493dc7f03ab;hpb=5b18d3025c1c1d36be8f81f137265b46da58f881 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 2bb1866b8c..ad590e5116 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -147,7 +147,6 @@ #endif #include #include "ssl_locl.h" -#include "kssl_lcl.h" #include #include #include @@ -160,7 +159,7 @@ # include #endif -const char *SSL_version_str = OPENSSL_VERSION_TEXT; +const char SSL_version_str[] = OPENSSL_VERSION_TEXT; SSL3_ENC_METHOD ssl3_undef_enc_method = { /* @@ -187,9 +186,16 @@ SSL3_ENC_METHOD ssl3_undef_enc_method = { int use_context))ssl_undefined_function, }; -int SSL_clear(SSL *s) +static void clear_ciphers(SSL *s) { + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} +int SSL_clear(SSL *s) +{ if (s->method == NULL) { SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); return (0); @@ -204,46 +210,22 @@ int SSL_clear(SSL *s) s->hit = 0; s->shutdown = 0; -#if 0 - /* - * Disabled since version 1.10 of this file (early return not - * needed because SSL_clear is not called when doing renegotiation) - */ - /* - * This is set if we are doing dynamic renegotiation so keep - * the old cipher. It is sort of a SSL_clear_lite :-) - */ - if (s->renegotiate) - return (1); -#else if (s->renegotiate) { SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); return 0; } -#endif - s->type = 0; - - s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); + ossl_statem_clear(s); s->version = s->method->version; s->client_version = s->version; s->rwstate = SSL_NOTHING; - s->rstate = SSL_ST_READ_HEADER; -#if 0 - s->read_ahead = s->ctx->read_ahead; -#endif - - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + clear_ciphers(s); s->first_packet = 0; + s->no_cert_verify = 0; /* * Check to see if we were changed into a different method, if so, revert @@ -257,6 +239,9 @@ int SSL_clear(SSL *s) return (0); } else s->method->ssl_clear(s); + + RECORD_LAYER_clear(&s->rlayer); + return (1); } @@ -291,44 +276,35 @@ SSL *SSL_new(SSL_CTX *ctx) return (NULL); } - s = (SSL *)OPENSSL_malloc(sizeof(SSL)); + s = OPENSSL_zalloc(sizeof(*s)); if (s == NULL) goto err; - memset(s, 0, sizeof(SSL)); -#ifndef OPENSSL_NO_KRB5 - s->kssl_ctx = kssl_ctx_new(); -#endif /* OPENSSL_NO_KRB5 */ + RECORD_LAYER_init(&s->rlayer, s); s->options = ctx->options; s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; + s->references = 1; - if (ctx->cert != NULL) { - /* - * Earlier library versions used to copy the pointer to the CERT, not - * its contents; only when setting new parameters for the per-SSL - * copy, ssl_cert_new would be called (and the direct reference to - * the per-SSL_CTX settings would be lost, but those still were - * indirectly accessed for various purposes, and for that reason they - * used to be known as s->ctx->default_cert). Now we don't look at the - * SSL_CTX's CERT after having duplicated it once. - */ - - s->cert = ssl_cert_dup(ctx->cert); - if (s->cert == NULL) - goto err; - } else - s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */ + /* + * Earlier library versions used to copy the pointer to the CERT, not + * its contents; only when setting new parameters for the per-SSL + * copy, ssl_cert_new would be called (and the direct reference to + * the per-SSL_CTX settings would be lost, but those still were + * indirectly accessed for various purposes, and for that reason they + * used to be known as s->ctx->default_cert). Now we don't look at the + * SSL_CTX's CERT after having duplicated it once. + */ + s->cert = ssl_cert_dup(ctx->cert); + if (s->cert == NULL) + goto err; - s->read_ahead = ctx->read_ahead; + RECORD_LAYER_set_read_ahead(&s->rlayer, ctx->read_ahead); s->msg_callback = ctx->msg_callback; s->msg_callback_arg = ctx->msg_callback_arg; s->verify_mode = ctx->verify_mode; s->not_resumable_session_cb = ctx->not_resumable_session_cb; -#if 0 - s->verify_depth = ctx->verify_depth; -#endif s->sid_ctx_length = ctx->sid_ctx_length; OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); @@ -339,16 +315,11 @@ SSL *SSL_new(SSL_CTX *ctx) if (!s->param) goto err; X509_VERIFY_PARAM_inherit(s->param, ctx->param); -#if 0 - s->purpose = ctx->purpose; - s->trust = ctx->trust; -#endif s->quiet_shutdown = ctx->quiet_shutdown; s->max_send_fragment = ctx->max_send_fragment; CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); s->ctx = ctx; -#ifndef OPENSSL_NO_TLSEXT s->tlsext_debug_cb = 0; s->tlsext_debug_arg = NULL; s->tlsext_ticket_expected = 0; @@ -393,7 +364,6 @@ SSL *SSL_new(SSL_CTX *ctx) s->ctx->alpn_client_proto_list_len); s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; } -#endif s->verify_result = X509_V_OK; @@ -402,10 +372,10 @@ SSL *SSL_new(SSL_CTX *ctx) if (!s->method->ssl_new(s)) goto err; - s->references = 1; s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; - SSL_clear(s); + if (!SSL_clear(s)) + goto err; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); @@ -416,8 +386,7 @@ SSL *SSL_new(SSL_CTX *ctx) return (s); err: - if (s != NULL) - SSL_free(s); + SSL_free(s); SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); return (NULL); } @@ -556,9 +525,7 @@ void SSL_free(SSL *s) } #endif - if (s->param) - X509_VERIFY_PARAM_free(s->param); - + X509_VERIFY_PARAM_free(s->param); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); if (s->bbio != NULL) { @@ -569,19 +536,15 @@ void SSL_free(SSL *s) BIO_free(s->bbio); s->bbio = NULL; } - if (s->rbio != NULL) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != s->rbio)) + BIO_free_all(s->rbio); + if (s->wbio != s->rbio) BIO_free_all(s->wbio); - if (s->init_buf != NULL) - BUF_MEM_free(s->init_buf); + BUF_MEM_free(s->init_buf); /* add extra stuff */ - if (s->cipher_list != NULL) - sk_SSL_CIPHER_free(s->cipher_list); - if (s->cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(s->cipher_list_by_id); + sk_SSL_CIPHER_free(s->cipher_list); + sk_SSL_CIPHER_free(s->cipher_list_by_id); /* Make the next call work :-) */ if (s->session != NULL) { @@ -589,63 +552,50 @@ void SSL_free(SSL *s) SSL_SESSION_free(s->session); } - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); - if (s->cert != NULL) - ssl_cert_free(s->cert); + ssl_cert_free(s->cert); /* Free up if allocated */ -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_hostname) - OPENSSL_free(s->tlsext_hostname); - if (s->initial_ctx) - SSL_CTX_free(s->initial_ctx); -# ifndef OPENSSL_NO_EC - if (s->tlsext_ecpointformatlist) - OPENSSL_free(s->tlsext_ecpointformatlist); - if (s->tlsext_ellipticcurvelist) - OPENSSL_free(s->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ - if (s->tlsext_ocsp_exts) - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); - if (s->tlsext_ocsp_ids) - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); - if (s->tlsext_ocsp_resp) - OPENSSL_free(s->tlsext_ocsp_resp); - if (s->alpn_client_proto_list) - OPENSSL_free(s->alpn_client_proto_list); -#endif + OPENSSL_free(s->tlsext_hostname); + SSL_CTX_free(s->initial_ctx); +#ifndef OPENSSL_NO_EC + OPENSSL_free(s->tlsext_ecpointformatlist); + OPENSSL_free(s->tlsext_ellipticcurvelist); +#endif /* OPENSSL_NO_EC */ + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + OPENSSL_free(s->tlsext_ocsp_resp); + OPENSSL_free(s->alpn_client_proto_list); - if (s->client_CA != NULL) - sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); + sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); if (s->method != NULL) s->method->ssl_free(s); - if (s->ctx) - SSL_CTX_free(s->ctx); + RECORD_LAYER_release(&s->rlayer); -#ifndef OPENSSL_NO_KRB5 - if (s->kssl_ctx != NULL) - kssl_ctx_free(s->kssl_ctx); -#endif /* OPENSSL_NO_KRB5 */ + SSL_CTX_free(s->ctx); -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - if (s->next_proto_negotiated) - OPENSSL_free(s->next_proto_negotiated); +#if !defined(OPENSSL_NO_NEXTPROTONEG) + OPENSSL_free(s->next_proto_negotiated); #endif #ifndef OPENSSL_NO_SRTP - if (s->srtp_profiles) - sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); + sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); #endif OPENSSL_free(s); } -void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +void SSL_set_rbio(SSL *s, BIO *rbio) +{ + if (s->rbio != rbio) + BIO_free_all(s->rbio); + s->rbio = rbio; +} + +void SSL_set_wbio(SSL *s, BIO *wbio) { /* * If the output buffering BIO is still in place, remove it @@ -656,14 +606,17 @@ void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) s->bbio->next_bio = NULL; } } - if ((s->rbio != NULL) && (s->rbio != rbio)) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio)) + if (s->wbio != wbio && s->rbio != s->wbio) BIO_free_all(s->wbio); - s->rbio = rbio; s->wbio = wbio; } +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +{ + SSL_set_wbio(s, wbio); + SSL_set_rbio(s, rbio); +} + BIO *SSL_get_rbio(const SSL *s) { return (s->rbio); @@ -838,12 +791,12 @@ void SSL_set_verify_depth(SSL *s, int depth) void SSL_set_read_ahead(SSL *s, int yes) { - s->read_ahead = yes; + RECORD_LAYER_set_read_ahead(&s->rlayer, yes); } int SSL_get_read_ahead(const SSL *s) { - return (s->read_ahead); + return RECORD_LAYER_get_read_ahead(&s->rlayer); } int SSL_pending(const SSL *s) @@ -870,7 +823,7 @@ X509 *SSL_get_peer_certificate(const SSL *s) if (r == NULL) return (r); - CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); + X509_up_ref(r); return (r); } @@ -879,11 +832,10 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) { STACK_OF(X509) *r; - if ((s == NULL) || (s->session == NULL) - || (s->session->sess_cert == NULL)) + if ((s == NULL) || (s->session == NULL)) r = NULL; else - r = s->session->sess_cert->cert_chain; + r = s->session->peer_chain; /* * If we are a client, cert_chain includes the peer's own certificate; if @@ -897,12 +849,12 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) * Now in theory, since the calling process own 't' it should be safe to * modify. We need to be able to read f without being hassled */ -void SSL_copy_session_id(SSL *t, const SSL *f) +int SSL_copy_session_id(SSL *t, const SSL *f) { - CERT *tmp; - /* Do we need to to SSL locking? */ - SSL_set_session(t, SSL_get_session(f)); + if (!SSL_set_session(t, SSL_get_session(f))) { + return 0; + } /* * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa @@ -913,22 +865,21 @@ void SSL_copy_session_id(SSL *t, const SSL *f) t->method->ssl_new(t); /* setup new */ } - tmp = t->cert; - if (f->cert != NULL) { - CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - t->cert = f->cert; - } else - t->cert = NULL; - if (tmp != NULL) - ssl_cert_free(tmp); - SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); + CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + ssl_cert_free(t->cert); + t->cert = f->cert; + if (!SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length)) { + return 0; + } + + return 1; } /* Fix this so it checks all the valid key/cert options */ int SSL_CTX_check_private_key(const SSL_CTX *ctx) { if ((ctx == NULL) || - (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) { + (ctx->cert->key->x509 == NULL)) { SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); return (0); @@ -949,10 +900,6 @@ int SSL_check_private_key(const SSL *ssl) SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); return (0); } - if (ssl->cert == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); - return 0; - } if (ssl->cert->key->x509 == NULL) { SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); return (0); @@ -1085,10 +1032,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) switch (cmd) { case SSL_CTRL_GET_READ_AHEAD: - return (s->read_ahead); + return (RECORD_LAYER_get_read_ahead(&s->rlayer)); case SSL_CTRL_SET_READ_AHEAD: - l = s->read_ahead; - s->read_ahead = larg; + l = RECORD_LAYER_get_read_ahead(&s->rlayer); + RECORD_LAYER_set_read_ahead(&s->rlayer, larg); return (l); case SSL_CTRL_SET_MSG_CALLBACK_ARG: @@ -1126,12 +1073,13 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_RAW_CIPHERLIST: if (parg) { - if (s->cert->ciphers_raw == NULL) + if (s->s3->tmp.ciphers_raw == NULL) return 0; - *(unsigned char **)parg = s->cert->ciphers_raw; - return (int)s->cert->ciphers_rawlen; - } else - return ssl_put_cipher_by_char(s, NULL, NULL); + *(unsigned char **)parg = s->s3->tmp.ciphers_raw; + return (int)s->s3->tmp.ciphers_rawlen; + } else { + return TLS_CIPHER_LEN; + } case SSL_CTRL_GET_EXTMS_SUPPORT: if (!s->session || SSL_in_init(s) || s->in_handshake) return -1; @@ -1312,6 +1260,13 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) return (NULL); } +STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s) +{ + if ((s == NULL) || (s->session == NULL) || !s->server) + return NULL; + return s->session->ciphers; +} + STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s) { STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers; @@ -1444,162 +1399,6 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) return (buf); } -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)) -{ - int i, j = 0; - SSL_CIPHER *c; - unsigned char *q; - int empty_reneg_info_scsv = !s->renegotiate; - /* Set disabled masks for this session */ - ssl_set_client_disabled(s); - - if (sk == NULL) - return (0); - q = p; - if (put_cb == NULL) - put_cb = s->method->put_cipher_by_char; - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - /* Skip disabled ciphers */ - if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) - continue; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (c->id == SSL3_CK_SCSV) { - if (!empty_reneg_info_scsv) - continue; - else - empty_reneg_info_scsv = 0; - } -#endif - j = put_cb(c, p); - p += j; - } - /* - * If p == q, no ciphers; caller indicates an error. Otherwise, add - * applicable SCSVs. - */ - if (p != q) { - if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); -#endif - } - if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; - } - } - - return (p - q); -} - -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp) -{ - const SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - int i, n; - - if (s->s3) - s->s3->send_connection_binding = 0; - - n = ssl_put_cipher_by_char(s, NULL, NULL); - if (n == 0 || (num % n) != 0) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); - return (NULL); - } - if ((skp == NULL) || (*skp == NULL)) - sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ - else { - sk = *skp; - sk_SSL_CIPHER_zero(sk); - } - - if (s->cert->ciphers_raw) - OPENSSL_free(s->cert->ciphers_raw); - s->cert->ciphers_raw = BUF_memdup(p, num); - if (s->cert->ciphers_raw == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - s->cert->ciphers_rawlen = (size_t)num; - - for (i = 0; i < num; i += n) { - /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ - if (s->s3 && (n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { - /* SCSV fatal if renegotiating */ - if (s->renegotiate) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - s->s3->send_connection_binding = 1; - p += n; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "SCSV received by server\n"); -#endif - continue; - } - - /* Check for TLS_FALLBACK_SCSV */ - if ((n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { - /* - * The SCSV indicates that the client previously tried a higher - * version. Fail if the current version is an unexpected - * downgrade. - */ - if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_INAPPROPRIATE_FALLBACK); - if (s->s3) - ssl3_send_alert(s, SSL3_AL_FATAL, - SSL_AD_INAPPROPRIATE_FALLBACK); - goto err; - } - p += n; - continue; - } - - c = ssl_get_cipher_by_char(s, p); - p += n; - if (c != NULL) { - if (!sk_SSL_CIPHER_push(sk, c)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } - - if (skp != NULL) - *skp = sk; - return (sk); - err: - if ((skp == NULL) || (*skp == NULL)) - sk_SSL_CIPHER_free(sk); - return (NULL); -} - -#ifndef OPENSSL_NO_TLSEXT /** return a servername extension value if provided in Client Hello, or NULL. * So far, only host_name types are defined (RFC 3546). */ @@ -1681,7 +1480,7 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, return status; } -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG /* * SSL_get0_next_proto_negotiated sets *data and *len to point to the * client's requested protocol for this connection and returns 0. If the @@ -1742,7 +1541,7 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, ctx->next_proto_select_cb = cb; ctx->next_proto_select_cb_arg = arg; } -# endif +#endif /* * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. @@ -1752,9 +1551,7 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned protos_len) { - if (ctx->alpn_client_proto_list) - OPENSSL_free(ctx->alpn_client_proto_list); - + OPENSSL_free(ctx->alpn_client_proto_list); ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len); if (!ctx->alpn_client_proto_list) return 1; @@ -1772,9 +1569,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, unsigned protos_len) { - if (ssl->alpn_client_proto_list) - OPENSSL_free(ssl->alpn_client_proto_list); - + OPENSSL_free(ssl->alpn_client_proto_list); ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len); if (!ssl->alpn_client_proto_list) return 1; @@ -1819,7 +1614,6 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, *len = ssl->s3->alpn_selected_len; } -#endif /* !OPENSSL_NO_TLSEXT */ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const char *label, size_t llen, @@ -1889,63 +1683,21 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); goto err; } - ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); + ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) goto err; - memset(ret, 0, sizeof(SSL_CTX)); - ret->method = meth; - - ret->cert_store = NULL; ret->session_cache_mode = SSL_SESS_CACHE_SERVER; ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; - ret->session_cache_head = NULL; - ret->session_cache_tail = NULL; - - /* We take the system default */ + /* We take the system default. */ ret->session_timeout = meth->get_timeout(); - - ret->new_session_cb = 0; - ret->remove_session_cb = 0; - ret->get_session_cb = 0; - ret->generate_session_id = 0; - - memset((char *)&ret->stats, 0, sizeof(ret->stats)); - ret->references = 1; - ret->quiet_shutdown = 0; - -/* ret->cipher=NULL;*/ -/*- - ret->s2->challenge=NULL; - ret->master_key=NULL; - ret->s2->conn_id=NULL; */ - - ret->info_callback = NULL; - - ret->app_verify_callback = 0; - ret->app_verify_arg = NULL; - ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; - ret->read_ahead = 0; - ret->msg_callback = 0; - ret->msg_callback_arg = NULL; ret->verify_mode = SSL_VERIFY_NONE; -#if 0 - ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */ -#endif - ret->sid_ctx_length = 0; - ret->default_verify_callback = NULL; if ((ret->cert = ssl_cert_new()) == NULL) goto err; - ret->default_passwd_callback = 0; - ret->default_passwd_callback_userdata = NULL; - ret->client_cert_cb = 0; - ret->app_gen_cookie_cb = 0; - ret->app_verify_cookie_cb = 0; - ret->sessions = lh_SSL_SESSION_new(); if (ret->sessions == NULL) goto err; @@ -1953,10 +1705,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (ret->cert_store == NULL) goto err; - ssl_create_cipher_list(ret->method, + if (!ssl_create_cipher_list(ret->method, &ret->cipher_list, &ret->cipher_list_by_id, - SSL_DEFAULT_CIPHER_LIST, ret->cert); - if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { + SSL_DEFAULT_CIPHER_LIST, ret->cert) + || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); goto err2; } @@ -1979,40 +1731,23 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); - ret->extra_certs = NULL; /* No compression for DTLS */ if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) ret->comp_methods = SSL_COMP_get_compression_methods(); ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; -#ifndef OPENSSL_NO_TLSEXT - ret->tlsext_servername_callback = 0; - ret->tlsext_servername_arg = NULL; /* Setup RFC4507 ticket keys */ - if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) ret->options |= SSL_OP_NO_TICKET; - ret->tlsext_status_cb = 0; - ret->tlsext_status_arg = NULL; - -# ifndef OPENSSL_NO_NEXTPROTONEG - ret->next_protos_advertised_cb = 0; - ret->next_proto_select_cb = 0; -# endif -#endif -#ifndef OPENSSL_NO_PSK - ret->psk_identity_hint = NULL; - ret->psk_client_callback = NULL; - ret->psk_server_callback = NULL; -#endif #ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_init(ret); + if (!SSL_CTX_SRP_CTX_init(ret)) + goto err; #endif #ifndef OPENSSL_NO_ENGINE - ret->client_cert_engine = NULL; # ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO # define eng_strx(x) #x # define eng_str(x) eng_strx(x) @@ -2040,8 +1775,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) err: SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); err2: - if (ret != NULL) - SSL_CTX_free(ret); + SSL_CTX_free(ret); return (NULL); } @@ -2065,8 +1799,7 @@ void SSL_CTX_free(SSL_CTX *a) } #endif - if (a->param) - X509_VERIFY_PARAM_free(a->param); + X509_VERIFY_PARAM_free(a->param); /* * Free internal session cache. However: the remove_cb() may reference @@ -2081,38 +1814,16 @@ void SSL_CTX_free(SSL_CTX *a) SSL_CTX_flush_sessions(a, 0); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); - - if (a->sessions != NULL) - lh_SSL_SESSION_free(a->sessions); - - if (a->cert_store != NULL) - X509_STORE_free(a->cert_store); - if (a->cipher_list != NULL) - sk_SSL_CIPHER_free(a->cipher_list); - if (a->cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(a->cipher_list_by_id); - if (a->cert != NULL) - ssl_cert_free(a->cert); - if (a->client_CA != NULL) - sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); - if (a->extra_certs != NULL) - sk_X509_pop_free(a->extra_certs, X509_free); -#if 0 /* This should never be done, since it - * removes a global database */ - if (a->comp_methods != NULL) - sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free); -#else + lh_SSL_SESSION_free(a->sessions); + X509_STORE_free(a->cert_store); + sk_SSL_CIPHER_free(a->cipher_list); + sk_SSL_CIPHER_free(a->cipher_list_by_id); + ssl_cert_free(a->cert); + sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); + sk_X509_pop_free(a->extra_certs, X509_free); a->comp_methods = NULL; -#endif - #ifndef OPENSSL_NO_SRTP - if (a->srtp_profiles) - sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); -#endif - -#ifndef OPENSSL_NO_PSK - if (a->psk_identity_hint) - OPENSSL_free(a->psk_identity_hint); + sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); #endif #ifndef OPENSSL_NO_SRP SSL_CTX_SRP_CTX_free(a); @@ -2122,16 +1833,11 @@ void SSL_CTX_free(SSL_CTX *a) ENGINE_finish(a->client_cert_engine); #endif -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC - if (a->tlsext_ecpointformatlist) - OPENSSL_free(a->tlsext_ecpointformatlist); - if (a->tlsext_ellipticcurvelist) - OPENSSL_free(a->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ - if (a->alpn_client_proto_list != NULL) - OPENSSL_free(a->alpn_client_proto_list); +#ifndef OPENSSL_NO_EC + OPENSSL_free(a->tlsext_ecpointformatlist); + OPENSSL_free(a->tlsext_ellipticcurvelist); #endif + OPENSSL_free(a->alpn_client_proto_list); OPENSSL_free(a); } @@ -2177,23 +1883,21 @@ void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) ssl_cert_set_cert_cb(s->cert, cb, arg); } -void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) +void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher) { CERT_PKEY *cpk; + CERT *c = s->cert; + uint32_t *pvalid = s->s3->tmp.valid_flags; int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign; int rsa_enc_export, dh_rsa_export, dh_dsa_export; int rsa_tmp_export, dh_tmp_export, kl; unsigned long mask_k, mask_a, emask_k, emask_a; -#ifndef OPENSSL_NO_ECDSA +#ifndef OPENSSL_NO_EC int have_ecc_cert, ecdsa_ok, ecc_pkey_size; -#endif -#ifndef OPENSSL_NO_ECDH int have_ecdh_tmp, ecdh_ok; -#endif -#ifndef OPENSSL_NO_EC X509 *x = NULL; EVP_PKEY *ecc_pkey = NULL; - int signature_nid = 0, pk_nid = 0, md_nid = 0; + int pk_nid = 0, md_nid = 0; #endif if (c == NULL) return; @@ -2216,26 +1920,25 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) dh_tmp = dh_tmp_export = 0; #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); #endif cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); - rsa_enc = cpk->valid_flags & CERT_PKEY_VALID; + rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID; rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); - rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; + rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN; cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); - dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; + dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN; cpk = &(c->pkeys[SSL_PKEY_DH_RSA]); - dh_rsa = cpk->valid_flags & CERT_PKEY_VALID; + dh_rsa = pvalid[SSL_PKEY_DH_RSA] & CERT_PKEY_VALID; dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); cpk = &(c->pkeys[SSL_PKEY_DH_DSA]); -/* FIX THIS EAY EAY EAY */ - dh_dsa = cpk->valid_flags & CERT_PKEY_VALID; + dh_dsa = pvalid[SSL_PKEY_DH_DSA] & CERT_PKEY_VALID; dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); cpk = &(c->pkeys[SSL_PKEY_ECC]); #ifndef OPENSSL_NO_EC - have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID; + have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID; #endif mask_k = 0; mask_a = 0; @@ -2254,26 +1957,12 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) mask_k |= SSL_kGOST; mask_a |= SSL_aGOST01; } - cpk = &(c->pkeys[SSL_PKEY_GOST94]); - if (cpk->x509 != NULL && cpk->privatekey != NULL) { - mask_k |= SSL_kGOST; - mask_a |= SSL_aGOST94; - } if (rsa_enc || (rsa_tmp && rsa_sign)) mask_k |= SSL_kRSA; if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) emask_k |= SSL_kRSA; -#if 0 - /* The match needs to be both kDHE and aRSA or aDSA, so don't worry */ - if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) - mask_k |= SSL_kDHE; - if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && - (rsa_enc || rsa_sign || dsa_sign)) - emask_k |= SSL_kDHE; -#endif - if (dh_tmp_export) emask_k |= SSL_kDHE; @@ -2290,7 +1979,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) if (dh_dsa_export) emask_k |= SSL_kDHd; - if (emask_k & (SSL_kDHr | SSL_kDHd)) + if (mask_k & (SSL_kDHr | SSL_kDHd)) mask_a |= SSL_aDH; if (rsa_enc || rsa_sign) { @@ -2306,39 +1995,24 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) mask_a |= SSL_aNULL; emask_a |= SSL_aNULL; -#ifndef OPENSSL_NO_KRB5 - mask_k |= SSL_kKRB5; - mask_a |= SSL_aKRB5; - emask_k |= SSL_kKRB5; - emask_a |= SSL_aKRB5; -#endif - /* * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites * depending on the key usage extension. */ #ifndef OPENSSL_NO_EC if (have_ecc_cert) { + uint32_t ex_kusage; cpk = &c->pkeys[SSL_PKEY_ECC]; x = cpk->x509; - /* This call populates extension flags (ex_flags) */ - X509_check_purpose(x, -1, 0); -# ifndef OPENSSL_NO_ECDH - ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; -# endif - ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; - if (!(cpk->valid_flags & CERT_PKEY_SIGN)) + ex_kusage = X509_get_key_usage(x); + ecdh_ok = ex_kusage & X509v3_KU_KEY_AGREEMENT; + ecdsa_ok = ex_kusage & X509v3_KU_DIGITAL_SIGNATURE; + if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN)) ecdsa_ok = 0; ecc_pkey = X509_get_pubkey(x); ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; EVP_PKEY_free(ecc_pkey); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } -# ifndef OPENSSL_NO_ECDH + OBJ_find_sigid_algs(X509_get_signature_nid(x), &md_nid, &pk_nid); if (ecdh_ok) { if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { @@ -2359,17 +2033,14 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) } } } -# endif -# ifndef OPENSSL_NO_ECDSA if (ecdsa_ok) { mask_a |= SSL_aECDSA; emask_a |= SSL_aECDSA; } -# endif } #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC if (have_ecdh_tmp) { mask_k |= SSL_kECDHE; emask_k |= SSL_kECDHE; @@ -2381,19 +2052,20 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) mask_a |= SSL_aPSK; emask_k |= SSL_kPSK; emask_a |= SSL_aPSK; + if (mask_k & SSL_kRSA) + mask_k |= SSL_kRSAPSK; + if (mask_k & SSL_kDHE) + mask_k |= SSL_kDHEPSK; + if (mask_k & SSL_kECDHE) + mask_k |= SSL_kECDHEPSK; #endif - c->mask_k = mask_k; - c->mask_a = mask_a; - c->export_mask_k = emask_k; - c->export_mask_a = emask_a; - c->valid = 1; + s->s3->tmp.mask_k = mask_k; + s->s3->tmp.mask_a = mask_a; + s->s3->tmp.export_mask_k = emask_k; + s->s3->tmp.export_mask_a = emask_a; } -/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) - #ifndef OPENSSL_NO_EC int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) @@ -2401,8 +2073,9 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) unsigned long alg_k, alg_a; EVP_PKEY *pkey = NULL; int keysize = 0; - int signature_nid = 0, md_nid = 0, pk_nid = 0; + int md_nid = 0, pk_nid = 0; const SSL_CIPHER *cs = s->s3->tmp.new_cipher; + uint32_t ex_kusage = X509_get_key_usage(x); alg_k = cs->algorithm_mkey; alg_a = cs->algorithm_auth; @@ -2418,15 +2091,11 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) return 0; } - /* This call populates the ex_flags field correctly */ - X509_check_purpose(x, -1, 0); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } + OBJ_find_sigid_algs(X509_get_signature_nid(x), &md_nid, &pk_nid); + if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { /* key usage, if present, must allow key agreement */ - if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { + if (!(ex_kusage & X509v3_KU_KEY_AGREEMENT)) { SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); return 0; @@ -2451,7 +2120,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) } if (alg_a & SSL_aECDSA) { /* key usage, if present, must allow signing */ - if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { + if (!(ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) { SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; @@ -2474,7 +2143,7 @@ static int ssl_get_server_cert_index(const SSL *s) return idx; } -CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) +CERT_PKEY *ssl_get_server_send_pkey(SSL *s) { CERT *c; int i; @@ -2482,7 +2151,7 @@ CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) c = s->cert; if (!s->s3 || !s->s3->tmp.new_cipher) return NULL; - ssl_set_cert_masks(c, s->s3->tmp.new_cipher); + ssl_set_masks(s, s->s3->tmp.new_cipher); #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL /* @@ -2539,11 +2208,10 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, return (NULL); } if (pmd) - *pmd = c->pkeys[idx].digest; + *pmd = s->s3->tmp.md[idx]; return c->pkeys[idx].privatekey; } -#ifndef OPENSSL_NO_TLSEXT int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, size_t *serverinfo_length) { @@ -2563,7 +2231,6 @@ int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, *serverinfo_length = c->pkeys[i].serverinfo_length; return 1; } -#endif void ssl_update_cache(SSL *s, int mode) { @@ -2725,32 +2392,22 @@ int SSL_do_handshake(SSL *s) return (ret); } -/* - * For the next 2 functions, SSL_clear() sets shutdown and so one of these - * calls will reset it - */ void SSL_set_accept_state(SSL *s) { s->server = 1; s->shutdown = 0; - s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE; + ossl_statem_clear(s); s->handshake_func = s->method->ssl_accept; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); } void SSL_set_connect_state(SSL *s) { s->server = 0; s->shutdown = 0; - s->state = SSL_ST_CONNECT | SSL_ST_BEFORE; + ossl_statem_clear(s); s->handshake_func = s->method->ssl_connect; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); } int ssl_undefined_function(SSL *s) @@ -2789,6 +2446,12 @@ const char *SSL_get_version(const SSL *s) return ("TLSv1"); else if (s->version == SSL3_VERSION) return ("SSLv3"); + else if (s->version == DTLS1_BAD_VER) + return ("DTLSv0.9"); + else if (s->version == DTLS1_VERSION) + return ("DTLSv1"); + else if (s->version == DTLS1_2_VERSION) + return ("DTLSv1.2"); else return ("unknown"); } @@ -2804,12 +2467,12 @@ SSL *SSL_dup(SSL *s) return (NULL); ret->version = s->version; - ret->type = s->type; ret->method = s->method; if (s->session != NULL) { /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ - SSL_copy_session_id(ret, s); + if (!SSL_copy_session_id(ret, s)) + goto err; } else { /* * No session has been established yet, so we have to expect that @@ -2823,15 +2486,14 @@ SSL *SSL_dup(SSL *s) ret->method->ssl_new(ret); if (s->cert != NULL) { - if (ret->cert != NULL) { - ssl_cert_free(ret->cert); - } + ssl_cert_free(ret->cert); ret->cert = ssl_cert_dup(s->cert); if (ret->cert == NULL) goto err; } - SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length); + if (!SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length)) + goto err; } ret->options = s->options; @@ -2872,9 +2534,9 @@ SSL *SSL_dup(SSL *s) ret->new_session = s->new_session; ret->quiet_shutdown = s->quiet_shutdown; ret->shutdown = s->shutdown; - ret->state = s->state; /* SSL_dup does not really work at any state, - * though */ - ret->rstate = s->rstate; + ret->statem = s->statem; /* SSL_dup does not really work at any state, + * though */ + RECORD_LAYER_dup(&ret->rlayer, &s->rlayer); ret->init_num = 0; /* would have to copy ret->init_buf, * ret->init_msg, ret->init_num, * ret->init_off */ @@ -2905,14 +2567,11 @@ SSL *SSL_dup(SSL *s) } } } + return ret; - if (0) { err: - if (ret != NULL) - SSL_free(ret); - ret = NULL; - } - return (ret); + SSL_free(ret); + return NULL; } void ssl_clear_cipher_ctx(SSL *s) @@ -2928,14 +2587,10 @@ void ssl_clear_cipher_ctx(SSL *s) s->enc_write_ctx = NULL; } #ifndef OPENSSL_NO_COMP - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } + COMP_CTX_free(s->expand); + s->expand = NULL; + COMP_CTX_free(s->compress); + s->compress = NULL; #endif } @@ -2978,32 +2633,23 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) return (NULL); } -#ifdef OPENSSL_NO_COMP -const void *SSL_get_current_compression(SSL *s) -{ - return NULL; -} - -const void *SSL_get_current_expansion(SSL *s) -{ - return NULL; -} -#else - const COMP_METHOD *SSL_get_current_compression(SSL *s) { - if (s->compress != NULL) - return (s->compress->meth); - return (NULL); +#ifndef OPENSSL_NO_COMP + return s->compress ? COMP_CTX_get_method(s->compress) : NULL; +#else + return NULL; +#endif } const COMP_METHOD *SSL_get_current_expansion(SSL *s) { - if (s->expand != NULL) - return (s->expand->meth); - return (NULL); -} +#ifndef OPENSSL_NO_COMP + return s->expand ? COMP_CTX_get_method(s->expand) : NULL; +#else + return NULL; #endif +} int ssl_init_wbio_buffer(SSL *s, int push) { @@ -3037,6 +2683,7 @@ int ssl_init_wbio_buffer(SSL *s, int push) void ssl_free_wbio_buffer(SSL *s) { + /* callers ensure s is never null */ if (s->bbio == NULL) return; @@ -3094,26 +2741,17 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { - CERT *ocert = ssl->cert; + CERT *new_cert; if (ssl->ctx == ctx) return ssl->ctx; -#ifndef OPENSSL_NO_TLSEXT if (ctx == NULL) ctx = ssl->initial_ctx; -#endif - ssl->cert = ssl_cert_dup(ctx->cert); - if (ocert) { - /* Preserve any already negotiated parameters */ - if (ssl->server) { - ssl->cert->peer_sigalgs = ocert->peer_sigalgs; - ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen; - ocert->peer_sigalgs = NULL; - ssl->cert->ciphers_raw = ocert->ciphers_raw; - ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen; - ocert->ciphers_raw = NULL; - } - ssl_cert_free(ocert); + new_cert = ssl_cert_dup(ctx->cert); + if (new_cert == NULL) { + return NULL; } + ssl_cert_free(ssl->cert); + ssl->cert = new_cert; /* * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), @@ -3135,25 +2773,53 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) } CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - if (ssl->ctx != NULL) - SSL_CTX_free(ssl->ctx); /* decrement reference count */ + SSL_CTX_free(ssl->ctx); /* decrement reference count */ ssl->ctx = ctx; return (ssl->ctx); } -#ifndef OPENSSL_NO_STDIO int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { return (X509_STORE_set_default_paths(ctx->cert_store)); } +int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return 0; + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* Clear any errors if the default directory does not exist */ + ERR_clear_error(); + + return 1; +} + +int SSL_CTX_set_default_verify_file(SSL_CTX *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_file()); + if (lookup == NULL) + return 0; + + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* Clear any errors if the default file does not exist */ + ERR_clear_error(); + + return 1; +} + int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath) { return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); } -#endif void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) @@ -3171,24 +2837,49 @@ void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , return ssl->info_callback; } -int SSL_state(const SSL *ssl) +void SSL_set_verify_result(SSL *ssl, long arg) { - return (ssl->state); + ssl->verify_result = arg; } -void SSL_set_state(SSL *ssl, int state) +long SSL_get_verify_result(const SSL *ssl) { - ssl->state = state; + return (ssl->verify_result); } -void SSL_set_verify_result(SSL *ssl, long arg) +size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen) { - ssl->verify_result = arg; + if (outlen == 0) + return sizeof(ssl->s3->client_random); + if (outlen > sizeof(ssl->s3->client_random)) + outlen = sizeof(ssl->s3->client_random); + memcpy(out, ssl->s3->client_random, outlen); + return outlen; } -long SSL_get_verify_result(const SSL *ssl) +size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen) { - return (ssl->verify_result); + if (outlen == 0) + return sizeof(ssl->s3->server_random); + if (outlen > sizeof(ssl->s3->server_random)) + outlen = sizeof(ssl->s3->server_random); + memcpy(out, ssl->s3->server_random, outlen); + return outlen; +} + +size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, + unsigned char *out, size_t outlen) +{ + if (session->master_key_length < 0) { + /* Should never happen */ + return 0; + } + if (outlen == 0) + return session->master_key_length; + if (outlen > (size_t)session->master_key_length) + outlen = session->master_key_length; + memcpy(out, session->master_key, outlen); + return outlen; } int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, @@ -3238,8 +2929,7 @@ X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) { - if (ctx->cert_store != NULL) - X509_STORE_free(ctx->cert_store); + X509_STORE_free(ctx->cert_store); ctx->cert_store = store; } @@ -3307,7 +2997,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, } #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, EC_KEY *(*ecdh) (SSL *ssl, int is_export, int keylength)) @@ -3332,14 +3022,13 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) SSL_R_DATA_LENGTH_TOO_LONG); return 0; } - if (ctx->psk_identity_hint != NULL) - OPENSSL_free(ctx->psk_identity_hint); + OPENSSL_free(ctx->cert->psk_identity_hint); if (identity_hint != NULL) { - ctx->psk_identity_hint = BUF_strdup(identity_hint); - if (ctx->psk_identity_hint == NULL) + ctx->cert->psk_identity_hint = BUF_strdup(identity_hint); + if (ctx->cert->psk_identity_hint == NULL) return 0; } else - ctx->psk_identity_hint = NULL; + ctx->cert->psk_identity_hint = NULL; return 1; } @@ -3348,21 +3037,17 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) if (s == NULL) return 0; - if (s->session == NULL) - return 1; /* session not created yet, ignored */ - if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); + OPENSSL_free(s->cert->psk_identity_hint); if (identity_hint != NULL) { - s->session->psk_identity_hint = BUF_strdup(identity_hint); - if (s->session->psk_identity_hint == NULL) + s->cert->psk_identity_hint = BUF_strdup(identity_hint); + if (s->cert->psk_identity_hint == NULL) return 0; } else - s->session->psk_identity_hint = NULL; + s->cert->psk_identity_hint = NULL; return 1; }