forked from wolfSSL/wolfssl
adds partial client support to TLS Extension Status Request, a.k.a. OCSP stapling;
missing: - compare OcspRequest and OcspResponse; - execute contingence plan; - add nonce extension;
This commit is contained in:
13
configure.ac
13
configure.ac
@ -1595,6 +1595,18 @@ then
|
|||||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_TRUNCATED_HMAC"
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_TRUNCATED_HMAC"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Certificate Status Request : a.k.a. OCSP stapling
|
||||||
|
AC_ARG_ENABLE([statusrequest],
|
||||||
|
[ --enable-statusrequest Enable Certificate Status Request (default: disabled)],
|
||||||
|
[ ENABLED_CERTIFICATE_STATUS_REQUEST=$enableval ],
|
||||||
|
[ ENABLED_CERTIFICATE_STATUS_REQUEST=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "x$ENABLED_CERTIFICATE_STATUS_REQUEST" = "xyes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_CERTIFICATE_STATUS_REQUEST"
|
||||||
|
fi
|
||||||
|
|
||||||
# Renegotiation Indication - (FAKE Secure Renegotiation)
|
# Renegotiation Indication - (FAKE Secure Renegotiation)
|
||||||
AC_ARG_ENABLE([renegotiation-indication],
|
AC_ARG_ENABLE([renegotiation-indication],
|
||||||
[AS_HELP_STRING([--enable-renegotiation-indication],[Enable Renegotiation Indication (default: disabled)])],
|
[AS_HELP_STRING([--enable-renegotiation-indication],[Enable Renegotiation Indication (default: disabled)])],
|
||||||
@ -2492,6 +2504,7 @@ echo " * Server Name Indication: $ENABLED_SNI"
|
|||||||
echo " * ALPN: $ENABLED_ALPN"
|
echo " * ALPN: $ENABLED_ALPN"
|
||||||
echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
|
echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
|
||||||
echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC"
|
echo " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC"
|
||||||
|
echo " * Status Request: $ENABLED_CERTIFICATE_STATUS_REQUEST"
|
||||||
echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES"
|
echo " * Supported Elliptic Curves: $ENABLED_SUPPORTED_CURVES"
|
||||||
echo " * Session Ticket: $ENABLED_SESSION_TICKET"
|
echo " * Session Ticket: $ENABLED_SESSION_TICKET"
|
||||||
echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION"
|
echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION"
|
||||||
|
@ -425,7 +425,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
byte maxFragment = 0;
|
byte maxFragment = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_TRUNCATED_HMAC
|
#ifdef HAVE_TRUNCATED_HMAC
|
||||||
byte truncatedHMAC = 0;
|
byte truncatedHMAC = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
byte statusRequest = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -465,8 +468,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
StackTrap();
|
StackTrap();
|
||||||
|
|
||||||
while ((ch = mygetopt(argc, argv,
|
while ((ch = mygetopt(argc, argv,
|
||||||
"?gdeDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:aB:"))
|
"?gdeDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:aB:W")) != -1) {
|
||||||
!= -1) {
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '?' :
|
case '?' :
|
||||||
Usage();
|
Usage();
|
||||||
@ -653,6 +655,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'W' :
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
statusRequest = 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
case 'o' :
|
case 'o' :
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
useOcsp = 1;
|
useOcsp = 1;
|
||||||
@ -938,6 +946,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
|
if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
|
||||||
err_sys("UseTruncatedHMAC failed");
|
err_sys("UseTruncatedHMAC failed");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
if (statusRequest)
|
||||||
|
if (wolfSSL_CTX_UseCertificateStatusRequest(ctx, WOLFSSL_CSR_OCSP)
|
||||||
|
!= SSL_SUCCESS)
|
||||||
|
err_sys("UseCertificateStatusRequest failed");
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS)
|
if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS)
|
||||||
err_sys("UseSessionTicket failed");
|
err_sys("UseSessionTicket failed");
|
||||||
@ -1320,4 +1334,3 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
140
src/internal.c
140
src/internal.c
@ -4357,7 +4357,6 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
|
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
int doCrlLookup = 1;
|
int doCrlLookup = 1;
|
||||||
(void)doCrlLookup;
|
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
|
if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
|
||||||
WOLFSSL_MSG("Doing Non Leaf OCSP check");
|
WOLFSSL_MSG("Doing Non Leaf OCSP check");
|
||||||
@ -4380,6 +4379,8 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
WOLFSSL_MSG("\tCRL check not ok");
|
WOLFSSL_MSG("\tCRL check not ok");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)doCrlLookup;
|
||||||
#endif /* HAVE_CRL */
|
#endif /* HAVE_CRL */
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OCSP || HAVE_CRL */
|
#endif /* HAVE_OCSP || HAVE_CRL */
|
||||||
@ -4447,7 +4448,6 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
|
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
|
||||||
if (fatal == 0) {
|
if (fatal == 0) {
|
||||||
int doCrlLookup = 1;
|
int doCrlLookup = 1;
|
||||||
(void)doCrlLookup;
|
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (ssl->ctx->cm->ocspEnabled) {
|
if (ssl->ctx->cm->ocspEnabled) {
|
||||||
WOLFSSL_MSG("Doing Leaf OCSP check");
|
WOLFSSL_MSG("Doing Leaf OCSP check");
|
||||||
@ -4469,6 +4469,8 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
fatal = 0;
|
fatal = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)doCrlLookup;
|
||||||
#endif /* HAVE_CRL */
|
#endif /* HAVE_CRL */
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OCSP || HAVE_CRL */
|
#endif /* HAVE_OCSP || HAVE_CRL */
|
||||||
@ -4776,6 +4778,101 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||||
|
word32 size)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
byte status_type;
|
||||||
|
word32 status_length;
|
||||||
|
|
||||||
|
if (size < ENUM_LEN + OPAQUE24_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
status_type = input[(*inOutIdx)++];
|
||||||
|
|
||||||
|
c24to32(input + *inOutIdx, &status_length);
|
||||||
|
*inOutIdx += OPAQUE24_LEN;
|
||||||
|
|
||||||
|
if (size != ENUM_LEN + OPAQUE24_LEN + status_length)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
switch (status_type) {
|
||||||
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
||||||
|
|
||||||
|
case WOLFSSL_CSR_OCSP: {
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
CertStatus* status;
|
||||||
|
OcspResponse* response;
|
||||||
|
#else
|
||||||
|
CertStatus status[1];
|
||||||
|
OcspResponse response[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
do {
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
if (ssl->status_request) {
|
||||||
|
ssl->status_request = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
if (ssl->status_request_v2) {
|
||||||
|
ssl->status_request_v2 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
if (status == NULL || response == NULL) {
|
||||||
|
if (status) XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (response) XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
return MEMORY_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InitOcspResponse(response, status, input +*inOutIdx, status_length);
|
||||||
|
|
||||||
|
if ((ret = OcspResponseDecode(response)) == 0) {
|
||||||
|
if (response->responseStatus != OCSP_SUCCESSFUL)
|
||||||
|
ret = FATAL_ERROR;
|
||||||
|
/* TODO CSR */
|
||||||
|
/*else if (CompareOcspReqResp(request, response) != 0)
|
||||||
|
ret = FATAL_ERROR; */
|
||||||
|
else if (response->status->status != CERT_GOOD)
|
||||||
|
ret = FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*inOutIdx += status_length;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = BUFFER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
SendAlert(ssl, alert_fatal, bad_certificate_status_response);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !NO_CERTS */
|
#endif /* !NO_CERTS */
|
||||||
|
|
||||||
|
|
||||||
@ -4971,6 +5068,26 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
case certificate_status:
|
||||||
|
if (ssl->msgsReceived.got_certificate_status) {
|
||||||
|
WOLFSSL_MSG("Duplicate CertificateSatatus received");
|
||||||
|
return DUPLICATE_MSG_E;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_certificate_status = 1;
|
||||||
|
|
||||||
|
if (ssl->msgsReceived.got_certificate == 0) {
|
||||||
|
WOLFSSL_MSG("No Certificate before CertificateStatus");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
if (ssl->msgsReceived.got_server_key_exchange != 0) {
|
||||||
|
WOLFSSL_MSG("CertificateStatus after ServerKeyExchange");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
case server_key_exchange:
|
case server_key_exchange:
|
||||||
if (ssl->msgsReceived.got_server_key_exchange) {
|
if (ssl->msgsReceived.got_server_key_exchange) {
|
||||||
@ -4979,10 +5096,18 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
}
|
}
|
||||||
ssl->msgsReceived.got_server_key_exchange = 1;
|
ssl->msgsReceived.got_server_key_exchange = 1;
|
||||||
|
|
||||||
if ( ssl->msgsReceived.got_server_hello == 0) {
|
if (ssl->msgsReceived.got_server_hello == 0) {
|
||||||
WOLFSSL_MSG("No ServerHello before Cert");
|
WOLFSSL_MSG("No ServerHello before ServerKeyExchange");
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
}
|
}
|
||||||
|
if (ssl->msgsReceived.got_certificate_status == 0) {
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
if (ssl->status_request) {
|
||||||
|
WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -5224,7 +5349,12 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
case certificate:
|
case certificate:
|
||||||
WOLFSSL_MSG("processing certificate");
|
WOLFSSL_MSG("processing certificate");
|
||||||
ret = DoCertificate(ssl, input, inOutIdx, size);
|
ret = DoCertificate(ssl, input, inOutIdx, size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case certificate_status:
|
||||||
|
WOLFSSL_MSG("processing certificate status");
|
||||||
|
ret = DoCertificateStatus(ssl, input, inOutIdx, size);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
21
src/ssl.c
21
src/ssl.c
@ -794,6 +794,27 @@ int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
|
|||||||
#endif /* NO_WOLFSSL_CLIENT */
|
#endif /* NO_WOLFSSL_CLIENT */
|
||||||
#endif /* HAVE_TRUNCATED_HMAC */
|
#endif /* HAVE_TRUNCATED_HMAC */
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
|
||||||
|
int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type)
|
||||||
|
{
|
||||||
|
if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type)
|
||||||
|
{
|
||||||
|
if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
||||||
|
|
||||||
/* Elliptic Curves */
|
/* Elliptic Curves */
|
||||||
#ifdef HAVE_SUPPORTED_CURVES
|
#ifdef HAVE_SUPPORTED_CURVES
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
152
src/tls.c
152
src/tls.c
@ -1885,6 +1885,139 @@ int TLSX_UseTruncatedHMAC(TLSX** extensions)
|
|||||||
|
|
||||||
#endif /* HAVE_TRUNCATED_HMAC */
|
#endif /* HAVE_TRUNCATED_HMAC */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Certificate Status Request */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
|
||||||
|
#ifndef HAVE_OCSP
|
||||||
|
#error Status Request Extension requires OCSP. \
|
||||||
|
Use --enable-ocsp in the configure script or define HAVE_OCSP.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void TLSX_CSR_Free(CertificateStatusRequest* csr)
|
||||||
|
{
|
||||||
|
switch (csr->status_type) {
|
||||||
|
case WOLFSSL_CSR_OCSP:
|
||||||
|
/* nothing to release for now... */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
|
||||||
|
{
|
||||||
|
/* shut up compiler warnings */
|
||||||
|
(void) csr; (void) isRequest;
|
||||||
|
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
if (isRequest) {
|
||||||
|
switch (csr->status_type) {
|
||||||
|
case WOLFSSL_CSR_OCSP:
|
||||||
|
return ENUM_LEN + 2 * OPAQUE16_LEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
||||||
|
byte isRequest)
|
||||||
|
{
|
||||||
|
/* shut up compiler warnings */
|
||||||
|
(void) csr; (void) output; (void) isRequest;
|
||||||
|
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
if (isRequest) {
|
||||||
|
word16 offset = 0;
|
||||||
|
|
||||||
|
/* type */
|
||||||
|
output[offset++] = csr->status_type;
|
||||||
|
|
||||||
|
switch (csr->status_type) {
|
||||||
|
case WOLFSSL_CSR_OCSP:
|
||||||
|
/* responder id list */
|
||||||
|
c16toa(0, output + offset);
|
||||||
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
/* request extensions */
|
||||||
|
c16toa(0, output + offset);
|
||||||
|
offset += OPAQUE16_LEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||||
|
byte isRequest)
|
||||||
|
{
|
||||||
|
/* shut up compiler warnings */
|
||||||
|
(void) ssl; (void) input;
|
||||||
|
|
||||||
|
if (!isRequest) {
|
||||||
|
ssl->status_request = 1;
|
||||||
|
|
||||||
|
return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type)
|
||||||
|
{
|
||||||
|
CertificateStatusRequest* csr = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
csr = (CertificateStatusRequest*)XMALLOC(sizeof(CertificateStatusRequest),
|
||||||
|
NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
if (!csr)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
csr->status_type = status_type;
|
||||||
|
|
||||||
|
switch (status_type) {
|
||||||
|
case WOLFSSL_CSR_OCSP:
|
||||||
|
/* nothing to handle for now... */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr)) != 0) {
|
||||||
|
XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CSR_FREE_ALL TLSX_CSR_Free
|
||||||
|
#define CSR_GET_SIZE TLSX_CSR_GetSize
|
||||||
|
#define CSR_WRITE TLSX_CSR_Write
|
||||||
|
#define CSR_PARSE TLSX_CSR_Parse
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CSR_FREE_ALL(data)
|
||||||
|
#define CSR_GET_SIZE(a, b) 0
|
||||||
|
#define CSR_WRITE(a, b, c) 0
|
||||||
|
#define CSR_PARSE(a, b, c, d) 0
|
||||||
|
|
||||||
|
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Supported Elliptic Curves */
|
/* Supported Elliptic Curves */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -3094,6 +3227,10 @@ void TLSX_FreeAll(TLSX* list)
|
|||||||
EC_FREE_ALL(extension->data);
|
EC_FREE_ALL(extension->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST:
|
||||||
|
CSR_FREE_ALL(extension->data);
|
||||||
|
break;
|
||||||
|
|
||||||
case TLSX_RENEGOTIATION_INFO:
|
case TLSX_RENEGOTIATION_INFO:
|
||||||
SCR_FREE_ALL(extension->data);
|
SCR_FREE_ALL(extension->data);
|
||||||
break;
|
break;
|
||||||
@ -3161,6 +3298,10 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
|
|||||||
length += EC_GET_SIZE(extension->data);
|
length += EC_GET_SIZE(extension->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST:
|
||||||
|
length += CSR_GET_SIZE(extension->data, isRequest);
|
||||||
|
break;
|
||||||
|
|
||||||
case TLSX_RENEGOTIATION_INFO:
|
case TLSX_RENEGOTIATION_INFO:
|
||||||
length += SCR_GET_SIZE(extension->data, isRequest);
|
length += SCR_GET_SIZE(extension->data, isRequest);
|
||||||
break;
|
break;
|
||||||
@ -3230,6 +3371,11 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
|||||||
offset += EC_WRITE(extension->data, output + offset);
|
offset += EC_WRITE(extension->data, output + offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST:
|
||||||
|
offset += CSR_WRITE(extension->data, output + offset,
|
||||||
|
isRequest);
|
||||||
|
break;
|
||||||
|
|
||||||
case TLSX_RENEGOTIATION_INFO:
|
case TLSX_RENEGOTIATION_INFO:
|
||||||
offset += SCR_WRITE(extension->data, output + offset,
|
offset += SCR_WRITE(extension->data, output + offset,
|
||||||
isRequest);
|
isRequest);
|
||||||
@ -3723,6 +3869,12 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
|
|||||||
ret = EC_PARSE(ssl, input + offset, size, isRequest);
|
ret = EC_PARSE(ssl, input + offset, size, isRequest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST:
|
||||||
|
WOLFSSL_MSG("Certificate Status Request extension received");
|
||||||
|
|
||||||
|
ret = CSR_PARSE(ssl, input + offset, size, isRequest);
|
||||||
|
break;
|
||||||
|
|
||||||
case TLSX_RENEGOTIATION_INFO:
|
case TLSX_RENEGOTIATION_INFO:
|
||||||
WOLFSSL_MSG("Secure Renegotiation extension received");
|
WOLFSSL_MSG("Secure Renegotiation extension received");
|
||||||
|
|
||||||
|
@ -43,7 +43,11 @@
|
|||||||
|
|
||||||
#include <wolfssl/wolfcrypt/random.h>
|
#include <wolfssl/wolfcrypt/random.h>
|
||||||
#include <wolfssl/wolfcrypt/hash.h>
|
#include <wolfssl/wolfcrypt/hash.h>
|
||||||
|
#ifdef NO_INLINE
|
||||||
|
#include <wolfssl/wolfcrypt/misc.h>
|
||||||
|
#else
|
||||||
|
#include <wolfcrypt/src/misc.c>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_RC4
|
#ifndef NO_RC4
|
||||||
#include <wolfssl/wolfcrypt/arc4.h>
|
#include <wolfssl/wolfcrypt/arc4.h>
|
||||||
@ -8856,18 +8860,11 @@ int EncodeOcspRequest(OcspRequest* req)
|
|||||||
algoSz = SetAlgoID(SHAh, algoArray, hashType, 0);
|
algoSz = SetAlgoID(SHAh, algoArray, hashType, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
req->issuerHash = req->cert->issuerHash;
|
issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray);
|
||||||
issuerSz = SetDigest(req->cert->issuerHash, KEYID_SIZE, issuerArray);
|
issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray);
|
||||||
|
snSz = SetSerialNumber(req->serial, req->serialSz, snArray);
|
||||||
|
extSz = 0;
|
||||||
|
|
||||||
req->issuerKeyHash = req->cert->issuerKeyHash;
|
|
||||||
issuerKeySz = SetDigest(req->cert->issuerKeyHash,
|
|
||||||
KEYID_SIZE, issuerKeyArray);
|
|
||||||
|
|
||||||
req->serial = req->cert->serial;
|
|
||||||
req->serialSz = req->cert->serialSz;
|
|
||||||
snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
|
|
||||||
|
|
||||||
extSz = 0;
|
|
||||||
if (req->useNonce) {
|
if (req->useNonce) {
|
||||||
WC_RNG rng;
|
WC_RNG rng;
|
||||||
if (wc_InitRng(&rng) != 0) {
|
if (wc_InitRng(&rng) != 0) {
|
||||||
@ -8885,25 +8882,30 @@ int EncodeOcspRequest(OcspRequest* req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
|
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
|
||||||
|
|
||||||
for (i = 4; i >= 0; i--) {
|
for (i = 4; i >= 0; i--) {
|
||||||
seqSz[i] = SetSequence(totalSz, seqArray[i]);
|
seqSz[i] = SetSequence(totalSz, seqArray[i]);
|
||||||
totalSz += seqSz[i];
|
totalSz += seqSz[i];
|
||||||
if (i == 2) totalSz += extSz;
|
if (i == 2) totalSz += extSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalSz = 0;
|
totalSz = 0;
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
|
XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
|
||||||
totalSz += seqSz[i];
|
totalSz += seqSz[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(output + totalSz, algoArray, algoSz);
|
XMEMCPY(output + totalSz, algoArray, algoSz);
|
||||||
totalSz += algoSz;
|
totalSz += algoSz;
|
||||||
|
|
||||||
XMEMCPY(output + totalSz, issuerArray, issuerSz);
|
XMEMCPY(output + totalSz, issuerArray, issuerSz);
|
||||||
totalSz += issuerSz;
|
totalSz += issuerSz;
|
||||||
|
|
||||||
XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
|
XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
|
||||||
totalSz += issuerKeySz;
|
totalSz += issuerKeySz;
|
||||||
|
|
||||||
XMEMCPY(output + totalSz, snArray, snSz);
|
XMEMCPY(output + totalSz, snArray, snSz);
|
||||||
totalSz += snSz;
|
totalSz += snSz;
|
||||||
|
|
||||||
if (extSz != 0) {
|
if (extSz != 0) {
|
||||||
XMEMCPY(output + totalSz, extArray, extSz);
|
XMEMCPY(output + totalSz, extArray, extSz);
|
||||||
totalSz += extSz;
|
totalSz += extSz;
|
||||||
@ -8918,14 +8920,16 @@ void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
|
|||||||
{
|
{
|
||||||
WOLFSSL_ENTER("InitOcspRequest");
|
WOLFSSL_ENTER("InitOcspRequest");
|
||||||
|
|
||||||
req->cert = cert;
|
ForceZero(req, sizeof(OcspRequest));
|
||||||
req->useNonce = useNonce;
|
|
||||||
req->nonceSz = 0;
|
req->cert = cert;
|
||||||
req->issuerHash = NULL;
|
req->useNonce = useNonce;
|
||||||
req->issuerKeyHash = NULL;
|
req->issuerHash = cert->issuerHash;
|
||||||
req->serial = NULL;
|
req->issuerKeyHash = cert->issuerKeyHash;
|
||||||
req->dest = dest;
|
req->serial = cert->serial;
|
||||||
req->destSz = destSz;
|
req->serialSz = cert->serialSz;
|
||||||
|
req->dest = dest;
|
||||||
|
req->destSz = destSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1463,7 +1463,8 @@ typedef enum {
|
|||||||
TLSX_SERVER_NAME = 0x0000, /* a.k.a. SNI */
|
TLSX_SERVER_NAME = 0x0000, /* a.k.a. SNI */
|
||||||
TLSX_MAX_FRAGMENT_LENGTH = 0x0001,
|
TLSX_MAX_FRAGMENT_LENGTH = 0x0001,
|
||||||
TLSX_TRUNCATED_HMAC = 0x0004,
|
TLSX_TRUNCATED_HMAC = 0x0004,
|
||||||
TLSX_SUPPORTED_GROUPS = 0x000a,
|
TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stappling */
|
||||||
|
TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */
|
||||||
TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */
|
TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */
|
||||||
TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */
|
TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */
|
||||||
TLSX_SESSION_TICKET = 0x0023,
|
TLSX_SESSION_TICKET = 0x0023,
|
||||||
@ -1498,6 +1499,7 @@ WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
#elif defined(HAVE_SNI) \
|
#elif defined(HAVE_SNI) \
|
||||||
|| defined(HAVE_MAX_FRAGMENT) \
|
|| defined(HAVE_MAX_FRAGMENT) \
|
||||||
|| defined(HAVE_TRUNCATED_HMAC) \
|
|| defined(HAVE_TRUNCATED_HMAC) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|| defined(HAVE_SUPPORTED_CURVES) \
|
|| defined(HAVE_SUPPORTED_CURVES) \
|
||||||
|| defined(HAVE_ALPN) \
|
|| defined(HAVE_ALPN) \
|
||||||
|| defined(HAVE_QSH) \
|
|| defined(HAVE_QSH) \
|
||||||
@ -1569,6 +1571,18 @@ WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions);
|
|||||||
|
|
||||||
#endif /* HAVE_TRUNCATED_HMAC */
|
#endif /* HAVE_TRUNCATED_HMAC */
|
||||||
|
|
||||||
|
/** Certificate Status Request - RFC 6066 (session 8) */
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte status_type;
|
||||||
|
} CertificateStatusRequest;
|
||||||
|
|
||||||
|
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
|
||||||
|
byte status_type);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Supported Elliptic Curves - RFC 4492 (session 4) */
|
/** Supported Elliptic Curves - RFC 4492 (session 4) */
|
||||||
#ifdef HAVE_SUPPORTED_CURVES
|
#ifdef HAVE_SUPPORTED_CURVES
|
||||||
|
|
||||||
@ -2301,6 +2315,7 @@ typedef struct MsgsReceived {
|
|||||||
word16 got_hello_verify_request:1;
|
word16 got_hello_verify_request:1;
|
||||||
word16 got_session_ticket:1;
|
word16 got_session_ticket:1;
|
||||||
word16 got_certificate:1;
|
word16 got_certificate:1;
|
||||||
|
word16 got_certificate_status:1;
|
||||||
word16 got_server_key_exchange:1;
|
word16 got_server_key_exchange:1;
|
||||||
word16 got_certificate_request:1;
|
word16 got_certificate_request:1;
|
||||||
word16 got_server_hello_done:1;
|
word16 got_server_hello_done:1;
|
||||||
@ -2452,6 +2467,9 @@ struct WOLFSSL {
|
|||||||
#ifdef HAVE_TRUNCATED_HMAC
|
#ifdef HAVE_TRUNCATED_HMAC
|
||||||
byte truncated_hmac;
|
byte truncated_hmac;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
byte status_request;
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
|
SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
|
||||||
#endif /* user turned on */
|
#endif /* user turned on */
|
||||||
|
@ -188,6 +188,7 @@ enum AlertDescription {
|
|||||||
#endif
|
#endif
|
||||||
no_renegotiation = 100,
|
no_renegotiation = 100,
|
||||||
unrecognized_name = 112, /**< RFC 6066, section 3 */
|
unrecognized_name = 112, /**< RFC 6066, section 3 */
|
||||||
|
bad_certificate_status_response = 113, /**< RFC 6066, section 8 */
|
||||||
no_application_protocol = 120
|
no_application_protocol = 120
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1406,6 +1407,24 @@ WOLFSSL_API int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Certificate Status Request */
|
||||||
|
/* Certificate Status Type */
|
||||||
|
enum {
|
||||||
|
WOLFSSL_CSR_OCSP = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
|
||||||
|
WOLFSSL_API int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl,
|
||||||
|
unsigned char status_type);
|
||||||
|
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx,
|
||||||
|
unsigned char status_type);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Elliptic Curves */
|
/* Elliptic Curves */
|
||||||
enum {
|
enum {
|
||||||
WOLFSSL_ECC_SECP160R1 = 0x10,
|
WOLFSSL_ECC_SECP160R1 = 0x10,
|
||||||
|
Reference in New Issue
Block a user