diff --git a/include/cyassl_int.h b/include/cyassl_int.h index 611f2ba4d..adce32345 100644 --- a/include/cyassl_int.h +++ b/include/cyassl_int.h @@ -927,6 +927,7 @@ typedef struct Options { byte processReply; /* nonblocking resume */ byte partialWrite; /* only one msg per write call */ byte quietShutdown; /* don't send close notify */ + byte certOnly; /* stop once we get cert */ #ifndef NO_PSK byte havePSK; /* psk key set by user */ psk_client_callback client_psk_cb; diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 45d6e4958..cd3dc2858 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -646,6 +646,9 @@ CYASSL_API int CyaSSL_get_chain_cert_pem(X509_CHAIN*, int idx, CYASSL_API const unsigned char* CyaSSL_get_sessionID(const SSL_SESSION* sess); CYASSL_API int CyaSSL_X509_get_serial_number(X509*, unsigned char*, int*); +/* connect enough to get peer cert */ +CYASSL_API int CyaSSL_connect_cert(SSL* ssl); + /* server CTX Diffie-Hellman parameters */ CYASSL_API int CyaSSL_SetTmpDH(SSL*, unsigned char* p, int pSz, unsigned char* g, int gSz); diff --git a/src/cyassl_int.c b/src/cyassl_int.c index f1308ff0e..cfb52ade7 100644 --- a/src/cyassl_int.c +++ b/src/cyassl_int.c @@ -721,6 +721,7 @@ int InitSSL(SSL* ssl, SSL_CTX* ctx) ssl->options.dtls = 0; ssl->options.partialWrite = ctx->partialWrite; ssl->options.quietShutdown = ctx->quietShutdown; + ssl->options.certOnly = 0; /* SSL_CTX still owns certificate, certChain, key, and caList buffers */ ssl->buffers.certificate = ctx->certificate; diff --git a/src/ssl.c b/src/ssl.c index 10276511d..325e78373 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1333,6 +1333,9 @@ int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list) CYASSL_MSG("connect state: HELLO_AGAIN"); case HELLO_AGAIN : + if (ssl->options.certOnly) + return SSL_SUCCESS; + #ifdef CYASSL_DTLS if (ssl->options.dtls && !ssl->options.resuming) { /* re-init hashes, exclude first hello and verify request */ @@ -4198,5 +4201,26 @@ const byte* CyaSSL_get_sessionID(const SSL_SESSION* session) } +/* connect enough to get peer cert chain, no validation */ +int CyaSSL_connect_cert(SSL* ssl) +{ + int ret; + byte oldVerify; + + if (ssl == NULL) + return SSL_FAILURE; + + oldVerify = ssl->options.verifyNone; + ssl->options.verifyNone = 1; + ssl->options.certOnly = 1; + + ret = SSL_connect(ssl); + + ssl->options.verifyNone = oldVerify; + ssl->options.certOnly = 0; + + return ret; +} + #endif /* SESSION_CERTS */