Merge pull request #6325 from SparkiDev/memusage_fix_4

Memory Usage fixes
This commit is contained in:
JacobBarthelmeh
2023-04-21 09:37:11 -06:00
committed by GitHub
4 changed files with 122 additions and 30 deletions

View File

@ -5221,23 +5221,13 @@ int Ed25519CheckPubKey(WOLFSSL* ssl)
/* Public key required for signing. */
if (key != NULL && !key->pubKeySet) {
DerBuffer* leaf = ssl->buffers.certificate;
DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert),
ssl->heap, DYNAMIC_TYPE_DCERT);
if (cert == NULL)
ret = MEMORY_E;
const unsigned char* pubKey;
word32 pubKeySz;
ret = wc_CertGetPubKey(ssl->buffers.certificate->buffer,
ssl->buffers.certificate->length, &pubKey, &pubKeySz);
if (ret == 0) {
InitDecodedCert(cert, leaf->buffer, leaf->length, ssl->heap);
ret = DecodeToKey(cert, 0);
}
if (ret == 0) {
ret = wc_ed25519_import_public(cert->publicKey, cert->pubKeySize,
key);
}
if (cert != NULL) {
FreeDecodedCert(cert);
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
ret = wc_ed25519_import_public(pubKey, pubKeySz, key);
}
}
@ -5555,23 +5545,13 @@ int Ed448CheckPubKey(WOLFSSL* ssl)
/* Public key required for signing. */
if (key != NULL && !key->pubKeySet) {
DerBuffer* leaf = ssl->buffers.certificate;
DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert), ssl->heap,
DYNAMIC_TYPE_DCERT);
if (cert == NULL)
ret = MEMORY_E;
const unsigned char* pubKey;
word32 pubKeySz;
ret = wc_CertGetPubKey(ssl->buffers.certificate->buffer,
ssl->buffers.certificate->length, &pubKey, &pubKeySz);
if (ret == 0) {
InitDecodedCert(cert, leaf->buffer, leaf->length, ssl->heap);
ret = DecodeToKey(cert, 0);
}
if (ret == 0) {
ret = wc_ed448_import_public(cert->publicKey, cert->pubKeySize,
key);
}
if (cert != NULL) {
FreeDecodedCert(cert);
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
ret = wc_ed448_import_public(pubKey, pubKeySz, key);
}
}

View File

@ -21473,6 +21473,109 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
#endif /* WOLFSSL_SMALL_CERT_VERIFY */
#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
#if (defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) || \
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)))
/* ASN.1 DER decode instruction. */
typedef struct DecodeInstr {
/* Tag expected. */
byte tag;
/* Operation to perform: step in or go over */
byte op:1;
/* ASN.1 item is optional. */
byte optional:1;
} DecodeInstr;
/* Step into ASN.1 item. */
#define DECODE_INSTR_IN 0
/* Step over ASN.1 item. */
#define DECODE_INSTR_OVER 1
/* Get the public key data from the DER encoded X.509 certificate.
*
* Assumes data has previously been parsed for complete validity.
*
* @param [in] cert DER encoded X.509 certificate data.
* @param [in] certSz Length of DER encoding.
* @param [out] pubKey Public key data. (From the BIT_STRING.)
* @param [out] pubKeySz Length of public key data in bytes.
* @return 0 on success.
* @return BAD_FUNC_ARG when cert, pubKey or pubKeySz is NULL.
* @return ASN_PARSE_E when certificate encoding is invalid.
*/
int wc_CertGetPubKey(const byte* cert, word32 certSz,
const unsigned char** pubKey, word32* pubKeySz)
{
int ret = 0;
int l;
word32 o = 0;
int i;
static DecodeInstr ops[] = {
/* Outer SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN , 0 },
/* TBSCertificate: SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN , 0 },
/* Version: [0] */
{ ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_X509_CERT_VERSION,
DECODE_INSTR_OVER, 1 },
/* CertificateSerialNumber: INT */
{ ASN_INTEGER, DECODE_INSTR_OVER, 0 },
/* AlgorithmIdentifier: SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
/* issuer: SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
/* Validity: SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
/* subject: SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
/* subjectPublicKeyInfo SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN , 0 },
/* AlgorithmIdentifier: SEQ */
{ ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
/* PublicKey: BIT_STRING */
{ ASN_BIT_STRING, DECODE_INSTR_IN , 0 },
};
/* Validate parameters. */
if ((cert == NULL) || (pubKey == NULL) || (pubKeySz == NULL)) {
ret = BAD_FUNC_ARG;
}
/* Process each instruction to take us to public key data. */
for (i = 0; (ret == 0) && (i < (int)(sizeof(ops) / sizeof(*ops))); i++) {
DecodeInstr op = ops[i];
/* Check the current ASN.1 item has the expected tag. */
if (cert[o] != op.tag) {
/* If not optional then error, otherwise skip op. */
if (!op.optional) {
ret = ASN_PARSE_E;
}
}
else {
/* Move past tag. */
o++;
/* Get the length of ASN.1 item and move past length encoding. */
if (GetLength(cert, &o, &l, certSz) < 0) {
ret = ASN_PARSE_E;
}
/* Skip data if required. */
else if (op.op == DECODE_INSTR_OVER) {
o += l;
}
}
}
if (ret == 0) {
/* Return the public key data and length.
* Skip first byte of BIT_STRING data: unused bits. */
*pubKey = cert + o + 1;
*pubKeySz = l - 1;
}
return ret;
}
#endif
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
{
int ret = 0;

View File

@ -1337,6 +1337,10 @@ enum {
/* Integer/heap maths - support 4096-bit. */
#define ENCRYPT_BASE_BITS 4096
#endif
#elif defined(HAVE_CURVE448)
#define ENCRYPT_BASE_BITS (456 * 2)
#elif defined(HAVE_CURVE25519)
#define ENCRYPT_BASE_BITS (256 * 2)
#else
/* No secret from public key operation but PSK key plus length used. */
#define ENCRYPT_BASE_BITS ((MAX_PSK_ID_LEN + 2) * 8)

View File

@ -2045,6 +2045,11 @@ WOLFSSL_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz,
void* heap, const byte* pubKey,
word32 pubKeySz, int pubKeyOID);
#endif
#if (defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) || \
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)))
WOLFSSL_LOCAL int wc_CertGetPubKey(const byte* cert, word32 certSz,
const unsigned char** pubKey, word32* pubKeySz);
#endif
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz,