mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
adds support to nonce extension in OCSP stapling (status request tls extension);
fix nonce encoding, there was a missing ASN.1 OctetString header;
This commit is contained in:
@@ -984,8 +984,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
if (statusRequest) {
|
||||
if (wolfSSL_UseCertificateStatusRequest(ssl, WOLFSSL_CSR_OCSP)
|
||||
!= SSL_SUCCESS)
|
||||
if (wolfSSL_UseCertificateStatusRequest(ssl, WOLFSSL_CSR_OCSP,
|
||||
WOLFSSL_CSR_OCSP_USE_NONCE) != SSL_SUCCESS)
|
||||
err_sys("UseCertificateStatusRequest failed");
|
||||
|
||||
wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE);
|
||||
|
12
src/ssl.c
12
src/ssl.c
@@ -796,21 +796,25 @@ int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
|
||||
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
|
||||
int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type)
|
||||
int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type,
|
||||
byte options)
|
||||
{
|
||||
if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type);
|
||||
return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type)
|
||||
int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type,
|
||||
byte options)
|
||||
{
|
||||
if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type);
|
||||
return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
|
||||
options);
|
||||
}
|
||||
|
||||
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
|
||||
|
79
src/tls.c
79
src/tls.c
@@ -1909,6 +1909,8 @@ static void TLSX_CSR_Free(CertificateStatusRequest* csr)
|
||||
|
||||
static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
|
||||
{
|
||||
word16 size = 0;
|
||||
|
||||
/* shut up compiler warnings */
|
||||
(void) csr; (void) isRequest;
|
||||
|
||||
@@ -1916,12 +1918,15 @@ static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
|
||||
if (isRequest) {
|
||||
switch (csr->status_type) {
|
||||
case WOLFSSL_CSR_OCSP:
|
||||
return ENUM_LEN + 2 * OPAQUE16_LEN;
|
||||
size += ENUM_LEN + 2 * OPAQUE16_LEN;
|
||||
|
||||
if (csr->request.ocsp.nonceSz)
|
||||
size += MAX_OCSP_EXT_SZ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
||||
@@ -1933,6 +1938,7 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
if (isRequest) {
|
||||
word16 offset = 0;
|
||||
word16 length = 0;
|
||||
|
||||
/* type */
|
||||
output[offset++] = csr->status_type;
|
||||
@@ -1944,8 +1950,15 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
||||
offset += OPAQUE16_LEN;
|
||||
|
||||
/* request extensions */
|
||||
c16toa(0, output + offset);
|
||||
offset += OPAQUE16_LEN;
|
||||
if (csr->request.ocsp.nonceSz)
|
||||
length = EncodeOcspRequestExtensions(
|
||||
&csr->request.ocsp,
|
||||
output + offset + OPAQUE16_LEN,
|
||||
MAX_OCSP_EXT_SZ);
|
||||
|
||||
c16toa(length, output + offset);
|
||||
offset += OPAQUE16_LEN + length;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1980,9 +1993,25 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
|
||||
/* enable extension at ssl level */
|
||||
ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
|
||||
csr->status_type);
|
||||
csr->status_type, csr->options);
|
||||
if (ret != SSL_SUCCESS)
|
||||
return ret;
|
||||
|
||||
switch (csr->status_type) {
|
||||
case WOLFSSL_CSR_OCSP:
|
||||
/* propagate nonce */
|
||||
if (csr->request.ocsp.nonceSz) {
|
||||
OcspRequest* request =
|
||||
TLSX_CSR_GetRequest(ssl->extensions);
|
||||
|
||||
if (request) {
|
||||
XMEMCPY(request->nonce, csr->request.ocsp.nonce,
|
||||
csr->request.ocsp.nonceSz);
|
||||
request->nonceSz = csr->request.ocsp.nonceSz;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ssl->status_request = 1;
|
||||
@@ -1998,15 +2027,29 @@ int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert)
|
||||
{
|
||||
TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
|
||||
CertificateStatusRequest* csr = extension ? extension->data : NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (csr) {
|
||||
switch (csr->status_type) {
|
||||
case WOLFSSL_CSR_OCSP:
|
||||
return InitOcspRequest(&csr->request.ocsp, cert, 0);
|
||||
case WOLFSSL_CSR_OCSP: {
|
||||
byte nonce[MAX_OCSP_NONCE_SZ];
|
||||
int nonceSz = csr->request.ocsp.nonceSz;
|
||||
|
||||
/* preserve nonce */
|
||||
XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz);
|
||||
|
||||
if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0)) != 0)
|
||||
return ret;
|
||||
|
||||
/* restore nonce */
|
||||
XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz);
|
||||
csr->request.ocsp.nonceSz = nonceSz;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* TLSX_CSR_GetRequest(TLSX* extensions)
|
||||
@@ -2044,7 +2087,8 @@ int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type)
|
||||
int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
|
||||
byte options)
|
||||
{
|
||||
CertificateStatusRequest* csr = NULL;
|
||||
int ret = 0;
|
||||
@@ -2060,6 +2104,23 @@ int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type)
|
||||
ForceZero(csr, sizeof(CertificateStatusRequest));
|
||||
|
||||
csr->status_type = status_type;
|
||||
csr->options = options;
|
||||
|
||||
switch (csr->status_type) {
|
||||
case WOLFSSL_CSR_OCSP:
|
||||
if (options & WOLFSSL_CSR_OCSP_USE_NONCE) {
|
||||
WC_RNG rng;
|
||||
|
||||
if (wc_InitRng(&rng) == 0) {
|
||||
if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce,
|
||||
MAX_OCSP_NONCE_SZ) == 0)
|
||||
csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ;
|
||||
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr)) != 0) {
|
||||
XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
|
||||
|
@@ -8786,53 +8786,40 @@ int OcspResponseDecode(OcspResponse* resp)
|
||||
}
|
||||
|
||||
|
||||
static word32 SetOcspReqExtensions(word32 extSz, byte* output,
|
||||
const byte* nonce, word32 nonceSz)
|
||||
word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
|
||||
{
|
||||
static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
|
||||
0x30, 0x01, 0x02 };
|
||||
byte seqArray[5][MAX_SEQ_SZ];
|
||||
word32 seqSz[5], totalSz;
|
||||
byte seqArray[6][MAX_SEQ_SZ];
|
||||
word32 seqSz[6], totalSz = (word32)sizeof(NonceObjId);
|
||||
|
||||
WOLFSSL_ENTER("SetOcspReqExtensions");
|
||||
|
||||
if (nonce == NULL || nonceSz == 0) return 0;
|
||||
if (!req || !output || !req->nonceSz)
|
||||
return 0;
|
||||
|
||||
seqArray[0][0] = ASN_OCTET_STRING;
|
||||
seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
|
||||
totalSz += req->nonceSz;
|
||||
totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
|
||||
totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
|
||||
seqArray[2][0] = ASN_OBJECT_ID;
|
||||
totalSz += seqSz[2] = 1 + SetLength(sizeof(NonceObjId), &seqArray[2][1]);
|
||||
totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
|
||||
totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
|
||||
totalSz += seqSz[5] = SetExplicit(2, totalSz, seqArray[5]);
|
||||
|
||||
seqArray[1][0] = ASN_OBJECT_ID;
|
||||
seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
|
||||
|
||||
totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId);
|
||||
|
||||
seqSz[2] = SetSequence(totalSz, seqArray[2]);
|
||||
totalSz += seqSz[2];
|
||||
|
||||
seqSz[3] = SetSequence(totalSz, seqArray[3]);
|
||||
totalSz += seqSz[3];
|
||||
|
||||
seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
|
||||
seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
|
||||
totalSz += seqSz[4];
|
||||
|
||||
if (totalSz < extSz)
|
||||
if (totalSz < size)
|
||||
{
|
||||
totalSz = 0;
|
||||
XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
|
||||
totalSz += seqSz[4];
|
||||
XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
|
||||
totalSz += seqSz[3];
|
||||
XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
|
||||
totalSz += seqSz[2];
|
||||
XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
|
||||
totalSz += seqSz[1];
|
||||
XMEMCPY(output + totalSz, seqArray[5], seqSz[5]); totalSz += seqSz[5];
|
||||
XMEMCPY(output + totalSz, seqArray[4], seqSz[4]); totalSz += seqSz[4];
|
||||
XMEMCPY(output + totalSz, seqArray[3], seqSz[3]); totalSz += seqSz[3];
|
||||
XMEMCPY(output + totalSz, seqArray[2], seqSz[2]); totalSz += seqSz[2];
|
||||
XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
|
||||
totalSz += (word32)sizeof(NonceObjId);
|
||||
XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
|
||||
totalSz += seqSz[0];
|
||||
XMEMCPY(output + totalSz, nonce, nonceSz);
|
||||
totalSz += nonceSz;
|
||||
XMEMCPY(output + totalSz, seqArray[1], seqSz[1]); totalSz += seqSz[1];
|
||||
XMEMCPY(output + totalSz, seqArray[0], seqSz[0]); totalSz += seqSz[0];
|
||||
XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
|
||||
totalSz += req->nonceSz;
|
||||
}
|
||||
|
||||
return totalSz;
|
||||
@@ -8865,8 +8852,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
|
||||
extSz = 0;
|
||||
|
||||
if (req->nonceSz)
|
||||
extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
|
||||
req->nonce, req->nonceSz);
|
||||
extSz = EncodeOcspRequestExtensions(req, extArray, MAX_OCSP_EXT_SZ);
|
||||
|
||||
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
|
||||
for (i = 4; i >= 0; i--) {
|
||||
|
@@ -1576,13 +1576,14 @@ WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions);
|
||||
|
||||
typedef struct {
|
||||
byte status_type;
|
||||
byte options;
|
||||
union {
|
||||
OcspRequest ocsp;
|
||||
} request;
|
||||
} CertificateStatusRequest;
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
|
||||
byte status_type);
|
||||
byte status_type, byte options);
|
||||
WOLFSSL_LOCAL int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert);
|
||||
WOLFSSL_LOCAL void* TLSX_CSR_GetRequest(TLSX* extensions);
|
||||
WOLFSSL_LOCAL int TLSX_CSR_ForceRequest(WOLFSSL* ssl);
|
||||
|
@@ -1413,14 +1413,19 @@ enum {
|
||||
WOLFSSL_CSR_OCSP = 1
|
||||
};
|
||||
|
||||
/* Certificate Status Options (flags) */
|
||||
enum {
|
||||
WOLFSSL_CSR_OCSP_USE_NONCE = 0x01
|
||||
};
|
||||
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
|
||||
WOLFSSL_API int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl,
|
||||
unsigned char status_type);
|
||||
unsigned char status_type, unsigned char options);
|
||||
|
||||
WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx,
|
||||
unsigned char status_type);
|
||||
unsigned char status_type, unsigned char options);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -188,7 +188,7 @@ enum Misc_ASN {
|
||||
MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ,
|
||||
#endif
|
||||
MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */
|
||||
MAX_OCSP_NONCE_SZ = 18, /* OCSP Nonce size */
|
||||
MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */
|
||||
EIGHTK_BUF = 8192, /* Tmp buffer size */
|
||||
MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2,
|
||||
/* use bigger NTRU size */
|
||||
@@ -722,9 +722,11 @@ struct OcspRequest {
|
||||
WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
|
||||
WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*);
|
||||
|
||||
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte);
|
||||
WOLFSSL_LOCAL void FreeOcspRequest(OcspRequest*);
|
||||
WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*, byte*, word32);
|
||||
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte);
|
||||
WOLFSSL_LOCAL void FreeOcspRequest(OcspRequest*);
|
||||
WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*, byte*, word32);
|
||||
WOLFSSL_LOCAL word32 EncodeOcspRequestExtensions(OcspRequest*, byte*, word32);
|
||||
|
||||
|
||||
WOLFSSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*);
|
||||
|
||||
|
Reference in New Issue
Block a user