|
79 | 79 | #include <wolfssl/wolfcrypt/signature.h> |
80 | 80 | #endif |
81 | 81 |
|
82 | | -#ifdef WOLFSSL_SMALL_CERT_VERIFY |
| 82 | +#if defined(WOLFSSL_SMALL_CERT_VERIFY) || \ |
| 83 | + (defined(HAVE_PKCS8) && !defined(NO_ASN)) |
| 84 | + /* for ASN tag and PBE/PKCS enum values used by the PKCS#8 encrypt tests */ |
83 | 85 | #include <wolfssl/wolfcrypt/asn.h> |
84 | 86 | #endif |
85 | 87 |
|
@@ -23157,6 +23159,109 @@ static int test_wc_CreateEncryptedPKCS8Key(void) |
23157 | 23159 | return EXPECT_RESULT(); |
23158 | 23160 | } |
23159 | 23161 |
|
| 23162 | +#if defined(HAVE_PKCS8) && !defined(NO_ASN) && !defined(NO_PWDBASED) && \ |
| 23163 | + !defined(NO_SHA) && !defined(NO_ASN_CRYPT) && ((defined(WOLFSSL_AES_256) && \ |
| 23164 | + !defined(NO_AES_CBC)) || !defined(NO_DES3) || !defined(NO_RC4)) |
| 23165 | +/* Encrypt a block-aligned plaintext PKCS#8 and verify the trailing encrypted |
| 23166 | + * OCTET STRING length. expExtra is the padding expected: a full block for CBC |
| 23167 | + * ciphers, 0 for stream ciphers. Also confirms a decrypt round-trip. */ |
| 23168 | +static int enc_pkcs8_pad_check(int vPKCS, int pbeOid, int encAlgId, |
| 23169 | + word32 expExtra) |
| 23170 | +{ |
| 23171 | + EXPECT_DECLS; |
| 23172 | + WC_RNG rng; |
| 23173 | + byte* encKey = NULL; |
| 23174 | + word32 encKeySz = 0; |
| 23175 | + int decKeySz = 0; |
| 23176 | + word32 expEncLen = 0; |
| 23177 | + const char password[] = "Lorem ipsum dolor sit amet"; |
| 23178 | + word32 passwordSz = (word32)XSTRLEN(password); |
| 23179 | + /* Block-aligned plaintext: a valid 48-byte DER SEQUENCE (a multiple of both |
| 23180 | + * the 8- and 16-byte block sizes). Content is arbitrary; only the header |
| 23181 | + * must parse so decrypt can strip padding by re-reading the DER length. */ |
| 23182 | + byte plain[48]; |
| 23183 | + |
| 23184 | + XMEMSET(plain, 0, sizeof(plain)); |
| 23185 | + plain[0] = ASN_SEQUENCE | ASN_CONSTRUCTED; |
| 23186 | + plain[1] = (byte)(sizeof(plain) - 2); /* content length = 46 */ |
| 23187 | + |
| 23188 | + XMEMSET(&rng, 0, sizeof(WC_RNG)); |
| 23189 | + ExpectIntEQ(wc_InitRng(&rng), 0); |
| 23190 | + PRIVATE_KEY_UNLOCK(); |
| 23191 | + /* Query required output size. */ |
| 23192 | + ExpectIntEQ(wc_EncryptPKCS8Key(plain, (word32)sizeof(plain), NULL, &encKeySz, |
| 23193 | + password, (int)passwordSz, vPKCS, pbeOid, encAlgId, NULL, 0, |
| 23194 | + WC_PKCS12_ITT_DEFAULT, &rng, NULL), WC_NO_ERR_TRACE(LENGTH_ONLY_E)); |
| 23195 | + ExpectNotNull(encKey = (byte*)XMALLOC(encKeySz, HEAP_HINT, |
| 23196 | + DYNAMIC_TYPE_TMP_BUFFER)); |
| 23197 | + ExpectIntGT(wc_EncryptPKCS8Key(plain, (word32)sizeof(plain), encKey, |
| 23198 | + &encKeySz, password, (int)passwordSz, vPKCS, pbeOid, encAlgId, NULL, 0, |
| 23199 | + WC_PKCS12_ITT_DEFAULT, &rng, NULL), 0); |
| 23200 | + |
| 23201 | + /* The encrypted content is the trailing OCTET STRING, extending to the end |
| 23202 | + * of the buffer: plaintext + expected pad, a full block for a block cipher |
| 23203 | + * and none for a stream cipher. Read below assumes a short-form length. */ |
| 23204 | + expEncLen = (word32)sizeof(plain) + expExtra; |
| 23205 | + ExpectIntLT(expEncLen, 128); |
| 23206 | + ExpectIntGE(encKeySz, expEncLen + 2); |
| 23207 | + if (EXPECT_SUCCESS() && (encKey != NULL) && (encKeySz >= expEncLen + 2)) { |
| 23208 | + ExpectIntEQ(encKey[encKeySz - expEncLen - 2], ASN_OCTET_STRING); |
| 23209 | + ExpectIntEQ(encKey[encKeySz - expEncLen - 1], (byte)expEncLen); |
| 23210 | + } |
| 23211 | + |
| 23212 | + /* Round-trip: decrypt recovers the original plaintext. */ |
| 23213 | + ExpectIntGT(decKeySz = wc_DecryptPKCS8Key(encKey, encKeySz, password, |
| 23214 | + (int)passwordSz), 0); |
| 23215 | + ExpectIntEQ(decKeySz, (int)sizeof(plain)); |
| 23216 | + ExpectIntEQ(XMEMCMP(encKey, plain, sizeof(plain)), 0); |
| 23217 | + PRIVATE_KEY_LOCK(); |
| 23218 | + |
| 23219 | + XFREE(encKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); |
| 23220 | + wc_FreeRng(&rng); |
| 23221 | + return EXPECT_RESULT(); |
| 23222 | +} |
| 23223 | +#endif |
| 23224 | + |
| 23225 | +/* PBES2 / AES-256-CBC (blockSz 16): a block-aligned plaintext must get a full |
| 23226 | + * pad block. The path the fix corrects; the helper's direct length check (not |
| 23227 | + * its round-trip, which false-passes here) is what detects a missing block. */ |
| 23228 | +static int test_wc_EncryptPKCS8Key_blockAligned(void) |
| 23229 | +{ |
| 23230 | + EXPECT_DECLS; |
| 23231 | +#if defined(HAVE_PKCS8) && !defined(NO_ASN) && !defined(NO_PWDBASED) \ |
| 23232 | + && defined(WOLFSSL_AES_256) && !defined(NO_AES_CBC) && !defined(NO_SHA) \ |
| 23233 | + && !defined(NO_ASN_CRYPT) |
| 23234 | + EXPECT_TEST(enc_pkcs8_pad_check(PKCS5, PBES2, AES256CBCb, AES_BLOCK_SIZE)); |
| 23235 | +#endif |
| 23236 | + return EXPECT_RESULT(); |
| 23237 | +} |
| 23238 | + |
| 23239 | +/* PBES1 / SHA1-DES (blockSz 8): exercises the PBES1 encoder branch and a |
| 23240 | + * different block size; a block-aligned plaintext gets a full 8-byte pad |
| 23241 | + * block. */ |
| 23242 | +static int test_wc_EncryptPKCS8Key_pbes1BlockAligned(void) |
| 23243 | +{ |
| 23244 | + EXPECT_DECLS; |
| 23245 | +#if defined(HAVE_PKCS8) && !defined(NO_ASN) && !defined(NO_PWDBASED) \ |
| 23246 | + && !defined(NO_DES3) && !defined(NO_SHA) && !defined(NO_ASN_CRYPT) |
| 23247 | + EXPECT_TEST(enc_pkcs8_pad_check(PKCS5, PBES1_SHA1_DES, 0, DES_BLOCK_SIZE)); |
| 23248 | +#endif |
| 23249 | + return EXPECT_RESULT(); |
| 23250 | +} |
| 23251 | + |
| 23252 | +/* PKCS12 / RC4 (blockSz 1): a stream cipher adds no padding even for a |
| 23253 | + * block-aligned plaintext. Exercises the blockSz > 1 guard in |
| 23254 | + * wc_EncryptPKCS8Key_ex. */ |
| 23255 | +static int test_wc_EncryptPKCS8Key_rc4NoPad(void) |
| 23256 | +{ |
| 23257 | + EXPECT_DECLS; |
| 23258 | +#if defined(HAVE_PKCS8) && !defined(NO_ASN) && !defined(NO_PWDBASED) \ |
| 23259 | + && !defined(NO_RC4) && !defined(NO_SHA) && !defined(NO_ASN_CRYPT) |
| 23260 | + EXPECT_TEST(enc_pkcs8_pad_check(1, PBE_SHA1_RC4_128, 0, 0)); |
| 23261 | +#endif |
| 23262 | + return EXPECT_RESULT(); |
| 23263 | +} |
| 23264 | + |
23160 | 23265 | static int test_wc_DecryptedPKCS8Key(void) |
23161 | 23266 | { |
23162 | 23267 | EXPECT_DECLS; |
@@ -36898,6 +37003,9 @@ TEST_CASE testCases[] = { |
36898 | 37003 | /* wolfCrypt ASN tests */ |
36899 | 37004 | TEST_DECL(test_ToTraditional), |
36900 | 37005 | TEST_DECL(test_wc_CreateEncryptedPKCS8Key), |
| 37006 | + TEST_DECL(test_wc_EncryptPKCS8Key_blockAligned), |
| 37007 | + TEST_DECL(test_wc_EncryptPKCS8Key_pbes1BlockAligned), |
| 37008 | + TEST_DECL(test_wc_EncryptPKCS8Key_rc4NoPad), |
36901 | 37009 | TEST_DECL(test_wc_DecryptedPKCS8Key), |
36902 | 37010 | TEST_DECL(test_wc_GetPkcs8TraditionalOffset), |
36903 | 37011 |
|
|
0 commit comments