mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #5197 from JacobBarthelmeh/OCSP
RSA-PSS with OCSP and add simple OCSP response der verify test casepull/5573/head
commit
38418b31f1
|
@ -32,4 +32,7 @@ EXTRA_DIST += \
|
|||
certs/ocsp/server5-key.pem \
|
||||
certs/ocsp/server5-cert.pem \
|
||||
certs/ocsp/root-ca-key.pem \
|
||||
certs/ocsp/root-ca-cert.pem
|
||||
certs/ocsp/root-ca-cert.pem \
|
||||
certs/ocsp/test-response.der \
|
||||
certs/ocsp/test-response-rsapss.der \
|
||||
certs/ocsp/test-response-nointern.der
|
||||
|
|
|
@ -79,3 +79,27 @@ update_cert server2 "www2.wolfssl.com" intermediate1-ca
|
|||
update_cert server3 "www3.wolfssl.com" intermediate2-ca v3_req2 07
|
||||
update_cert server4 "www4.wolfssl.com" intermediate2-ca v3_req2 08 # REVOKED
|
||||
update_cert server5 "www5.wolfssl.com" intermediate3-ca v3_req3 09
|
||||
|
||||
|
||||
# Create response DER buffer for test
|
||||
openssl ocsp -port 22221 -ndays 1000 -index index-ca-and-intermediate-cas.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA root-ca-cert.pem -partial_chain &
|
||||
PID=$!
|
||||
|
||||
openssl ocsp -issuer ./root-ca-cert.pem -cert ./intermediate1-ca-cert.pem -url http://localhost:22221/ -respout test-response.der -noverify
|
||||
openssl ocsp -issuer ./root-ca-cert.pem -cert ./intermediate1-ca-cert.pem -url http://localhost:22221/ -respout test-response-nointern.der -no_intern -noverify
|
||||
kill $PID
|
||||
wait $PID
|
||||
|
||||
|
||||
# now start up a responder that signs using rsa-pss
|
||||
openssl ocsp -port 22221 -ndays 1000 -index index-ca-and-intermediate-cas.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA root-ca-cert.pem -rsigopt rsa_padding_mode:pss &
|
||||
PID=$!
|
||||
|
||||
openssl ocsp -issuer ./root-ca-cert.pem -cert ./intermediate1-ca-cert.pem -url http://localhost:22221/ -respout test-response-rsapss.der -noverify
|
||||
# can verify with the following command
|
||||
# openssl ocsp -respin test-response-nointern.der -CAfile root-ca-cert.pem -issuer intermediate1-ca-cert.pem
|
||||
|
||||
kill $PID
|
||||
wait $PID
|
||||
|
||||
exit 0
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -826,6 +826,7 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
|
|||
OcspResponse *resp = NULL;
|
||||
word32 idx = 0;
|
||||
int length = 0;
|
||||
int ret;
|
||||
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
@ -867,7 +868,10 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
|
|||
XMEMCPY(resp->source, *data, len);
|
||||
resp->maxIdx = len;
|
||||
|
||||
if (OcspResponseDecode(resp, NULL, NULL, 1) != 0) {
|
||||
ret = OcspResponseDecode(resp, NULL, NULL, 1);
|
||||
if (ret != 0 && ret != ASN_OCSP_CONFIRM_E) {
|
||||
/* for just converting from a DER to an internal structure the CA may
|
||||
* not yet be known to this function for signature verification */
|
||||
wolfSSL_OCSP_RESPONSE_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
|
|
89
tests/api.c
89
tests/api.c
|
@ -1605,6 +1605,94 @@ static int test_wolfSSL_CertManagerCheckOCSPResponse(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int test_wolfSSL_CheckOCSPResponse(void)
|
||||
{
|
||||
#if defined(HAVE_OCSP) && !defined(NO_RSA) && defined(OPENSSL_ALL)
|
||||
const char* responseFile = "./certs/ocsp/test-response.der";
|
||||
const char* responseNoInternFile = "./certs/ocsp/test-response-nointern.der";
|
||||
const char* caFile = "./certs/ocsp/root-ca-cert.pem";
|
||||
OcspResponse* res = NULL;
|
||||
byte data[4096];
|
||||
const unsigned char* pt;
|
||||
int dataSz;
|
||||
XFILE f;
|
||||
WOLFSSL_OCSP_BASICRESP* bs;
|
||||
WOLFSSL_X509_STORE* st;
|
||||
WOLFSSL_X509* issuer;
|
||||
|
||||
|
||||
printf(testingFmt, "wolfSSL_CheckOCSPResponse()");
|
||||
|
||||
f = XFOPEN(responseFile, "rb");
|
||||
AssertTrue(f != XBADFILE);
|
||||
dataSz = (word32)XFREAD(data, 1, sizeof(data), f);
|
||||
AssertIntGT(dataSz, 0);
|
||||
XFCLOSE(f);
|
||||
|
||||
pt = data;
|
||||
res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz);
|
||||
AssertNotNull(res);
|
||||
issuer = wolfSSL_X509_load_certificate_file(caFile, SSL_FILETYPE_PEM);
|
||||
AssertNotNull(issuer);
|
||||
st = wolfSSL_X509_STORE_new();
|
||||
AssertNotNull(st);
|
||||
AssertIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS);
|
||||
bs = wolfSSL_OCSP_response_get1_basic(res);
|
||||
AssertNotNull(bs);
|
||||
AssertIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), WOLFSSL_SUCCESS);
|
||||
wolfSSL_OCSP_BASICRESP_free(bs);
|
||||
wolfSSL_OCSP_RESPONSE_free(res);
|
||||
wolfSSL_X509_STORE_free(st);
|
||||
wolfSSL_X509_free(issuer);
|
||||
|
||||
/* check loading a response with optional certs */
|
||||
f = XFOPEN(responseNoInternFile, "rb");
|
||||
AssertTrue(f != XBADFILE);
|
||||
dataSz = (word32)XFREAD(data, 1, sizeof(data), f);
|
||||
AssertIntGT(dataSz, 0);
|
||||
XFCLOSE(f);
|
||||
|
||||
pt = data;
|
||||
res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz);
|
||||
AssertNotNull(res);
|
||||
wolfSSL_OCSP_RESPONSE_free(res);
|
||||
|
||||
#if defined(WC_RSA_PSS)
|
||||
{
|
||||
const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der";
|
||||
|
||||
/* check loading a response with RSA-PSS signature */
|
||||
f = XFOPEN(responsePssFile, "rb");
|
||||
AssertTrue(f != XBADFILE);
|
||||
dataSz = (word32)XFREAD(data, 1, sizeof(data), f);
|
||||
AssertIntGT(dataSz, 0);
|
||||
XFCLOSE(f);
|
||||
|
||||
pt = data;
|
||||
res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz);
|
||||
AssertNotNull(res);
|
||||
|
||||
/* try to verify the response */
|
||||
issuer = wolfSSL_X509_load_certificate_file(caFile, SSL_FILETYPE_PEM);
|
||||
AssertNotNull(issuer);
|
||||
st = wolfSSL_X509_STORE_new();
|
||||
AssertNotNull(st);
|
||||
AssertIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS);
|
||||
bs = wolfSSL_OCSP_response_get1_basic(res);
|
||||
AssertNotNull(bs);
|
||||
AssertIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), WOLFSSL_SUCCESS);
|
||||
wolfSSL_OCSP_BASICRESP_free(bs);
|
||||
wolfSSL_OCSP_RESPONSE_free(res);
|
||||
wolfSSL_X509_STORE_free(st);
|
||||
wolfSSL_X509_free(issuer);
|
||||
}
|
||||
#endif
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif /* HAVE_OCSP */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_wolfSSL_CertManagerLoadCABuffer(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -58080,6 +58168,7 @@ TEST_CASE testCases[] = {
|
|||
TEST_DECL(test_wolfSSL_CTX_use_PrivateKey_file),
|
||||
TEST_DECL(test_wolfSSL_CTX_load_verify_locations),
|
||||
TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse),
|
||||
TEST_DECL(test_wolfSSL_CheckOCSPResponse),
|
||||
TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer),
|
||||
TEST_DECL(test_wolfSSL_CertManagerGetCerts),
|
||||
TEST_DECL(test_wolfSSL_CertManagerSetVerify),
|
||||
|
|
|
@ -34264,6 +34264,10 @@ static const ASNItem ocspBasicRespASN[] = {
|
|||
/* SIGALGO */ { 1, ASN_SEQUENCE, 1, 1, 0, },
|
||||
/* SIGALGO_OID */ { 2, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
/* SIGALGO_NULL */ { 2, ASN_TAG_NULL, 0, 0, 1 },
|
||||
/* parameters */
|
||||
#ifdef WC_RSA_PSS
|
||||
/* SIGALGO_PARAMS */ { 2, ASN_SEQUENCE, 1, 0, 1 },
|
||||
#endif
|
||||
/* signature */
|
||||
/* SIGNATURE */ { 1, ASN_BIT_STRING, 0, 0, 0 },
|
||||
/* certs */
|
||||
|
@ -34276,6 +34280,9 @@ enum {
|
|||
OCSPBASICRESPASN_IDX_SIGALGO,
|
||||
OCSPBASICRESPASN_IDX_SIGALGO_OID,
|
||||
OCSPBASICRESPASN_IDX_SIGALGO_NULL,
|
||||
#ifdef WC_RSA_PSS
|
||||
OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS,
|
||||
#endif
|
||||
OCSPBASICRESPASN_IDX_SIGNATURE,
|
||||
OCSPBASICRESPASN_IDX_CERTS,
|
||||
OCSPBASICRESPASN_IDX_CERTS_SEQ,
|
||||
|
@ -34291,9 +34298,13 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||
int length;
|
||||
word32 idx = *ioIndex;
|
||||
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
||||
word32 end_index;
|
||||
#endif
|
||||
int ret;
|
||||
int sigLength;
|
||||
const byte* sigParams = NULL;
|
||||
word32 sigParamsSz = 0;
|
||||
|
||||
WOLFSSL_ENTER("DecodeBasicOcspResponse");
|
||||
(void)heap;
|
||||
|
@ -34303,14 +34314,34 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
|
||||
if (idx + length > size)
|
||||
return ASN_INPUT_E;
|
||||
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
||||
end_index = idx + length;
|
||||
#endif
|
||||
|
||||
if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
|
||||
return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
|
||||
|
||||
/* Get the signature algorithm */
|
||||
if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
|
||||
if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
#ifdef WC_RSA_PSS
|
||||
else if (resp->sigOID == CTC_RSASSAPSS) {
|
||||
word32 sz;
|
||||
int len;
|
||||
const byte* params;
|
||||
|
||||
sz = idx;
|
||||
params = source + idx;
|
||||
if (GetSequence(source, &idx, &len, size) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0) {
|
||||
idx += len;
|
||||
sigParams = params;
|
||||
sigParamsSz = idx - sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
|
||||
if (ret != 0)
|
||||
|
@ -34378,7 +34409,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
&cert->sigCtx,
|
||||
resp->response, resp->responseSz,
|
||||
cert->publicKey, cert->pubKeySize, cert->keyOID,
|
||||
resp->sig, resp->sigSz, resp->sigOID, NULL, 0, NULL);
|
||||
resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
|
||||
NULL);
|
||||
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("\tOCSP Confirm signature failed");
|
||||
|
@ -34415,7 +34447,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
/* ConfirmSignature is blocking here */
|
||||
sigValid = ConfirmSignature(&sigCtx, resp->response,
|
||||
resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
|
||||
resp->sig, resp->sigSz, resp->sigOID, NULL, 0, NULL);
|
||||
resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
|
||||
NULL);
|
||||
}
|
||||
if (ca == NULL || sigValid != 0) {
|
||||
WOLFSSL_MSG("\tOCSP Confirm signature failed");
|
||||
|
@ -34431,6 +34464,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
|
||||
int ret = 0;
|
||||
word32 idx = *ioIndex;
|
||||
const byte* sigParams = NULL;
|
||||
word32 sigParamsSz = 0;
|
||||
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
DecodedCert* cert = NULL;
|
||||
|
@ -34463,6 +34498,16 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
#ifdef WC_RSA_PSS
|
||||
if (ret == 0 && (dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS].tag != 0)) {
|
||||
sigParams = GetASNItem_Addr(
|
||||
dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
|
||||
source);
|
||||
sigParamsSz =
|
||||
GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
|
||||
source);
|
||||
}
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
/* Get the signature OID and signature. */
|
||||
resp->sigOID = dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID].data.oid.sum;
|
||||
|
@ -34535,7 +34580,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||
/* Check the signature of the response CA public key. */
|
||||
sigValid = ConfirmSignature(&sigCtx, resp->response,
|
||||
resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
|
||||
resp->sig, resp->sigSz, resp->sigOID, NULL, 0, NULL);
|
||||
resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
|
||||
NULL);
|
||||
}
|
||||
if ((ca == NULL) || (sigValid != 0)) {
|
||||
/* Didn't find certificate or signature verificate failed. */
|
||||
|
|
Loading…
Reference in New Issue