Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for enabling and disabling CRLs. #6329

Merged
merged 5 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions scripts/crl-revoked.test
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cp -rp . $RUNNING_DIR/.
cd $RUNNING_DIR

revocation_code="-361"
revocation_code_openssl="23"
exit_code=1
counter=0
# need a unique resume port since may run the same time as testsuite
Expand Down Expand Up @@ -112,7 +113,7 @@ run_test() {
server_result=$?

case "$capture_out" in
*$revocation_code*)
*"$revocation_code"*|*"$revocation_code_openssl"*)
# only exit with zero on detection of the expected error code
echo ""
echo "Successful Revocation!!!!"
Expand Down Expand Up @@ -178,7 +179,7 @@ run_hashdir_test() {
server_result=$?

case "$capture_out" in
*$revocation_code*)
*"$revocation_code"*|*"$revocation_code_openssl"*)
# only exit with zero on detection of the expected error code
echo ""
echo "Successful Revocation!!!! with hash dir"
Expand Down
32 changes: 28 additions & 4 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,13 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS

#endif /* !WOLFSSL_NO_TLS12 */

#ifndef NO_WOLFSSL_SERVER
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET)
#if defined(WOLFSSL_HAPROXY)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we support a way to use initial_ctx with a macro besides WOLFSSL_HAPROXY?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgarske, not in this PR. More comfortable with the current changes since it has been tested against Haproxy.

Copy link
Contributor

@dgarske dgarske Jun 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems shortsighted to limit that area of code to HAPROXY only. Could you instead create a new macro like WOLFSSL_TICKET_USE_INITIAL_CTX and set this macro in settings.h for WOLFSSL_HAPROXY? At least giving other OSP projects the opportunity to use it?

Copy link
Contributor Author

@tmael tmael Jun 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the use case for initial_ctx is quite rare, and I'm skeptical about its use in other OSP projects.
Currently, #define SSL_TICKET_CTX(ssl) ssl->initial_ctx->ticketEncCtx , initial_ctx, and ssl->initial_ctx are gated by WOLFSSL_HAPROXY. Are you suggesting alterations to the gating for all of these?
If that's the case, I can replace the WOLFSSL_HAPROXY gating with WOLFSSL_USE_INITIAL_CTX, which would provide a bit more flexibility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, looking for flexibility around the use of the initial_ctx feature. Its a fairly easy refactor. If you think HAPROXY is the only project that will ever use this feature then we can take the PR as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying. Currently, I'm inclined to leave it as-is and consider the easy refactor only when necessary. None of our supported OSP projects require it presently, and if they had, we would have run into issues earlier. I can't predict the needs of future OSP projects. Although introducing a new setting is straightforward, it implies the added responsibility of maintenance and instructing non-configure autotool users to add one more setting to their user_settings.h file.

#define SSL_TICKET_CTX(ssl) ssl->initial_ctx->ticketEncCtx
#else
#define SSL_TICKET_CTX(ssl) ssl->ctx->ticketEncCtx
#endif
#if !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
static int TicketEncCbCtx_Init(WOLFSSL_CTX* ctx,
TicketEncCbCtx* keyCtx);
static void TicketEncCbCtx_Free(TicketEncCbCtx* keyCtx);
Expand Down Expand Up @@ -6213,6 +6218,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
if (!newSSL) {
WOLFSSL_MSG("freeing old ctx to decrement reference count. Switching ctx.");
wolfSSL_CTX_free(ssl->ctx);
#if defined(WOLFSSL_HAPROXY)
wolfSSL_CTX_free(ssl->initial_ctx);
#endif
}

/* increment CTX reference count */
Expand All @@ -6229,6 +6237,20 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->ctx = ctx; /* only for passing to calls, options could change */
julek-wolfssl marked this conversation as resolved.
Show resolved Hide resolved
/* Don't change version on a SSL object that has already started a
* handshake */
#if defined(WOLFSSL_HAPROXY)
ret = wolfSSL_CTX_up_ref(ctx);
if (ret == WOLFSSL_SUCCESS) {
ssl->initial_ctx = ctx; /* Save access to session key materials */
}
else {
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
return ret;
#else
(void)ret;
#endif
}

#endif
if (!ssl->msgsReceived.got_client_hello &&
!ssl->msgsReceived.got_server_hello)
ssl->version = ctx->method->version;
Expand Down Expand Up @@ -23135,6 +23157,8 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
#ifdef OPENSSL_EXTRA
case 0 :
return "ok";
case -WOLFSSL_X509_V_ERR_CERT_REVOKED :
return "certificate revoked";
#endif

