diff --git a/src/internal.c b/src/internal.c index 6cb32e43c..bf78a27a3 100755 --- a/src/internal.c +++ b/src/internal.c @@ -2592,6 +2592,7 @@ void SSL_ResourceFree(WOLFSSL* ssl) } #endif #ifndef NO_CERTS + ssl->keepCert = 0; /* make sure certificate is free'd */ wolfSSL_UnloadCertsKeys(ssl); #endif #ifndef NO_RSA diff --git a/src/ssl.c b/src/ssl.c index ce35375c3..f4c7eb628 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -81,7 +81,6 @@ #include #include #include - #include #ifdef HAVE_STUNNEL #include #endif /* WITH_STUNNEL */ @@ -3473,14 +3472,13 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, FreeX509(ssl->ourCert); if (ssl->ourCert) { XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509); + ssl->ourCert = NULL; } #endif } XMEMCPY(&ssl->buffers.certificate, &der, sizeof(der)); #ifdef OPENSSL_EXTRA - ssl->ourCert = wolfSSL_X509_d2i(NULL, - ssl->buffers.certificate->buffer, - ssl->buffers.certificate->length); + ssl->keepCert = 1; /* hold cert for ssl lifetime */ #endif ssl->buffers.weOwnCert = 1; } @@ -3490,14 +3488,10 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, FreeX509(ctx->ourCert); if (ctx->ourCert) { XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509); + ctx->ourCert = NULL; } #endif XMEMCPY(&ctx->certificate, &der, sizeof(der)); - #ifdef OPENSSL_EXTRA - ctx->ourCert = wolfSSL_X509_d2i(NULL, - ctx->certificate->buffer, - ctx->certificate->length); - #endif } } else if (type == PRIVATEKEY_TYPE) { @@ -8040,13 +8034,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return BAD_FUNC_ARG; } - if (ssl->buffers.weOwnCert) { + if (ssl->buffers.weOwnCert && !ssl->keepCert) { WOLFSSL_MSG("Unloading cert"); FreeDer(&ssl->buffers.certificate); #ifdef OPENSSL_EXTRA FreeX509(ssl->ourCert); if (ssl->ourCert) { XFREE(ssl->ourCert, ssl->heap, DYNAMIC_TYPE_X509); + ssl->ourCert = NULL; } #endif ssl->buffers.weOwnCert = 0; @@ -10769,10 +10764,20 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl) } if (ssl->buffers.weOwnCert) { + if (ssl->ourCert == NULL) { + ssl->ourCert = wolfSSL_X509_d2i(NULL, + ssl->buffers.certificate->buffer, + ssl->buffers.certificate->length); + } return ssl->ourCert; } else { /* if cert not owned get parent ctx cert or return null */ if (ssl->ctx) { + if (ssl->ctx->ourCert == NULL) { + ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL, + ssl->ctx->certificate->buffer, + ssl->ctx->certificate->length); + } return ssl->ctx->ourCert; } else { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ed05d313e..d24f3fce7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2731,6 +2731,7 @@ struct WOLFSSL { points to ctx if not owned (owned flag found in buffers.weOwnCert) */ #endif + byte keepCert; /* keep certificate after handshake */ #if defined(FORTRESS) || defined(HAVE_STUNNEL) void* ex_data[MAX_EX_DATA]; /* external data, for Fortress */ #endif diff --git a/wolfssl/test.h b/wolfssl/test.h index 055222254..8c0468660 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -441,14 +441,22 @@ static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) static INLINE void ShowX509(WOLFSSL_X509* x509, const char* hdr) { char* altName; - char* issuer = wolfSSL_X509_NAME_oneline( - wolfSSL_X509_get_issuer_name(x509), 0, 0); - char* subject = wolfSSL_X509_NAME_oneline( - wolfSSL_X509_get_subject_name(x509), 0, 0); + char* issuer; + char* subject; byte serial[32]; int ret; int sz = sizeof(serial); + if (x509 == NULL) { + printf("%s No Cert\n", hdr); + return; + } + + issuer = wolfSSL_X509_NAME_oneline( + wolfSSL_X509_get_issuer_name(x509), 0, 0); + subject = wolfSSL_X509_NAME_oneline( + wolfSSL_X509_get_subject_name(x509), 0, 0); + printf("%s\n issuer : %s\n subject: %s\n", hdr, issuer, subject); while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL) @@ -487,6 +495,9 @@ static INLINE void showPeer(WOLFSSL* ssl) printf("peer has no cert!\n"); wolfSSL_FreeX509(peer); #endif +#if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) + ShowX509(wolfSSL_get_certificate(ssl), "our cert info:"); +#endif /* SHOW_CERTS */ printf("SSL version is %s\n", wolfSSL_get_version(ssl)); cipher = wolfSSL_get_current_cipher(ssl);