forked from wolfSSL/wolfssl
Merge pull request #1799 from SparkiDev/cert_vfy_small
Smaller dynamic memory usage in TLS
This commit is contained in:
@@ -669,7 +669,7 @@ AC_ARG_ENABLE([lowresource],
|
||||
if test "$ENABLED_LOWRESOURCE" = "yes"
|
||||
then
|
||||
# low memory / flash flags
|
||||
AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE -DRSA_LOW_MEM -DALT_ECC_SIZE -DGCM_SMALL -DCURVE25519_SMALL -DED25519_SMALL"
|
||||
AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE -DRSA_LOW_MEM -DALT_ECC_SIZE -DGCM_SMALL -DCURVE25519_SMALL -DED25519_SMALL -DWOLFSSL_SMALL_CERT_VERIFY"
|
||||
|
||||
# low flash flags
|
||||
AM_CFLAGS="$AM_CFLAGS -DUSE_SLOW_SHA -DUSE_SLOW_SHA256 -DUSE_SLOW_SHA512"
|
||||
|
@@ -27,6 +27,12 @@
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
/*
|
||||
* WOLFSSL_SMALL_CERT_VERIFY:
|
||||
* Verify the certificate signature without using DecodedCert. Doubles up
|
||||
* on some code but allows smaller dynamic memory usage.
|
||||
*/
|
||||
|
||||
#ifndef WOLFCRYPT_ONLY
|
||||
|
||||
#include <wolfssl/internal.h>
|
||||
@@ -8905,11 +8911,13 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
args->certIdx = 0;
|
||||
|
||||
args->dCertInit = 0;
|
||||
#ifndef WOLFSSL_SMALL_CERT_VERIFY
|
||||
args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
|
||||
DYNAMIC_TYPE_DCERT);
|
||||
if (args->dCert == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_ppc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_BUILD;
|
||||
@@ -8928,6 +8936,17 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
cert = &args->certs[args->certIdx];
|
||||
|
||||
if (!args->dCertInit) {
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
if (args->dCert == NULL) {
|
||||
args->dCert = (DecodedCert*)XMALLOC(
|
||||
sizeof(DecodedCert), ssl->heap,
|
||||
DYNAMIC_TYPE_DCERT);
|
||||
if (args->dCert == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_ppc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InitDecodedCert(args->dCert,
|
||||
cert->buffer, cert->length, ssl->heap);
|
||||
args->dCert->sigCtx.devId = ssl->devId; /* setup async dev */
|
||||
@@ -9000,6 +9019,17 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
cert = &args->certs[args->certIdx];
|
||||
|
||||
if (!args->dCertInit) {
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
if (args->dCert == NULL) {
|
||||
args->dCert = (DecodedCert*)XMALLOC(
|
||||
sizeof(DecodedCert), ssl->heap,
|
||||
DYNAMIC_TYPE_DCERT);
|
||||
if (args->dCert == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_ppc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InitDecodedCert(args->dCert,
|
||||
cert->buffer, cert->length, ssl->heap);
|
||||
args->dCert->sigCtx.devId = ssl->devId;
|
||||
@@ -9052,7 +9082,34 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
args->certIdx = args->count - 1;
|
||||
cert = &args->certs[args->certIdx];
|
||||
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
if (!ssl->options.verifyNone) {
|
||||
if (args->dCert != NULL) {
|
||||
if (args->dCertInit) {
|
||||
FreeDecodedCert(args->dCert);
|
||||
args->dCertInit = 0;
|
||||
}
|
||||
XFREE(args->dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
|
||||
args->dCert = NULL;
|
||||
}
|
||||
ret = CheckCertSignature(cert->buffer, cert->length,
|
||||
ssl->heap, ssl->ctx->cm);
|
||||
if (ret != 0)
|
||||
goto exit_ppc;
|
||||
}
|
||||
#endif
|
||||
if (!args->dCertInit) {
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
if (args->dCert == NULL) {
|
||||
args->dCert = (DecodedCert*)XMALLOC(
|
||||
sizeof(DecodedCert), ssl->heap,
|
||||
DYNAMIC_TYPE_DCERT);
|
||||
if (args->dCert == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_ppc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InitDecodedCert(args->dCert,
|
||||
cert->buffer, cert->length, ssl->heap);
|
||||
args->dCert->sigCtx.devId = ssl->devId; /* setup async dev */
|
||||
@@ -9073,8 +9130,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_SMALL_CERT_VERIFY
|
||||
ret = ParseCertRelative(args->dCert, CERT_TYPE,
|
||||
!ssl->options.verifyNone, ssl->ctx->cm);
|
||||
#else
|
||||
ret = ParseCertRelative(args->dCert, CERT_TYPE,
|
||||
!ssl->options.verifyNone ? VERIFY_NAME : NO_VERIFY,
|
||||
ssl->ctx->cm);
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
@@ -9289,7 +9352,31 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
args->certIdx = 0;
|
||||
cert = &args->certs[args->certIdx];
|
||||
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
if (!ssl->options.verifyNone) {
|
||||
if (args->dCert != NULL) {
|
||||
if (args->dCertInit) {
|
||||
FreeDecodedCert(args->dCert);
|
||||
args->dCertInit = 0;
|
||||
}
|
||||
XFREE(args->dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
|
||||
args->dCert = NULL;
|
||||
}
|
||||
ret = CheckCertSignature(cert->buffer, cert->length,
|
||||
ssl->heap, ssl->ctx->cm);
|
||||
if (ret != 0)
|
||||
goto exit_ppc;
|
||||
}
|
||||
#endif
|
||||
if (!args->dCertInit) {
|
||||
if (args->dCert == NULL) {
|
||||
args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
|
||||
ssl->heap, DYNAMIC_TYPE_DCERT);
|
||||
if (args->dCert == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_ppc);
|
||||
}
|
||||
}
|
||||
|
||||
InitDecodedCert(args->dCert,
|
||||
cert->buffer, cert->length, ssl->heap);
|
||||
args->dCert->sigCtx.devId = ssl->devId; /* setup async dev */
|
||||
@@ -9309,8 +9396,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
#endif
|
||||
{
|
||||
/* only parse if not already present in dCert from above */
|
||||
#ifndef WOLFSSL_SMALL_CERT_VERIFY
|
||||
ret = ParseCertRelative(args->dCert, CERT_TYPE,
|
||||
!ssl->options.verifyNone, ssl->ctx->cm);
|
||||
#else
|
||||
ret = ParseCertRelative(args->dCert, CERT_TYPE,
|
||||
!ssl->options.verifyNone ? VERIFY_NAME : NO_VERIFY,
|
||||
ssl->ctx->cm);
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E) {
|
||||
ret = wolfSSL_AsyncPush(ssl,
|
||||
@@ -20167,7 +20260,7 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
return 0; /* sent blank cert, can't verify */
|
||||
}
|
||||
|
||||
args->sendSz = MAX_CERT_VERIFY_SZ;
|
||||
args->sendSz = MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA;
|
||||
if (IsEncryptionOn(ssl, 1)) {
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
}
|
||||
|
@@ -5201,7 +5201,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
|
||||
return 0; /* sent blank cert, can't verify */
|
||||
}
|
||||
|
||||
args->sendSz = MAX_CERT_VERIFY_SZ;
|
||||
args->sendSz = MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA;
|
||||
/* Always encrypted. */
|
||||
args->sendSz += MAX_MSG_EXTRA;
|
||||
|
||||
|
76
tests/api.c
76
tests/api.c
@@ -248,6 +248,10 @@
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SHA3) || defined(HAVE_PKCS7) || !defined(NO_RSA)
|
||||
static int devId = INVALID_DEVID;
|
||||
#endif
|
||||
@@ -19454,6 +19458,77 @@ static void test_wc_GetSubjectRaw(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_CheckCertSignature(void)
|
||||
{
|
||||
#if !defined(NO_CERTS) && defined(WOLFSSL_SMALL_CERT_VERIFY)
|
||||
WOLFSSL_CERT_MANAGER* cm = NULL;
|
||||
#if !defined(NO_FILESYSTEM)
|
||||
FILE* fp;
|
||||
byte cert[4096];
|
||||
int certSz;
|
||||
#endif
|
||||
|
||||
AssertIntEQ(BAD_FUNC_ARG, CheckCertSignature(NULL, 0, NULL, NULL));
|
||||
AssertNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
|
||||
AssertIntEQ(BAD_FUNC_ARG, CheckCertSignature(NULL, 0, NULL, cm));
|
||||
|
||||
#ifndef NO_RSA
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
AssertIntEQ(ASN_NO_SIGNER_E, CheckCertSignature(server_cert_der_1024,
|
||||
sizeof_server_cert_der_1024, NULL, cm));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
|
||||
ca_cert_der_1024, sizeof_ca_cert_der_1024,
|
||||
WOLFSSL_FILETYPE_ASN1));
|
||||
AssertIntEQ(0, CheckCertSignature(server_cert_der_1024,
|
||||
sizeof_server_cert_der_1024, NULL, cm));
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
AssertIntEQ(ASN_NO_SIGNER_E, CheckCertSignature(server_cert_der_2048,
|
||||
sizeof_server_cert_der_2048, NULL, cm));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
|
||||
ca_cert_der_2048, sizeof_ca_cert_der_2048,
|
||||
WOLFSSL_FILETYPE_ASN1));
|
||||
AssertIntEQ(0, CheckCertSignature(server_cert_der_2048,
|
||||
sizeof_server_cert_der_2048, NULL, cm));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
|
||||
AssertIntEQ(ASN_NO_SIGNER_E, CheckCertSignature(serv_ecc_der_256,
|
||||
sizeof_serv_ecc_der_256, NULL, cm));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
|
||||
ca_ecc_cert_der_256, sizeof_ca_ecc_cert_der_256,
|
||||
WOLFSSL_FILETYPE_ASN1));
|
||||
AssertIntEQ(0, CheckCertSignature(serv_ecc_der_256, sizeof_serv_ecc_der_256,
|
||||
NULL, cm));
|
||||
#endif
|
||||
|
||||
#if !defined(NO_FILESYSTEM)
|
||||
wolfSSL_CertManagerFree(cm);
|
||||
AssertNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
|
||||
#ifndef NO_RSA
|
||||
AssertNotNull(fp = XFOPEN("./certs/server-cert.der", "rb"));
|
||||
AssertIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), fp)), 0);
|
||||
XFCLOSE(fp);
|
||||
AssertIntEQ(ASN_NO_SIGNER_E, CheckCertSignature(cert, certSz, NULL, cm));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
|
||||
"./certs/ca-cert.pem", NULL));
|
||||
AssertIntEQ(0, CheckCertSignature(cert, certSz, NULL, cm));
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
AssertNotNull(fp = XFOPEN("./certs/server-ecc.der", "rb"));
|
||||
AssertIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), fp)), 0);
|
||||
XFCLOSE(fp);
|
||||
AssertIntEQ(ASN_NO_SIGNER_E, CheckCertSignature(cert, certSz, NULL, cm));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
|
||||
"./certs/ca-ecc-cert.pem", NULL));
|
||||
AssertIntEQ(0, CheckCertSignature(cert, certSz, NULL, cm));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
wolfSSL_CertManagerFree(cm);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| wolfCrypt ECC
|
||||
*----------------------------------------------------------------------------*/
|
||||
@@ -20696,6 +20771,7 @@ void ApiTest(void)
|
||||
test_wc_GetPkcs8TraditionalOffset();
|
||||
test_wc_SetSubjectRaw();
|
||||
test_wc_GetSubjectRaw();
|
||||
test_CheckCertSignature();
|
||||
|
||||
/* wolfCrypt ECC tests */
|
||||
test_wc_ecc_get_curve_size_from_name();
|
||||
|
@@ -46,6 +46,9 @@ ASN Options:
|
||||
disable checking of OCSP subject hash with issuer hash.
|
||||
* WOLFSSL_ALT_CERT_CHAINS: Allows matching multiple CA's to validate
|
||||
chain based on issuer and public key (includes signature confirmation)
|
||||
* WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
|
||||
DecodedCert. Doubles up on some code but allows smaller dynamic memory
|
||||
usage.
|
||||
*/
|
||||
|
||||
#ifndef NO_ASN
|
||||
@@ -4098,11 +4101,7 @@ static int GetName(DecodedCert* cert, int nameType)
|
||||
if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
#ifdef NO_SHA
|
||||
ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
|
||||
#else
|
||||
ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
|
||||
#endif
|
||||
ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -6369,13 +6368,8 @@ static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
|
||||
if (length == KEYID_SIZE) {
|
||||
XMEMCPY(cert->extAuthKeyId, input + idx, length);
|
||||
}
|
||||
else {
|
||||
#ifdef NO_SHA
|
||||
ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
|
||||
#else
|
||||
ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
ret = CalcHashId(input + idx, length, cert->extAuthKeyId);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -6400,16 +6394,11 @@ static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||
cert->extSubjKeyIdSz = length;
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
if (length == SIGNER_DIGEST_SIZE) {
|
||||
if (length == KEYID_SIZE) {
|
||||
XMEMCPY(cert->extSubjKeyId, input + idx, length);
|
||||
}
|
||||
else {
|
||||
#ifdef NO_SHA
|
||||
ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
|
||||
#else
|
||||
ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
ret = CalcHashId(input + idx, length, cert->extSubjKeyId);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -7107,6 +7096,272 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_CERT_VERIFY
|
||||
/* Only quick step through the certificate to find fields that are then used
|
||||
* in certificate signature verification.
|
||||
* Must use the signature OID from the signed part of the certificate.
|
||||
*
|
||||
* This is only for minimizing dynamic memory usage during TLS certificate
|
||||
* chain processing.
|
||||
* Doesn't support:
|
||||
* OCSP Only: alt lookup using subject and pub key w/o sig check
|
||||
*/
|
||||
int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
|
||||
{
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
SignatureCtx sigCtx[1];
|
||||
#else
|
||||
SignatureCtx* sigCtx;
|
||||
#endif
|
||||
byte hash[KEYID_SIZE];
|
||||
Signer* ca = NULL;
|
||||
word32 idx = 0;
|
||||
int len;
|
||||
word32 tbsCertIdx;
|
||||
word32 sigIndex;
|
||||
word32 signatureOID;
|
||||
word32 oid;
|
||||
word32 issuerIdx;
|
||||
word32 issuerSz;
|
||||
#ifndef NO_SKID
|
||||
int extLen;
|
||||
word32 extIdx;
|
||||
word32 extEndIdx;
|
||||
int extAuthKeyIdSet = 0;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
if (cert == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
sigCtx = XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
|
||||
if (sigCtx == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
|
||||
|
||||
/* Certificate SEQUENCE */
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0) {
|
||||
tbsCertIdx = idx;
|
||||
|
||||
/* TBSCertificate SEQUENCE */
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
sigIndex = len + idx;
|
||||
|
||||
if ((idx + 1) > certSz)
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* version - optional */
|
||||
if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
|
||||
idx++;
|
||||
if (GetLength(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
idx += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* serialNumber */
|
||||
if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
idx += len;
|
||||
|
||||
/* signature */
|
||||
if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
issuerIdx = idx;
|
||||
/* issuer */
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
issuerSz = len + idx - issuerIdx;
|
||||
}
|
||||
#ifndef NO_SKID
|
||||
if (ret == 0) {
|
||||
idx += len;
|
||||
|
||||
/* validity */
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
idx += len;
|
||||
|
||||
/* subject */
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
idx += len;
|
||||
|
||||
/* subjectPublicKeyInfo */
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
idx += len;
|
||||
|
||||
if ((idx + 1) > certSz)
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* issuerUniqueID - optional */
|
||||
if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
|
||||
idx++;
|
||||
if (GetLength(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
idx += len;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
if ((idx + 1) > certSz)
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* subjectUniqueID - optional */
|
||||
if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
|
||||
idx++;
|
||||
if (GetLength(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
idx += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if ((idx + 1) > certSz)
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
/* extensions - optional */
|
||||
if (ret == 0 && cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
|
||||
idx++;
|
||||
if (GetLength(cert, &idx, &extLen, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0) {
|
||||
if (GetSequence(cert, &idx, &extLen, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
extEndIdx = idx + extLen;
|
||||
|
||||
/* Check each extension for the ones we want. */
|
||||
while (ret == 0 && idx < extEndIdx) {
|
||||
if (GetSequence(cert, &idx, &len, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0) {
|
||||
extIdx = idx;
|
||||
if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
|
||||
certSz) < 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
if (cert[extIdx] == ASN_BOOLEAN) {
|
||||
if (GetBoolean(cert, &extIdx, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
switch (oid) {
|
||||
case AUTH_KEY_OID:
|
||||
extAuthKeyIdSet = 1;
|
||||
if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 &&
|
||||
cert[extIdx++] == (ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0) {
|
||||
if (extLen == KEYID_SIZE)
|
||||
XMEMCPY(hash, cert + extIdx, extLen);
|
||||
else {
|
||||
ret = CalcHashId(cert + extIdx, extLen,
|
||||
hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
idx += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (extAuthKeyIdSet)
|
||||
ca = GetCA(cm, hash);
|
||||
if (ca == NULL) {
|
||||
ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
|
||||
if (ret == 0)
|
||||
ca = GetCAByName(cm, hash);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ret == 0) {
|
||||
ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
|
||||
if (ret == 0)
|
||||
ca = GetCA(cm, hash);
|
||||
}
|
||||
#endif /* !NO_SKID */
|
||||
if (ca == NULL)
|
||||
ret = ASN_NO_SIGNER_E;
|
||||
|
||||
if (ret == 0) {
|
||||
idx = sigIndex;
|
||||
/* signatureAlgorithm */
|
||||
if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
if (oid != signatureOID)
|
||||
ret = ASN_SIG_OID_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* signatureValue */
|
||||
if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, sigIndex - tbsCertIdx,
|
||||
ca->publicKey, ca->pubKeySize, ca->keyOID,
|
||||
cert + idx, len, signatureOID);
|
||||
if (ret != WC_PENDING_E) {
|
||||
WOLFSSL_MSG("Confirm signature failed");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
if (sigCtx != NULL)
|
||||
XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -7166,13 +7421,8 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||
#ifndef NO_SKID
|
||||
if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
|
||||
cert->pubKeySize > 0) {
|
||||
#ifdef NO_SHA
|
||||
ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
|
||||
ret = CalcHashId(cert->publicKey, cert->pubKeySize,
|
||||
cert->extSubjKeyId);
|
||||
#else
|
||||
ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
|
||||
cert->extSubjKeyId);
|
||||
#endif /* NO_SHA */
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -7231,16 +7481,11 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||
}
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
/* Need the CA's public key hash for OCSP */
|
||||
#ifdef NO_SHA
|
||||
ret = wc_Sha256Hash(cert->ca->publicKey, cert->ca->pubKeySize,
|
||||
/* Need the CA's public key hash for OCSP */
|
||||
ret = CalcHashId(cert->ca->publicKey, cert->ca->pubKeySize,
|
||||
cert->issuerKeyHash);
|
||||
#else
|
||||
ret = wc_ShaHash(cert->ca->publicKey, cert->ca->pubKeySize,
|
||||
cert->issuerKeyHash);
|
||||
#endif /* NO_SHA */
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif /* HAVE_OCSP */
|
||||
}
|
||||
}
|
||||
@@ -7261,15 +7506,18 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||
}
|
||||
#ifndef IGNORE_NAME_CONSTRAINTS
|
||||
if (verify == VERIFY || verify == VERIFY_OCSP ||
|
||||
verify == VERIFY_NAME) {
|
||||
/* check that this cert's name is permitted by the signer's
|
||||
* name constraints */
|
||||
if (!ConfirmNameConstraints(cert->ca, cert)) {
|
||||
WOLFSSL_MSG("Confirm name constraint failed");
|
||||
return ASN_NAME_INVALID_E;
|
||||
}
|
||||
#endif /* IGNORE_NAME_CONSTRAINTS */
|
||||
}
|
||||
#endif /* IGNORE_NAME_CONSTRAINTS */
|
||||
}
|
||||
else {
|
||||
/* no signer */
|
||||
@@ -11289,29 +11537,16 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
|
||||
}
|
||||
|
||||
/* Compute SKID by hashing public key */
|
||||
#ifdef NO_SHA
|
||||
if (kid_type == SKID_TYPE) {
|
||||
ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
|
||||
cert->skidSz = WC_SHA256_DIGEST_SIZE;
|
||||
ret = CalcHashId(buffer, bufferSz, cert->skid);
|
||||
cert->skidSz = KEYID_SIZE;
|
||||
}
|
||||
else if (kid_type == AKID_TYPE) {
|
||||
ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
|
||||
cert->akidSz = WC_SHA256_DIGEST_SIZE;
|
||||
ret = CalcHashId(buffer, bufferSz, cert->akid);
|
||||
cert->akidSz = KEYID_SIZE;
|
||||
}
|
||||
else
|
||||
ret = BAD_FUNC_ARG;
|
||||
#else /* NO_SHA */
|
||||
if (kid_type == SKID_TYPE) {
|
||||
ret = wc_ShaHash(buffer, bufferSz, cert->skid);
|
||||
cert->skidSz = WC_SHA_DIGEST_SIZE;
|
||||
}
|
||||
else if (kid_type == AKID_TYPE) {
|
||||
ret = wc_ShaHash(buffer, bufferSz, cert->akid);
|
||||
cert->akidSz = WC_SHA_DIGEST_SIZE;
|
||||
}
|
||||
else
|
||||
ret = BAD_FUNC_ARG;
|
||||
#endif /* NO_SHA */
|
||||
|
||||
XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
@@ -13737,11 +13972,7 @@ WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
|
||||
if (GetSequence(source, idx, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
#ifdef NO_SHA
|
||||
ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
|
||||
#else
|
||||
ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
|
||||
#endif
|
||||
ret = CalcHashId(source + dummy, length + *idx - dummy, hash);
|
||||
|
||||
*idx += length;
|
||||
|
||||
|
@@ -99,11 +99,13 @@ int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, sp_int* e,
|
||||
*/
|
||||
void sp_clear(sp_int* a)
|
||||
{
|
||||
int i;
|
||||
if (a != NULL) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<a->used; i++)
|
||||
a->dp[i] = 0;
|
||||
a->used = 0;
|
||||
for (i=0; i<a->used; i++)
|
||||
a->dp[i] = 0;
|
||||
a->used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the number of 8-bit values required to represent the big number.
|
||||
|
@@ -1336,7 +1336,15 @@ enum Misc {
|
||||
MIN_RSA_SHA512_PSS_BITS = 512 * 2 + 8 * 8, /* Min key size */
|
||||
MIN_RSA_SHA384_PSS_BITS = 384 * 2 + 8 * 8, /* Min key size */
|
||||
|
||||
MAX_CERT_VERIFY_SZ = 1024, /* max */
|
||||
#ifndef NO_RSA
|
||||
MAX_CERT_VERIFY_SZ = 4096 / 8, /* max RSA - default 4096-bits */
|
||||
#elif defined(HAVE_ECC)
|
||||
MAX_CERT_VERIFY_SZ = ECC_MAX_SIG_SIZE, /* max ECC */
|
||||
#elif defined(HAVE_ED25519)
|
||||
MAX_CERT_VERIFY_SZ = ED25519_SIG_SIZE, /* max Ed25519 */
|
||||
#else
|
||||
MAX_CERT_VERIFY_SZ = 1024, /* max default */
|
||||
#endif
|
||||
CLIENT_HELLO_FIRST = 35, /* Protocol + RAN_LEN + sizeof(id_len) */
|
||||
MAX_SUITE_NAME = 48, /* maximum length of cipher suite string */
|
||||
|
||||
|
@@ -420,7 +420,8 @@ enum VerifyType {
|
||||
NO_VERIFY = 0,
|
||||
VERIFY = 1,
|
||||
VERIFY_CRL = 2,
|
||||
VERIFY_OCSP = 3
|
||||
VERIFY_OCSP = 3,
|
||||
VERIFY_NAME = 4
|
||||
};
|
||||
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
@@ -838,6 +839,14 @@ struct TrustedPeerCert {
|
||||
#define WOLFSSL_ASN_API WOLFSSL_LOCAL
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NO_SHA
|
||||
#define CalcHashId(data, len, hash) wc_Sha256Hash(data, len, hash)
|
||||
#else
|
||||
#define CalcHashId(data, len, hash) wc_ShaHash(data, len, hash)
|
||||
#endif
|
||||
|
||||
|
||||
WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der,
|
||||
word32* derSz);
|
||||
|
||||
@@ -850,6 +859,7 @@ WOLFSSL_ASN_API void FreeDecodedCert(DecodedCert*);
|
||||
WOLFSSL_ASN_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
|
||||
|
||||
WOLFSSL_LOCAL int DecodePolicyOID(char *o, word32 oSz, byte *in, word32 inSz);
|
||||
WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm);
|
||||
WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm);
|
||||
WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
|
||||
|
||||
|
Reference in New Issue
Block a user