mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 04:04:39 +02:00
pkcs7: refactoring CreateRecipientInfo to reduce stack usage: ~ 8 * sizeof(mp_int) bytes + ~935 bytes moved to the heap.
--- variable pubKey moved to the heap (more than 8 * sizeof(mp_int) bytes saved) --- variable decoded moved to the heap (sizeof(DecodedCert) ~= 880 bytes saved) --- variable serial moved to the heap (35 bytes saved) --- variable keyAlgArray moved to the heap (20 bytes saved)
This commit is contained in:
@@ -948,20 +948,49 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
int encKeyOctetStrSz;
|
int encKeyOctetStrSz;
|
||||||
|
|
||||||
byte ver[MAX_VERSION_SZ];
|
byte ver[MAX_VERSION_SZ];
|
||||||
byte serial[MAX_SN_SZ];
|
|
||||||
byte issuerSerialSeq[MAX_SEQ_SZ];
|
byte issuerSerialSeq[MAX_SEQ_SZ];
|
||||||
byte recipSeq[MAX_SEQ_SZ];
|
byte recipSeq[MAX_SEQ_SZ];
|
||||||
byte issuerSeq[MAX_SEQ_SZ];
|
byte issuerSeq[MAX_SEQ_SZ];
|
||||||
byte keyAlgArray[MAX_ALGO_SZ];
|
|
||||||
byte encKeyOctetStr[MAX_OCTET_STR_SZ];
|
byte encKeyOctetStr[MAX_OCTET_STR_SZ];
|
||||||
|
|
||||||
RsaKey pubKey;
|
#ifdef CYASSL_SMALL_STACK
|
||||||
DecodedCert decoded;
|
byte *serial;
|
||||||
|
byte *keyAlgArray;
|
||||||
|
|
||||||
InitDecodedCert(&decoded, (byte*)cert, certSz, 0);
|
RsaKey* pubKey;
|
||||||
ret = ParseCert(&decoded, CA_TYPE, NO_VERIFY, 0);
|
DecodedCert* decoded;
|
||||||
|
|
||||||
|
serial = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
if (decoded == NULL || serial == NULL || keyAlgArray == NULL) {
|
||||||
|
if (serial) XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (keyAlgArray) XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (decoded) XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
byte serial[MAX_SN_SZ];
|
||||||
|
byte keyAlgArray[MAX_ALGO_SZ];
|
||||||
|
|
||||||
|
RsaKey stack_pubKey;
|
||||||
|
RsaKey* pubKey = &stack_pubKey;
|
||||||
|
DecodedCert stack_decoded;
|
||||||
|
DecodedCert* decoded = &stack_decoded;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InitDecodedCert(decoded, (byte*)cert, certSz, 0);
|
||||||
|
ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,52 +998,109 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
verSz = SetMyVersion(0, ver, 0);
|
verSz = SetMyVersion(0, ver, 0);
|
||||||
|
|
||||||
/* IssuerAndSerialNumber */
|
/* IssuerAndSerialNumber */
|
||||||
if (decoded.issuerRaw == NULL || decoded.issuerRawLen == 0) {
|
if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
|
||||||
CYASSL_MSG("DecodedCert lacks raw issuer pointer and length");
|
CYASSL_MSG("DecodedCert lacks raw issuer pointer and length");
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
issuerSz = decoded.issuerRawLen;
|
issuerSz = decoded->issuerRawLen;
|
||||||
issuerSeqSz = SetSequence(issuerSz, issuerSeq);
|
issuerSeqSz = SetSequence(issuerSz, issuerSeq);
|
||||||
|
|
||||||
if (decoded.serial == NULL || decoded.serialSz == 0) {
|
if (decoded->serial == NULL || decoded->serialSz == 0) {
|
||||||
CYASSL_MSG("DecodedCert missing serial number");
|
CYASSL_MSG("DecodedCert missing serial number");
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
snSz = SetSerialNumber(decoded.serial, decoded.serialSz, serial);
|
snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial);
|
||||||
|
|
||||||
issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
|
issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
|
||||||
issuerSerialSeq);
|
issuerSerialSeq);
|
||||||
|
|
||||||
/* KeyEncryptionAlgorithmIdentifier, only support RSA now */
|
/* KeyEncryptionAlgorithmIdentifier, only support RSA now */
|
||||||
if (keyEncAlgo != RSAk) {
|
if (keyEncAlgo != RSAk) {
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ALGO_ID_E;
|
return ALGO_ID_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
|
keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
|
||||||
if (keyEncAlgSz == 0) {
|
if (keyEncAlgSz == 0) {
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (pubKey == NULL) {
|
||||||
|
FreeDecodedCert(decoded);
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* EncryptedKey */
|
/* EncryptedKey */
|
||||||
ret = InitRsaKey(&pubKey, 0);
|
ret = InitRsaKey(pubKey, 0);
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) {
|
||||||
if (RsaPublicKeyDecode(decoded.publicKey, &idx, &pubKey,
|
FreeDecodedCert(decoded);
|
||||||
decoded.pubKeySize) < 0) {
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
|
||||||
|
decoded->pubKeySize) < 0) {
|
||||||
CYASSL_MSG("ASN RSA key decode error");
|
CYASSL_MSG("ASN RSA key decode error");
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return PUBLIC_KEY_E;
|
return PUBLIC_KEY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
*keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
|
*keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
|
||||||
MAX_ENCRYPTED_KEY_SZ, &pubKey, rng);
|
MAX_ENCRYPTED_KEY_SZ, pubKey, rng);
|
||||||
FreeRsaKey(&pubKey);
|
FreeRsaKey(pubKey);
|
||||||
|
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (*keyEncSz < 0) {
|
if (*keyEncSz < 0) {
|
||||||
CYASSL_MSG("RSA Public Encrypt failed");
|
CYASSL_MSG("RSA Public Encrypt failed");
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return *keyEncSz;
|
return *keyEncSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,7 +1114,12 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
|
if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
|
||||||
keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
|
keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
|
||||||
CYASSL_MSG("RecipientInfo output buffer too small");
|
CYASSL_MSG("RecipientInfo output buffer too small");
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,7 +1131,7 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
totalSz += issuerSerialSeqSz;
|
totalSz += issuerSerialSeqSz;
|
||||||
XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
|
XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
|
||||||
totalSz += issuerSeqSz;
|
totalSz += issuerSeqSz;
|
||||||
XMEMCPY(out + totalSz, decoded.issuerRaw, issuerSz);
|
XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz);
|
||||||
totalSz += issuerSz;
|
totalSz += issuerSz;
|
||||||
XMEMCPY(out + totalSz, serial, snSz);
|
XMEMCPY(out + totalSz, serial, snSz);
|
||||||
totalSz += snSz;
|
totalSz += snSz;
|
||||||
@@ -1051,7 +1142,13 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
|
XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
|
||||||
totalSz += *keyEncSz;
|
totalSz += *keyEncSz;
|
||||||
|
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(decoded);
|
||||||
|
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
return totalSz;
|
return totalSz;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user