mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +02:00
adds basic extension code for CERTIFICATE_STATUS_REQUEST_V2;
fixes EncodeOcspRequestExtensions() length check;
This commit is contained in:
21
configure.ac
21
configure.ac
@@ -1676,6 +1676,26 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Certificate Status Request v2 : a.k.a. OCSP stapling v2
|
||||||
|
AC_ARG_ENABLE([ocspstapling2],
|
||||||
|
[AS_HELP_STRING([--enable-ocspstapling2],[Enable Certificate Status Request v2 - a.k.a. OCSP Stapling v2 (default: disabled)])],
|
||||||
|
[ ENABLED_CERTIFICATE_STATUS_REQUEST_V2=$enableval ],
|
||||||
|
[ ENABLED_CERTIFICATE_STATUS_REQUEST_V2=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "x$ENABLED_CERTIFICATE_STATUS_REQUEST_V2" = "xyes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_CERTIFICATE_STATUS_REQUEST_V2"
|
||||||
|
|
||||||
|
# Requires OCSP make sure on
|
||||||
|
if test "x$ENABLED_OCSP" = "xno"
|
||||||
|
then
|
||||||
|
ENABLED_OCSP="yes"
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_OCSP"
|
||||||
|
AM_CONDITIONAL([BUILD_OCSP], [test "x$ENABLED_OCSP" = "xyes"])
|
||||||
|
fi
|
||||||
|
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)])],
|
||||||
@@ -2720,6 +2740,7 @@ 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 " * Certificate Status Request: $ENABLED_CERTIFICATE_STATUS_REQUEST"
|
echo " * Certificate Status Request: $ENABLED_CERTIFICATE_STATUS_REQUEST"
|
||||||
|
echo " * Certificate Status Request v2: $ENABLED_CERTIFICATE_STATUS_REQUEST_V2"
|
||||||
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"
|
||||||
|
@@ -358,7 +358,8 @@ static void Usage(void)
|
|||||||
printf("-o Perform OCSP lookup on peer certificate\n");
|
printf("-o Perform OCSP lookup on peer certificate\n");
|
||||||
printf("-O <url> Perform OCSP lookup using <url> as responder\n");
|
printf("-O <url> Perform OCSP lookup using <url> as responder\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
printf("-W Use OCSP Stapling\n");
|
printf("-W Use OCSP Stapling\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef ATOMIC_USER
|
#ifdef ATOMIC_USER
|
||||||
@@ -440,7 +441,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
#ifdef HAVE_TRUNCATED_HMAC
|
#ifdef HAVE_TRUNCATED_HMAC
|
||||||
byte truncatedHMAC = 0;
|
byte truncatedHMAC = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
byte statusRequest = 0;
|
byte statusRequest = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -674,7 +676,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W' :
|
case 'W' :
|
||||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
statusRequest = 1;
|
statusRequest = 1;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -1010,6 +1013,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||||||
wolfSSL_CTX_EnableOCSP(ctx, 0);
|
wolfSSL_CTX_EnableOCSP(ctx, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
if (statusRequest) {
|
||||||
|
if (wolfSSL_UseCertificateStatusRequestV2(ssl, WOLFSSL_CSR2_OCSP,
|
||||||
|
WOLFSSL_CSR2_OCSP_USE_NONCE) != SSL_SUCCESS)
|
||||||
|
err_sys("UseCertificateStatusRequest failed");
|
||||||
|
|
||||||
|
wolfSSL_CTX_EnableOCSP(ctx, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tcp_connect(&sockfd, host, port, doDTLS, ssl);
|
tcp_connect(&sockfd, host, port, doDTLS, ssl);
|
||||||
|
|
||||||
|
@@ -725,7 +725,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
|
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
|
if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
|
||||||
err_sys("can't enable OCSP Stapling Certificate Manager");
|
err_sys("can't enable OCSP Stapling Certificate Manager");
|
||||||
if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
|
if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
|
||||||
|
@@ -4822,9 +4822,11 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
switch (status_type) {
|
switch (status_type) {
|
||||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
|
|
||||||
case WOLFSSL_CSR_OCSP: {
|
/* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
|
||||||
|
case WOLFSSL_CSR2_OCSP: {
|
||||||
OcspRequest* request = TLSX_CSR_GetRequest(ssl->extensions);
|
OcspRequest* request = TLSX_CSR_GetRequest(ssl->extensions);
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
@@ -4842,6 +4844,12 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
if (ssl->status_request_v2) {
|
||||||
|
ssl->status_request_v2 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
@@ -8147,7 +8155,8 @@ int SendCertificateRequest(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer status)
|
static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer status)
|
||||||
{
|
{
|
||||||
byte* output = NULL;
|
byte* output = NULL;
|
||||||
@@ -8232,9 +8241,15 @@ int SendCertificateStatus(WOLFSSL* ssl)
|
|||||||
status_type = ssl->status_request;
|
status_type = ssl->status_request;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
status_type = status_type ? status_type : ssl->status_request_v2;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (status_type) {
|
switch (status_type) {
|
||||||
#if defined HAVE_CERTIFICATE_STATUS_REQUEST
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
case WOLFSSL_CSR_OCSP: {
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
|
/* case WOLFSSL_CSR_OCSP: */
|
||||||
|
case WOLFSSL_CSR2_OCSP: {
|
||||||
OcspRequest* request = ssl->ctx->certOcspRequest;
|
OcspRequest* request = ssl->ctx->certOcspRequest;
|
||||||
buffer response = {NULL, 0};
|
buffer response = {NULL, 0};
|
||||||
|
|
||||||
@@ -8321,6 +8336,11 @@ int SendCertificateStatus(WOLFSSL* ssl)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
34
src/ssl.c
34
src/ssl.c
@@ -826,6 +826,31 @@ int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type,
|
|||||||
|
|
||||||
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
|
||||||
|
int wolfSSL_UseCertificateStatusRequestV2(WOLFSSL* ssl, byte status_type,
|
||||||
|
byte options)
|
||||||
|
{
|
||||||
|
if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
|
||||||
|
options);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSL_CTX_UseCertificateStatusRequestV2(WOLFSSL_CTX* ctx,
|
||||||
|
byte status_type, byte options)
|
||||||
|
{
|
||||||
|
if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
|
||||||
|
options);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
|
||||||
|
|
||||||
/* Elliptic Curves */
|
/* Elliptic Curves */
|
||||||
#ifdef HAVE_SUPPORTED_CURVES
|
#ifdef HAVE_SUPPORTED_CURVES
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
@@ -1643,7 +1668,8 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
|
|||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (cm->ocsp)
|
if (cm->ocsp)
|
||||||
FreeOCSP(cm->ocsp, 1);
|
FreeOCSP(cm->ocsp, 1);
|
||||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
if (cm->ocsp_stapling)
|
if (cm->ocsp_stapling)
|
||||||
FreeOCSP(cm->ocsp_stapling, 1);
|
FreeOCSP(cm->ocsp_stapling, 1);
|
||||||
#endif
|
#endif
|
||||||
@@ -3473,7 +3499,8 @@ int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
|
|||||||
if (cm == NULL)
|
if (cm == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
if (cm->ocsp_stapling == NULL) {
|
if (cm->ocsp_stapling == NULL) {
|
||||||
cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
|
cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
|
||||||
cm->heap, DYNAMIC_TYPE_OCSP);
|
cm->heap, DYNAMIC_TYPE_OCSP);
|
||||||
@@ -3669,7 +3696,8 @@ int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
|
int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
|
||||||
{
|
{
|
||||||
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
|
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
|
||||||
|
324
src/tls.c
324
src/tls.c
@@ -1917,6 +1917,7 @@ static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
|
|||||||
|
|
||||||
if (csr->request.ocsp.nonceSz)
|
if (csr->request.ocsp.nonceSz)
|
||||||
size += OCSP_NONCE_EXT_SZ;
|
size += OCSP_NONCE_EXT_SZ;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1949,7 +1950,7 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
|||||||
length = EncodeOcspRequestExtensions(
|
length = EncodeOcspRequestExtensions(
|
||||||
&csr->request.ocsp,
|
&csr->request.ocsp,
|
||||||
output + offset + OPAQUE16_LEN,
|
output + offset + OPAQUE16_LEN,
|
||||||
MAX_OCSP_EXT_SZ);
|
OCSP_NONCE_EXT_SZ);
|
||||||
|
|
||||||
c16toa(length, output + offset);
|
c16toa(length, output + offset);
|
||||||
offset += OPAQUE16_LEN + length;
|
offset += OPAQUE16_LEN + length;
|
||||||
@@ -2052,6 +2053,13 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if using status_request and already sending it, skip this one */
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
if (ssl->status_request_v2)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* accept the first good status_type and return */
|
||||||
ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
|
ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
|
||||||
0);
|
0);
|
||||||
if (ret != SSL_SUCCESS)
|
if (ret != SSL_SUCCESS)
|
||||||
@@ -2187,6 +2195,301 @@ int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
|
|||||||
|
|
||||||
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Certificate Status Request v2 */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
|
||||||
|
static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2)
|
||||||
|
{
|
||||||
|
CertificateStatusRequestItemV2* next;
|
||||||
|
|
||||||
|
for (; csr2; csr2 = next) {
|
||||||
|
next = csr2->next;
|
||||||
|
|
||||||
|
switch (csr2->status_type) {
|
||||||
|
case WOLFSSL_CSR2_OCSP:
|
||||||
|
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||||
|
FreeOcspRequest(&csr2->request.ocsp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(csr2, NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2,
|
||||||
|
byte isRequest)
|
||||||
|
{
|
||||||
|
word16 size = 0;
|
||||||
|
|
||||||
|
/* shut up compiler warnings */
|
||||||
|
(void) csr2; (void) isRequest;
|
||||||
|
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
if (isRequest) {
|
||||||
|
CertificateStatusRequestItemV2* next;
|
||||||
|
|
||||||
|
for (size = OPAQUE16_LEN; csr2; csr2 = next) {
|
||||||
|
next = csr2->next;
|
||||||
|
|
||||||
|
switch (csr2->status_type) {
|
||||||
|
case WOLFSSL_CSR2_OCSP:
|
||||||
|
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||||
|
size += ENUM_LEN + 3 * OPAQUE16_LEN;
|
||||||
|
|
||||||
|
if (csr2->request.ocsp.nonceSz)
|
||||||
|
size += OCSP_NONCE_EXT_SZ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
|
||||||
|
byte* output, byte isRequest)
|
||||||
|
{
|
||||||
|
/* shut up compiler warnings */
|
||||||
|
(void) csr2; (void) output; (void) isRequest;
|
||||||
|
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
if (isRequest) {
|
||||||
|
word16 offset;
|
||||||
|
word16 length;
|
||||||
|
|
||||||
|
for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) {
|
||||||
|
/* status_type */
|
||||||
|
output[offset++] = csr2->status_type;
|
||||||
|
|
||||||
|
/* request */
|
||||||
|
switch (csr2->status_type) {
|
||||||
|
case WOLFSSL_CSR2_OCSP:
|
||||||
|
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||||
|
/* request_length */
|
||||||
|
length = 2 * OPAQUE16_LEN;
|
||||||
|
|
||||||
|
if (csr2->request.ocsp.nonceSz)
|
||||||
|
length += OCSP_NONCE_EXT_SZ;
|
||||||
|
|
||||||
|
c16toa(length, output + offset);
|
||||||
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
/* responder id list */
|
||||||
|
c16toa(0, output + offset);
|
||||||
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
/* request extensions */
|
||||||
|
length = 0;
|
||||||
|
|
||||||
|
if (csr2->request.ocsp.nonceSz)
|
||||||
|
length = EncodeOcspRequestExtensions(
|
||||||
|
&csr2->request.ocsp,
|
||||||
|
output + offset + OPAQUE16_LEN,
|
||||||
|
OCSP_NONCE_EXT_SZ);
|
||||||
|
|
||||||
|
c16toa(length, output + offset);
|
||||||
|
offset += OPAQUE16_LEN + length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* list size */
|
||||||
|
c16toa(offset - OPAQUE16_LEN, output);
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||||
|
byte isRequest)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* shut up compiler warnings */
|
||||||
|
(void) ssl; (void) input;
|
||||||
|
|
||||||
|
if (!isRequest) {
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
|
||||||
|
CertificateStatusRequestItemV2* csr2 = extension ? extension->data
|
||||||
|
: NULL;
|
||||||
|
|
||||||
|
if (!csr2) {
|
||||||
|
/* look at context level */
|
||||||
|
|
||||||
|
extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2);
|
||||||
|
csr2 = extension ? extension->data : NULL;
|
||||||
|
|
||||||
|
if (!csr2)
|
||||||
|
return BUFFER_ERROR; /* unexpected extension */
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl->status_request_v2 = 1;
|
||||||
|
|
||||||
|
return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
byte status_type;
|
||||||
|
word16 request_length;
|
||||||
|
word16 offset = 0;
|
||||||
|
word16 size = 0;
|
||||||
|
|
||||||
|
/* list size */
|
||||||
|
ato16(input + offset, &request_length);
|
||||||
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
if (length - OPAQUE16_LEN != request_length)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
while (length > offset) {
|
||||||
|
if (length - offset < ENUM_LEN + OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
status_type = input[offset++];
|
||||||
|
|
||||||
|
ato16(input + offset, &request_length);
|
||||||
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
if (length - offset < request_length)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
switch (status_type) {
|
||||||
|
case WOLFSSL_CSR2_OCSP:
|
||||||
|
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||||
|
/* skip responder_id_list */
|
||||||
|
if (length - offset < OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
ato16(input + offset, &size);
|
||||||
|
offset += OPAQUE16_LEN + size;
|
||||||
|
|
||||||
|
/* skip request_extensions */
|
||||||
|
if (length - offset < OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
ato16(input + offset, &size);
|
||||||
|
offset += OPAQUE16_LEN + size;
|
||||||
|
|
||||||
|
if (offset > length)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
/* is able to send OCSP response? */
|
||||||
|
if (ssl->ctx->cm == NULL
|
||||||
|
|| !ssl->ctx->cm->ocspStaplingEnabled)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* unkown status type, skipping! */
|
||||||
|
offset += request_length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if using status_request and already sending it, skip this one */
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
if (ssl->status_request)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* accept the first good status_type and return */
|
||||||
|
ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
|
||||||
|
status_type, 0);
|
||||||
|
if (ret != SSL_SUCCESS)
|
||||||
|
return ret; /* throw error */
|
||||||
|
|
||||||
|
TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
|
||||||
|
ssl->status_request_v2 = status_type;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
|
||||||
|
byte options)
|
||||||
|
{
|
||||||
|
TLSX* extension = NULL;
|
||||||
|
CertificateStatusRequestItemV2* csr2 = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (status_type != WOLFSSL_CSR2_OCSP
|
||||||
|
&& status_type != WOLFSSL_CSR2_OCSP_MULTI)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
csr2 = (CertificateStatusRequestItemV2*)
|
||||||
|
XMALLOC(sizeof(CertificateStatusRequestItemV2), NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
if (!csr2)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
ForceZero(csr2, sizeof(CertificateStatusRequestItemV2));
|
||||||
|
|
||||||
|
csr2->status_type = status_type;
|
||||||
|
csr2->options = options;
|
||||||
|
csr2->next = NULL;
|
||||||
|
|
||||||
|
switch (csr2->status_type) {
|
||||||
|
case WOLFSSL_CSR2_OCSP:
|
||||||
|
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||||
|
if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) {
|
||||||
|
WC_RNG rng;
|
||||||
|
|
||||||
|
if (wc_InitRng(&rng) == 0) {
|
||||||
|
if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp.nonce,
|
||||||
|
MAX_OCSP_NONCE_SZ) == 0)
|
||||||
|
csr2->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ;
|
||||||
|
|
||||||
|
wc_FreeRng(&rng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* append new item */
|
||||||
|
if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) {
|
||||||
|
CertificateStatusRequestItemV2* last =
|
||||||
|
(CertificateStatusRequestItemV2*)extension->data;
|
||||||
|
|
||||||
|
for (; last->next; last = last->next);
|
||||||
|
|
||||||
|
last->next = csr2;
|
||||||
|
}
|
||||||
|
else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2))) {
|
||||||
|
XFREE(csr2, NULL, DYNAMIC_TYPE_TLSX);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CSR2_FREE_ALL TLSX_CSR2_FreeAll
|
||||||
|
#define CSR2_GET_SIZE TLSX_CSR2_GetSize
|
||||||
|
#define CSR2_WRITE TLSX_CSR2_Write
|
||||||
|
#define CSR2_PARSE TLSX_CSR2_Parse
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CSR2_FREE_ALL(data)
|
||||||
|
#define CSR2_GET_SIZE(a, b) 0
|
||||||
|
#define CSR2_WRITE(a, b, c) 0
|
||||||
|
#define CSR2_PARSE(a, b, c, d) 0
|
||||||
|
|
||||||
|
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Supported Elliptic Curves */
|
/* Supported Elliptic Curves */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -3400,6 +3703,10 @@ void TLSX_FreeAll(TLSX* list)
|
|||||||
CSR_FREE_ALL(extension->data);
|
CSR_FREE_ALL(extension->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST_V2:
|
||||||
|
CSR2_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;
|
||||||
@@ -3471,6 +3778,10 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
|
|||||||
length += CSR_GET_SIZE(extension->data, isRequest);
|
length += CSR_GET_SIZE(extension->data, isRequest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST_V2:
|
||||||
|
length += CSR2_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;
|
||||||
@@ -3545,6 +3856,11 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
|||||||
isRequest);
|
isRequest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST_V2:
|
||||||
|
offset += CSR2_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);
|
||||||
@@ -4044,6 +4360,12 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
|
|||||||
ret = CSR_PARSE(ssl, input + offset, size, isRequest);
|
ret = CSR_PARSE(ssl, input + offset, size, isRequest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TLSX_STATUS_REQUEST_V2:
|
||||||
|
WOLFSSL_MSG("Certificate Status Request v2 extension received");
|
||||||
|
|
||||||
|
ret = CSR2_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");
|
||||||
|
|
||||||
|
@@ -8860,8 +8860,9 @@ word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
|
|||||||
totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
|
totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
|
||||||
totalSz += seqSz[5] = SetExplicit(2, totalSz, seqArray[5]);
|
totalSz += seqSz[5] = SetExplicit(2, totalSz, seqArray[5]);
|
||||||
|
|
||||||
if (totalSz < size)
|
if (totalSz > size)
|
||||||
{
|
return 0;
|
||||||
|
|
||||||
totalSz = 0;
|
totalSz = 0;
|
||||||
|
|
||||||
XMEMCPY(output + totalSz, seqArray[5], seqSz[5]);
|
XMEMCPY(output + totalSz, seqArray[5], seqSz[5]);
|
||||||
@@ -8887,7 +8888,6 @@ word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
|
|||||||
|
|
||||||
XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
|
XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
|
||||||
totalSz += req->nonceSz;
|
totalSz += req->nonceSz;
|
||||||
}
|
|
||||||
|
|
||||||
return totalSz;
|
return totalSz;
|
||||||
}
|
}
|
||||||
@@ -8919,7 +8919,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
|
|||||||
extSz = 0;
|
extSz = 0;
|
||||||
|
|
||||||
if (req->nonceSz)
|
if (req->nonceSz)
|
||||||
extSz = EncodeOcspRequestExtensions(req, extArray, MAX_OCSP_EXT_SZ);
|
extSz = EncodeOcspRequestExtensions(req, extArray, OCSP_NONCE_EXT_SZ);
|
||||||
|
|
||||||
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
|
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
|
||||||
for (i = 4; i >= 0; i--) {
|
for (i = 4; i >= 0; i--) {
|
||||||
|
@@ -1364,7 +1364,8 @@ struct WOLFSSL_CERT_MANAGER {
|
|||||||
void* heap; /* heap helper */
|
void* heap; /* heap helper */
|
||||||
WOLFSSL_CRL* crl; /* CRL checker */
|
WOLFSSL_CRL* crl; /* CRL checker */
|
||||||
WOLFSSL_OCSP* ocsp; /* OCSP checker */
|
WOLFSSL_OCSP* ocsp; /* OCSP checker */
|
||||||
#if !defined(NO_WOLFSSL_SEVER) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
#if !defined(NO_WOLFSSL_SEVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
|
||||||
WOLFSSL_OCSP* ocsp_stapling; /* OCSP checker for OCSP stapling */
|
WOLFSSL_OCSP* ocsp_stapling; /* OCSP checker for OCSP stapling */
|
||||||
#endif
|
#endif
|
||||||
char* ocspOverrideURL; /* use this responder */
|
char* ocspOverrideURL; /* use this responder */
|
||||||
@@ -1470,6 +1471,7 @@ typedef enum {
|
|||||||
TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stappling */
|
TLSX_STATUS_REQUEST = 0x0005, /* a.k.a. OCSP stappling */
|
||||||
TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */
|
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_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stappling v2 */
|
||||||
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,
|
||||||
TLSX_RENEGOTIATION_INFO = 0xff01
|
TLSX_RENEGOTIATION_INFO = 0xff01
|
||||||
@@ -1504,6 +1506,7 @@ WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
|| defined(HAVE_MAX_FRAGMENT) \
|
|| defined(HAVE_MAX_FRAGMENT) \
|
||||||
|| defined(HAVE_TRUNCATED_HMAC) \
|
|| defined(HAVE_TRUNCATED_HMAC) \
|
||||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||||
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
|
||||||
|| defined(HAVE_SUPPORTED_CURVES) \
|
|| defined(HAVE_SUPPORTED_CURVES) \
|
||||||
|| defined(HAVE_ALPN) \
|
|| defined(HAVE_ALPN) \
|
||||||
|| defined(HAVE_QSH) \
|
|| defined(HAVE_QSH) \
|
||||||
@@ -1594,6 +1597,24 @@ WOLFSSL_LOCAL int TLSX_CSR_ForceRequest(WOLFSSL* ssl);
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Certificate Status Request v2 - RFC 6961 */
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
|
||||||
|
typedef struct CSRIv2 {
|
||||||
|
byte status_type;
|
||||||
|
byte options;
|
||||||
|
word16 request_length;
|
||||||
|
union {
|
||||||
|
OcspRequest ocsp;
|
||||||
|
} request;
|
||||||
|
struct CSRIv2* next;
|
||||||
|
} CertificateStatusRequestItemV2;
|
||||||
|
|
||||||
|
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequestV2(TLSX** extensions,
|
||||||
|
byte status_type, byte options);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Supported Elliptic Curves - RFC 4492 (session 4) */
|
/** Supported Elliptic Curves - RFC 4492 (session 4) */
|
||||||
#ifdef HAVE_SUPPORTED_CURVES
|
#ifdef HAVE_SUPPORTED_CURVES
|
||||||
|
|
||||||
@@ -2485,6 +2506,9 @@ struct WOLFSSL {
|
|||||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
byte status_request;
|
byte status_request;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
byte status_request_v2;
|
||||||
|
#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 */
|
||||||
|
@@ -1439,6 +1439,30 @@ WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Certificate Status Request v2 */
|
||||||
|
/* Certificate Status Type */
|
||||||
|
enum {
|
||||||
|
WOLFSSL_CSR2_OCSP = 1,
|
||||||
|
WOLFSSL_CSR2_OCSP_MULTI = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Certificate Status v2 Options (flags) */
|
||||||
|
enum {
|
||||||
|
WOLFSSL_CSR2_OCSP_USE_NONCE = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||||
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
|
|
||||||
|
WOLFSSL_API int wolfSSL_UseCertificateStatusRequestV2(WOLFSSL* ssl,
|
||||||
|
unsigned char status_type, unsigned char options);
|
||||||
|
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequestV2(WOLFSSL_CTX* ctx,
|
||||||
|
unsigned char status_type, unsigned char options);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Elliptic Curves */
|
/* Elliptic Curves */
|
||||||
enum {
|
enum {
|
||||||
WOLFSSL_ECC_SECP160R1 = 0x10,
|
WOLFSSL_ECC_SECP160R1 = 0x10,
|
||||||
|
Reference in New Issue
Block a user