diff --git a/configure.ac b/configure.ac index 19ffd6bd7..3d222f01b 100644 --- a/configure.ac +++ b/configure.ac @@ -4104,7 +4104,7 @@ then # Requires Secure Renegotiation if test "x$ENABLED_SECURE_RENEGOTIATION" = "xno" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_SECURE_RENEGOTIATION -DHAVE_SERVER_RENEGOTIATION_INFO" + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SECURE_RENEGOTIATION -DHAVE_SERVER_RENEGOTIATION_INFO" fi fi diff --git a/src/bio.c b/src/bio.c index 626384acd..9c1e0c712 100644 --- a/src/bio.c +++ b/src/bio.c @@ -940,11 +940,13 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) return 0; } - if (bio->type == WOLFSSL_BIO_MD) { - /* MD is a wrapper only get next bio */ + if (bio->type == WOLFSSL_BIO_MD || + bio->type == WOLFSSL_BIO_BASE64) { + /* these are wrappers only, get next bio */ while (bio->next != NULL) { bio = bio->next; - if (bio->type != WOLFSSL_BIO_MD) { + if (bio->type == WOLFSSL_BIO_MD || + bio->type == WOLFSSL_BIO_BASE64) { break; } } diff --git a/src/internal.c b/src/internal.c index 654080f5d..811a539ae 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12109,6 +12109,14 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, ssl->secure_renegotiation->verifySet = 1; } #endif +#ifdef OPENSSL_ALL + if (ssl->options.side == WOLFSSL_CLIENT_END) + XMEMCPY(ssl->serverFinished, + input + *inOutIdx, TLS_FINISHED_SZ); + else + XMEMCPY(ssl->clientFinished, + input + *inOutIdx, TLS_FINISHED_SZ); +#endif /* force input exhaustion at ProcessReply consuming padSz */ *inOutIdx += size + ssl->keys.padSz; @@ -16759,6 +16767,14 @@ int SendFinished(WOLFSSL* ssl) TLS_FINISHED_SZ); } #endif +#ifdef OPENSSL_ALL + if (ssl->options.side == WOLFSSL_CLIENT_END) + XMEMCPY(ssl->clientFinished, + hashes, TLS_FINISHED_SZ); + else + XMEMCPY(ssl->serverFinished, + hashes, TLS_FINISHED_SZ); +#endif #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { diff --git a/src/ssl.c b/src/ssl.c index c349fbad3..434612ec4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -9460,6 +9460,8 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, sk = NULL; } } + /* null so that it doesn't get pushed again after switch */ + gn = NULL; } } else { @@ -9729,18 +9731,21 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, goto err; } } - if (obj && wolfSSL_sk_ASN1_OBJECT_push(sk, obj) == WOLFSSL_SUCCESS) { - /* obj pushed successfully on stack */ + if (obj) { + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto " + "stack."); + goto err; + } } - else if (gn && wolfSSL_sk_GENERAL_NAME_push(sk, gn) == WOLFSSL_SUCCESS) { - /* gn pushed successfully on stack */ - } - else { - /* Nothing to push or push failed */ - WOLFSSL_MSG("Error pushing ASN1_OBJECT or GENERAL_NAME object onto stack " - "or nothing to push."); - goto err; + else if (gn) { + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing GENERAL_NAME object onto " + "stack."); + goto err; + } } + ret = sk; (void)idx; @@ -9755,7 +9760,7 @@ err: wolfSSL_GENERAL_NAME_free(gn); } if (sk) { - wolfSSL_sk_ASN1_OBJECT_free(sk); + wolfSSL_sk_free(sk); } return NULL; } @@ -15985,9 +15990,37 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) { WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version"); - /* supported only at compile-time only */ - (void)ctx; - (void)ver; + if (!ctx) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + switch (ver) { + case SSL2_VERSION: + WOLFSSL_MSG("wolfSSL does not support SSLv2"); + return WOLFSSL_FAILURE; + case SSL3_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1); + FALL_THROUGH; + case TLS1_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1); + FALL_THROUGH; + case TLS1_1_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2); + FALL_THROUGH; + case TLS1_2_VERSION: + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3); +#ifdef WOLFSSL_TLS13 + FALL_THROUGH; + case TLS1_3_VERSION: + /* Nothing to do here */ +#endif + break; + default: + WOLFSSL_MSG("Unrecognized protocol version"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; } @@ -19012,30 +19045,13 @@ void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name) #ifdef OPENSSL_EXTRA void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free"); if (gens == NULL) { return; } - /* parse through stack freeing each node */ - node = gens->next; - while (gens->num > 1) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - wolfSSL_ASN1_OBJECT_free(tmp->data.obj); - XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); - gens->num -= 1; - } - - /* free head of stack */ - if (gens->num == 1) { - wolfSSL_ASN1_OBJECT_free(gens->data.obj); - } - XFREE(gens, NULL, DYNAMIC_TYPE_ASN1); + wolfSSL_sk_free(gens); } #if defined(OPENSSL_ALL) @@ -20481,7 +20497,7 @@ WOLFSSL_ABI WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert) { WOLFSSL_ENTER("wolfSSL_X509_get_subject_name"); - if (cert && cert->subject.sz != 0) + if (cert) return &cert->subject; return NULL; } @@ -22825,9 +22841,8 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out) WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) { WOLFSSL_X509* localX509 = NULL; - unsigned char* mem = NULL; - int ret; - word32 size; + byte* mem = NULL; + int size; WOLFSSL_ENTER("wolfSSL_d2i_X509_bio"); @@ -22836,15 +22851,27 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509) return NULL; } - ret = wolfSSL_BIO_get_mem_data(bio, &mem); - if (mem == NULL || ret <= 0) { - WOLFSSL_MSG("Failed to get data from bio struct"); + size = wolfSSL_BIO_pending(bio); + if (size == 0) { + WOLFSSL_MSG("wolfSSL_BIO_pending error. Possibly no pending data."); + return NULL; + } + + if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) { + WOLFSSL_MSG("malloc error"); + return NULL; + } + + if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) { + WOLFSSL_MSG("wolfSSL_BIO_read error"); + XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); return NULL; } - size = ret; localX509 = wolfSSL_X509_d2i(NULL, mem, size); if (localX509 == NULL) { + WOLFSSL_MSG("wolfSSL_X509_d2i error"); + XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL); return NULL; } @@ -23358,7 +23385,6 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); - ctx->chain = sk; for (i = 0; i < c->count && i < MAX_CHAIN_DEPTH; i++) { WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i); @@ -23408,7 +23434,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } } #endif - + ctx->chain = sk; } #endif /* SESSION_CERTS */ @@ -23648,13 +23674,12 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, } -/* free's own cert chain holding and extra data */ +/* free's extra data */ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) { WOLFSSL_ENTER("X509_STORE_CTX_free"); if (ctx != NULL) { #ifdef OPENSSL_EXTRA - wolfSSL_sk_free(ctx->chain); if (ctx->param != NULL){ XFREE(ctx->param,NULL,DYNAMIC_TYPE_OPENSSL); ctx->param = NULL; @@ -26307,29 +26332,41 @@ int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp) } #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) -#ifndef NO_WOLFSSL_STUB -/*** TBD ***/ -WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count) +WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count) { - (void)s; - (void)buf; - (void)count; - WOLFSSL_STUB("SSL_get_finished"); - return WOLFSSL_FAILURE; -} -#endif + WOLFSSL_ENTER("SSL_get_finished"); -#ifndef NO_WOLFSSL_STUB -/*** TBD ***/ -WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count) -{ - (void)s; - (void)buf; - (void)count; - WOLFSSL_STUB("SSL_get_peer_finished"); - return WOLFSSL_FAILURE; + if (!ssl || !buf || count < TLS_FINISHED_SZ) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (ssl->options.side == WOLFSSL_SERVER_END) + XMEMCPY(buf, ssl->serverFinished, + TLS_FINISHED_SZ); + else + XMEMCPY(buf, ssl->clientFinished, + TLS_FINISHED_SZ); + return TLS_FINISHED_SZ; +} + +WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count) +{ + WOLFSSL_ENTER("SSL_get_peer_finished"); + + if (!ssl || !buf || count < TLS_FINISHED_SZ) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (ssl->options.side == WOLFSSL_CLIENT_END) + XMEMCPY(buf, ssl->serverFinished, + TLS_FINISHED_SZ); + else + XMEMCPY(buf, ssl->clientFinished, + TLS_FINISHED_SZ); + return TLS_FINISHED_SZ; } -#endif #endif /* WOLFSSL_HAPROXY */ #ifndef NO_WOLFSSL_STUB diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 8d1bda9e4..2f2c98bf4 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4291,6 +4291,10 @@ struct WOLFSSL { #ifdef WOLFSSL_STATIC_EPHEMERAL StaticKeyExchangeInfo_t staticKE; #endif +#ifdef OPENSSL_ALL + byte clientFinished[TLS_FINISHED_SZ]; + byte serverFinished[TLS_FINISHED_SZ]; +#endif }; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 2181d99e0..c98f12b21 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -308,6 +308,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_set_ex_data wolfSSL_set_ex_data #define SSL_get_shutdown wolfSSL_get_shutdown +#define SSL_get_finished wolfSSL_get_finished +#define SSL_get_peer_finished wolfSSL_get_peer_finished #define SSL_set_rfd wolfSSL_set_rfd #define SSL_set_wfd wolfSSL_set_wfd #define SSL_set_shutdown wolfSSL_set_shutdown diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c6f72bb94..a08a79644 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3933,8 +3933,8 @@ WOLFSSL_API int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc, #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLFSSL_API const unsigned char *SSL_SESSION_get0_id_context( const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length); -WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count); -WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count); +WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count); +WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count); #endif WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len);