case UNSUPPORTED_SUITE :
Expand Down Expand Up @@ -34650,7 +34674,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (error == 0) {
ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac,
1, et->enc_ticket, sizeof(InternalTicket), &encLen,
ssl->ctx->ticketEncCtx);
SSL_TICKET_CTX(ssl));
}
else {
ret = WOLFSSL_TICKET_RET_FATAL;
Expand Down Expand Up @@ -34775,7 +34799,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ret = ssl->ctx->ticketEncCb((WOLFSSL*)ssl, et->key_name, et->iv,
et->enc_ticket + inLen, 0,
et->enc_ticket, inLen, &outLen,
ssl->ctx->ticketEncCtx);
SSL_TICKET_CTX(ssl));
}
if (ret != WOLFSSL_TICKET_RET_OK) {
#ifdef WOLFSSL_ASYNC_CRYPT
Expand Down
74 changes: 56 additions & 18 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4509,7 +4509,11 @@ int wolfSSL_get_error(WOLFSSL* ssl, int ret)
return WOLFSSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */
else if (ssl->error == ZERO_RETURN || ssl->options.shutdownDone)
return WOLFSSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */
return ssl->error;
#if defined(WOLFSSL_HAPROXY)
return GetX509Error(ssl->error);
julek-wolfssl marked this conversation as resolved.
Show resolved Hide resolved
#else
return (ssl->error);
#endif
}


Expand Down Expand Up @@ -8152,7 +8156,8 @@ int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
return BAD_FUNC_ARG;

if (cm->crl == NULL) {
if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Enable CRL failed");
return WOLFSSL_FATAL_ERROR;
}
Expand Down Expand Up @@ -8204,11 +8209,21 @@ int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
{
int ret = WOLFSSL_SUCCESS;

(void)options;

WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
if (cm == NULL)
return BAD_FUNC_ARG;
#if defined(OPENSSL_COMPATIBLE_DEFAULTS)
if (options == 0) {

/* Turn off doing Leaf CRL check */
cm->crlEnabled = 0;
/* Turn off all checks */
cm->crlCheckAll = 0;
return ret;
}
#else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If OPENSSL_COMPATIBLE_DEFAULTS is defined, and we don't end up enabling CRL, is there any point in allocating and initializing the cert manager's CRL? Or should the entire function be skipped in this case? I'm not seeing anywhere else in the code where we set crlEnabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kareem-wolfssl. Excellent observation! Your feedback has been implemented in the update.

(void)options;
#endif

#ifdef HAVE_CRL
if (cm->crl == NULL) {
Expand All @@ -8228,10 +8243,15 @@ int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
cm->crl->crlIOCb = EmbedCrlLookup;
#endif
}

cm->crlEnabled = 1;
if (options & WOLFSSL_CRL_CHECKALL)
cm->crlCheckAll = 1;
#if defined(OPENSSL_COMPATIBLE_DEFAULTS)
if ((options & WOLFSSL_CRL_CHECKALL) ||
(options & WOLFSSL_CRL_CHECK))
#endif
{
cm->crlEnabled = 1;
if (options & WOLFSSL_CRL_CHECKALL)
cm->crlCheckAll = 1;
}
#else
ret = NOT_COMPILED_IN;
#endif
Expand Down Expand Up @@ -9431,7 +9451,8 @@ int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
return BAD_FUNC_ARG;

if (cm->crl == NULL) {
if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Enable CRL failed");
return WOLFSSL_FATAL_ERROR;
}
Expand All @@ -9448,7 +9469,8 @@ int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, const char* file,
return BAD_FUNC_ARG;

if (cm->crl == NULL) {
if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Enable CRL failed");
return WOLFSSL_FATAL_ERROR;
}
Expand Down Expand Up @@ -14494,12 +14516,17 @@ void SetupSession(WOLFSSL* ssl)

WOLFSSL_ENTER("SetupSession");

if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL &&
!session->haveAltSessionID) {
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) {
/* Make sure the session ID is available when the user calls any
* get_session API */
XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
session->sessionIDSz = ssl->arrays->sessionIDSz;
if (!session->haveAltSessionID) {
XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
session->sessionIDSz = ssl->arrays->sessionIDSz;
}
else {
XMEMCPY(session->sessionID, session->altSessionID, ID_LEN);
session->sessionIDSz = ID_LEN;
}
}
session->side = (byte)ssl->options.side;
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
Expand Down Expand Up @@ -14904,7 +14931,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
if (SslSessionCacheOff(ssl, ssl->session))
return WOLFSSL_FAILURE;

