mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +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
|
||||
|
||||
# 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)
|
||||
AC_ARG_ENABLE([renegotiation-indication],
|
||||
[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 " * Truncated HMAC: $ENABLED_TRUNCATED_HMAC"
|
||||
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 " * Session Ticket: $ENABLED_SESSION_TICKET"
|
||||
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 <url> Perform OCSP lookup using <url> as responder\n");
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
printf("-W Use OCSP Stapling\n");
|
||||
#endif
|
||||
#ifdef ATOMIC_USER
|
||||
@@ -440,7 +441,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#ifdef HAVE_TRUNCATED_HMAC
|
||||
byte truncatedHMAC = 0;
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
byte statusRequest = 0;
|
||||
#endif
|
||||
|
||||
@@ -674,7 +676,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
break;
|
||||
|
||||
case 'W' :
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
statusRequest = 1;
|
||||
#endif
|
||||
break;
|
||||
@@ -1010,6 +1013,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
wolfSSL_CTX_EnableOCSP(ctx, 0);
|
||||
}
|
||||
#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);
|
||||
|
||||
|
@@ -725,7 +725,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
|
||||
}
|
||||
#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)
|
||||
err_sys("can't enable OCSP Stapling Certificate Manager");
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@@ -4842,6 +4844,12 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
byte* output = NULL;
|
||||
@@ -8232,9 +8241,15 @@ int SendCertificateStatus(WOLFSSL* ssl)
|
||||
status_type = ssl->status_request;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
status_type = status_type ? status_type : ssl->status_request_v2;
|
||||
#endif
|
||||
|
||||
switch (status_type) {
|
||||
#if defined HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
case WOLFSSL_CSR_OCSP: {
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
/* case WOLFSSL_CSR_OCSP: */
|
||||
case WOLFSSL_CSR2_OCSP: {
|
||||
OcspRequest* request = ssl->ctx->certOcspRequest;
|
||||
buffer response = {NULL, 0};
|
||||
|
||||
@@ -8321,6 +8336,11 @@ int SendCertificateStatus(WOLFSSL* ssl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
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 */
|
||||
|
||||
#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 */
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
@@ -1643,7 +1668,8 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
|
||||
#ifdef HAVE_OCSP
|
||||
if (cm->ocsp)
|
||||
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)
|
||||
FreeOCSP(cm->ocsp_stapling, 1);
|
||||
#endif
|
||||
@@ -3473,7 +3499,8 @@ int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
|
||||
if (cm == NULL)
|
||||
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) {
|
||||
cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
|
||||
cm->heap, DYNAMIC_TYPE_OCSP);
|
||||
@@ -3669,7 +3696,8 @@ int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
|
||||
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)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
|
||||
|
328
src/tls.c
328
src/tls.c
@@ -919,7 +919,7 @@ static word16 TLSX_ALPN_GetSize(ALPN *list)
|
||||
length++; /* protocol name length is on one byte */
|
||||
length += (word16)XSTRLEN(alpn->protocol_name);
|
||||
}
|
||||
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
@@ -946,7 +946,7 @@ static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
|
||||
|
||||
/* writing list length */
|
||||
c16toa(offset - OPAQUE16_LEN, output);
|
||||
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
@@ -1917,6 +1917,7 @@ static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
|
||||
|
||||
if (csr->request.ocsp.nonceSz)
|
||||
size += OCSP_NONCE_EXT_SZ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1949,7 +1950,7 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
||||
length = EncodeOcspRequestExtensions(
|
||||
&csr->request.ocsp,
|
||||
output + offset + OPAQUE16_LEN,
|
||||
MAX_OCSP_EXT_SZ);
|
||||
OCSP_NONCE_EXT_SZ);
|
||||
|
||||
c16toa(length, output + offset);
|
||||
offset += OPAQUE16_LEN + length;
|
||||
@@ -2052,6 +2053,13 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
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,
|
||||
0);
|
||||
if (ret != SSL_SUCCESS)
|
||||
@@ -2187,6 +2195,301 @@ int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
|
||||
|
||||
#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 */
|
||||
/******************************************************************************/
|
||||
@@ -3400,6 +3703,10 @@ void TLSX_FreeAll(TLSX* list)
|
||||
CSR_FREE_ALL(extension->data);
|
||||
break;
|
||||
|
||||
case TLSX_STATUS_REQUEST_V2:
|
||||
CSR2_FREE_ALL(extension->data);
|
||||
break;
|
||||
|
||||
case TLSX_RENEGOTIATION_INFO:
|
||||
SCR_FREE_ALL(extension->data);
|
||||
break;
|
||||
@@ -3471,6 +3778,10 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
|
||||
length += CSR_GET_SIZE(extension->data, isRequest);
|
||||
break;
|
||||
|
||||
case TLSX_STATUS_REQUEST_V2:
|
||||
length += CSR2_GET_SIZE(extension->data, isRequest);
|
||||
break;
|
||||
|
||||
case TLSX_RENEGOTIATION_INFO:
|
||||
length += SCR_GET_SIZE(extension->data, isRequest);
|
||||
break;
|
||||
@@ -3545,6 +3856,11 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
||||
isRequest);
|
||||
break;
|
||||
|
||||
case TLSX_STATUS_REQUEST_V2:
|
||||
offset += CSR2_WRITE(extension->data, output + offset,
|
||||
isRequest);
|
||||
break;
|
||||
|
||||
case TLSX_RENEGOTIATION_INFO:
|
||||
offset += SCR_WRITE(extension->data, output + offset,
|
||||
isRequest);
|
||||
@@ -4044,6 +4360,12 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
|
||||
ret = CSR_PARSE(ssl, input + offset, size, isRequest);
|
||||
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:
|
||||
WOLFSSL_MSG("Secure Renegotiation extension received");
|
||||
|
||||
|
@@ -8860,34 +8860,34 @@ word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
|
||||
totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
|
||||
totalSz += seqSz[5] = SetExplicit(2, totalSz, seqArray[5]);
|
||||
|
||||
if (totalSz < size)
|
||||
{
|
||||
totalSz = 0;
|
||||
if (totalSz > size)
|
||||
return 0;
|
||||
|
||||
XMEMCPY(output + totalSz, seqArray[5], seqSz[5]);
|
||||
totalSz += seqSz[5];
|
||||
totalSz = 0;
|
||||
|
||||
XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
|
||||
totalSz += seqSz[4];
|
||||
XMEMCPY(output + totalSz, seqArray[5], seqSz[5]);
|
||||
totalSz += seqSz[5];
|
||||
|
||||
XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
|
||||
totalSz += seqSz[3];
|
||||
XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
|
||||
totalSz += seqSz[4];
|
||||
|
||||
XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
|
||||
totalSz += seqSz[2];
|
||||
XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
|
||||
totalSz += seqSz[3];
|
||||
|
||||
XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
|
||||
totalSz += (word32)sizeof(NonceObjId);
|
||||
XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
|
||||
totalSz += seqSz[2];
|
||||
|
||||
XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
|
||||
totalSz += seqSz[1];
|
||||
XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
|
||||
totalSz += (word32)sizeof(NonceObjId);
|
||||
|
||||
XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
|
||||
totalSz += seqSz[0];
|
||||
XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
|
||||
totalSz += seqSz[1];
|
||||
|
||||
XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
|
||||
totalSz += req->nonceSz;
|
||||
}
|
||||
XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
|
||||
totalSz += seqSz[0];
|
||||
|
||||
XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
|
||||
totalSz += req->nonceSz;
|
||||
|
||||
return totalSz;
|
||||
}
|
||||
@@ -8919,7 +8919,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
|
||||
extSz = 0;
|
||||
|
||||
if (req->nonceSz)
|
||||
extSz = EncodeOcspRequestExtensions(req, extArray, MAX_OCSP_EXT_SZ);
|
||||
extSz = EncodeOcspRequestExtensions(req, extArray, OCSP_NONCE_EXT_SZ);
|
||||
|
||||
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
|
||||
for (i = 4; i >= 0; i--) {
|
||||
|
@@ -1364,7 +1364,8 @@ struct WOLFSSL_CERT_MANAGER {
|
||||
void* heap; /* heap helper */
|
||||
WOLFSSL_CRL* crl; /* CRL 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 */
|
||||
#endif
|
||||
char* ocspOverrideURL; /* use this responder */
|
||||
@@ -1470,6 +1471,7 @@ typedef enum {
|
||||
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_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stappling v2 */
|
||||
TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */
|
||||
TLSX_SESSION_TICKET = 0x0023,
|
||||
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_TRUNCATED_HMAC) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
|
||||
|| defined(HAVE_SUPPORTED_CURVES) \
|
||||
|| defined(HAVE_ALPN) \
|
||||
|| defined(HAVE_QSH) \
|
||||
@@ -1594,6 +1597,24 @@ WOLFSSL_LOCAL int TLSX_CSR_ForceRequest(WOLFSSL* ssl);
|
||||
|
||||
#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) */
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
|
||||
@@ -2485,6 +2506,9 @@ struct WOLFSSL {
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
byte status_request;
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
byte status_request_v2;
|
||||
#endif
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
|
||||
#endif /* user turned on */
|
||||
|
@@ -1439,6 +1439,30 @@ WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx,
|
||||
#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 */
|
||||
enum {
|
||||
WOLFSSL_ECC_SECP160R1 = 0x10,
|
||||
|
Reference in New Issue
Block a user