From d86fc2dbbe032cd8df07d2262fee24795b6499f2 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 30 Aug 2018 14:46:43 +1000 Subject: [PATCH] Smaller dynamic memory usage in TLS Code doesn't require a DecodedCert which saves on dynamic memory usage. WOLFSSL_SMALL_CERT_VERIFY: Don't have a DecodedCert allocated and verify certificate signature in ProcessPeerCerts as this is maximum dynamic memory usage. WOLFSSL_SMALL_CERT_VERIFY is enabled with 'lowresource' configuration option. Fix sp_clear to work with NULL parameter. Define a new function HashId that maps to the hashing function available. Set MAX_CERT_VERIFY_SZ to be the maximum based on what algorithms are compiled in. Fix usage of MAX_CERT_VERIFY_SZ in functions sending certificate verify messages. --- configure.ac | 2 +- src/internal.c | 95 ++++++++++- src/tls13.c | 2 +- wolfcrypt/src/asn.c | 345 +++++++++++++++++++++++++++++++++------- wolfcrypt/src/sp_int.c | 10 +- wolfssl/internal.h | 10 +- wolfssl/wolfcrypt/asn.h | 12 +- 7 files changed, 408 insertions(+), 68 deletions(-) diff --git a/configure.ac b/configure.ac index c2da7e6d6..0adc93b86 100644 --- a/configure.ac +++ b/configure.ac @@ -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" diff --git a/src/internal.c b/src/internal.c index ee24ce84f..122ccadd9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -27,6 +27,12 @@ #include +/* + * 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 @@ -8896,11 +8902,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; @@ -8919,6 +8927,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 */ @@ -8991,6 +9010,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; @@ -9043,7 +9073,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 */ @@ -9064,8 +9121,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, @@ -9280,7 +9343,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 */ @@ -9300,8 +9387,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, @@ -20149,7 +20242,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; } diff --git a/src/tls13.c b/src/tls13.c index 37963a453..52522de36 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5195,7 +5195,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; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 84121040e..2ab357dd3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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,268 @@ 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(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; + +#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 +7417,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 +7477,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 +7502,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 +11533,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 +13968,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; diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 5f2ee122d..d8b9ddb46 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -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; iused; i++) - a->dp[i] = 0; - a->used = 0; + for (i=0; iused; i++) + a->dp[i] = 0; + a->used = 0; + } } /* Calculate the number of 8-bit values required to represent the big number. diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4bb3319a5..73cc2d964 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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 */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index c8add0227..5badf16aa 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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_LOCAL int CheckCertSignature(byte*,word32,void*,void* cm); WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm); WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);