if (ssl->options.haveSessionId == 0)
if (ssl->options.haveSessionId == 0 && !ssl->session->haveAltSessionID)
return WOLFSSL_FAILURE;

#ifdef HAVE_SESSION_TICKET
Expand All @@ -14913,7 +14940,8 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
#endif

XMEMSET(bogusID, 0, sizeof(bogusID));
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL
&& !ssl->session->haveAltSessionID)
id = ssl->arrays->sessionID;
else if (ssl->session->haveAltSessionID) {
id = ssl->session->altSessionID;
Expand Down Expand Up @@ -23116,8 +23144,9 @@ int wolfSSL_ERR_GET_REASON(unsigned long err)
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
/* Nginx looks for this error to know to stop parsing certificates.
* Same for HAProxy. */
if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE)
|| (err & 0xFFFFFFL) == -ASN_NO_PEM_HEADER)
if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE) ||
((err & 0xFFFFFFL) == -ASN_NO_PEM_HEADER) ||
((err & 0xFFFL) == PEM_R_NO_START_LINE ))
return PEM_R_NO_START_LINE;
if (err == ((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
return SSL_R_HTTP_REQUEST;
Expand Down Expand Up @@ -31248,6 +31277,9 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#endif
if (ssl->ctx) {
wolfSSL_CTX_free(ssl->ctx);
#if defined(WOLFSSL_HAPROXY)
wolfSSL_CTX_free(ssl->initial_ctx);
#endif
}
ssl->ctx = ctx;

Expand Down Expand Up @@ -31450,6 +31482,12 @@ const byte* wolfSSL_SESSION_get_id(const WOLFSSL_SESSION* sess,
WOLFSSL_MSG("Bad func args. Please provide idLen");
return NULL;
}
#ifdef HAVE_SESSION_TICKET
if (sess->haveAltSessionID) {
*idLen = ID_LEN;
return sess->altSessionID;
}
#endif
*idLen = sess->sessionIDSz;
return sess->sessionID;
}
Expand Down
5 changes: 3 additions & 2 deletions src/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -7028,7 +7028,8 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;

if (cm->crl == NULL) {
if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Enable CRL failed");
goto end;
}
Expand Down Expand Up @@ -12440,7 +12441,7 @@ WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(

for (i = 0; i < num; i++) {
name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
if (name == NULL || 0 != wolfSSL_sk_X509_NAME_push(copy, name)) {
if (name == NULL || WOLFSSL_SUCCESS != wolfSSL_sk_X509_NAME_push(copy, name)) {
julek-wolfssl marked this conversation as resolved.
Show resolved Hide resolved
WOLFSSL_MSG("Memory error");
wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
return NULL;
Expand Down
13 changes: 10 additions & 3 deletions src/x509_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ int GetX509Error(int e)
case ASN_BEFORE_DATE_E:
return WOLFSSL_X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
kareem-wolfssl marked this conversation as resolved.
Show resolved Hide resolved
case ASN_AFTER_DATE_E:
return WOLFSSL_X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
return WOLFSSL_X509_V_ERR_CERT_HAS_EXPIRED;
case ASN_NO_SIGNER_E: /* get issuer error if no CA found locally */
return WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
case ASN_SELF_SIGNED_E:
Expand All @@ -183,6 +183,8 @@ int GetX509Error(int e)
case ASN_SIG_HASH_E:
case ASN_SIG_KEY_E:
return WOLFSSL_X509_V_ERR_CERT_SIGNATURE_FAILURE;
case CRL_CERT_REVOKED:
return WOLFSSL_X509_V_ERR_CERT_REVOKED;
default:
#ifdef HAVE_WOLFSSL_MSG_EX
WOLFSSL_MSG_EX("Error not configured or implemented yet: %d", e);
Expand Down Expand Up @@ -980,7 +982,11 @@ int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
}

#if defined(OPENSSL_COMPATIBLE_DEFAULTS)
else if (flag == 0) {
ret = wolfSSL_CertManagerDisableCRL(store->cm);
}
kareem-wolfssl marked this conversation as resolved.
Show resolved Hide resolved
#endif
return ret;
}

Expand Down Expand Up @@ -1023,7 +1029,8 @@ WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,

#ifdef HAVE_CRL
if (str->cm->crl == NULL) {
if (wolfSSL_CertManagerEnableCRL(str->cm, 0) != WOLFSSL_SUCCESS) {
if (wolfSSL_CertManagerEnableCRL(str->cm, WOLFSSL_CRL_CHECK)
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Enable CRL failed");
wolfSSL_CTX_free(ctx);
return WOLFSSL_FAILURE;
Expand Down
Loading