@@ -16785,3 +16785,165 @@ int test_mldsa_pkcs8(void)
1678516785#endif
1678616786 return EXPECT_RESULT();
1678716787}
16788+
16789+ int test_mldsa_pkcs12(void)
16790+ {
16791+ EXPECT_DECLS;
16792+ #if !defined(NO_ASN) && defined(HAVE_PKCS12) && \
16793+ defined(HAVE_DILITHIUM) && !defined(NO_TLS) && \
16794+ !defined(NO_PWDBASED) && !defined(NO_HMAC) && \
16795+ !defined(NO_CERTS) && !defined(NO_DES3) && \
16796+ (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
16797+
16798+ WOLFSSL_CTX* ctx = NULL;
16799+ word32 i;
16800+ byte* inKey = NULL;
16801+ byte* inCert = NULL;
16802+ const word32 inKeyHeaderSz = 4;
16803+ const word32 inKeyMaxSz = inKeyHeaderSz + DILITHIUM_MAX_PRV_KEY_SIZE;
16804+ const word32 certConstSz = 412;
16805+ const word32 inCertMaxSz =
16806+ certConstSz + DILITHIUM_MAX_SIG_SIZE + DILITHIUM_MAX_PUB_KEY_SIZE;
16807+ const word32 pkcs8HeaderSz = 24;
16808+ WC_RNG rng;
16809+ dilithium_key mldsa_key;
16810+ char pkcs12Passwd[] = "mldsa";
16811+
16812+ struct {
16813+ int enc;
16814+ int wcId;
16815+ int oidSum;
16816+ int keySz;
16817+ int sigType;
16818+ int keyType;
16819+ } test_variant[] = {
16820+ {PBE_SHA1_DES3, WC_ML_DSA_44, ML_DSA_LEVEL2k,
16821+ ML_DSA_LEVEL2_PRV_KEY_SIZE, CTC_ML_DSA_LEVEL2, ML_DSA_LEVEL2_TYPE},
16822+ {PBE_SHA1_DES3, WC_ML_DSA_65, ML_DSA_LEVEL3k,
16823+ ML_DSA_LEVEL3_PRV_KEY_SIZE, CTC_ML_DSA_LEVEL3, ML_DSA_LEVEL3_TYPE},
16824+ {PBE_SHA1_DES3, WC_ML_DSA_87, ML_DSA_LEVEL5k,
16825+ ML_DSA_LEVEL5_PRV_KEY_SIZE, CTC_ML_DSA_LEVEL5, ML_DSA_LEVEL5_TYPE},
16826+ {-1, WC_ML_DSA_44, ML_DSA_LEVEL2k,
16827+ ML_DSA_LEVEL2_PRV_KEY_SIZE, CTC_ML_DSA_LEVEL2, ML_DSA_LEVEL2_TYPE},
16828+ {-1, WC_ML_DSA_65, ML_DSA_LEVEL3k,
16829+ ML_DSA_LEVEL3_PRV_KEY_SIZE, CTC_ML_DSA_LEVEL3, ML_DSA_LEVEL3_TYPE},
16830+ {-1, WC_ML_DSA_87, ML_DSA_LEVEL5k,
16831+ ML_DSA_LEVEL5_PRV_KEY_SIZE, CTC_ML_DSA_LEVEL5, ML_DSA_LEVEL5_TYPE},
16832+ };
16833+
16834+ ExpectNotNull(inKey = (byte*) XMALLOC(inKeyMaxSz, NULL,
16835+ DYNAMIC_TYPE_TMP_BUFFER));
16836+ ExpectNotNull(inCert = (byte*) XMALLOC(inCertMaxSz, NULL,
16837+ DYNAMIC_TYPE_TMP_BUFFER));
16838+
16839+ #ifndef NO_WOLFSSL_SERVER
16840+ ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
16841+ #else
16842+ ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
16843+ #endif /* NO_WOLFSSL_SERVER */
16844+
16845+ ExpectIntEQ(wc_InitRng(&rng), 0);
16846+ ExpectIntEQ(wc_dilithium_init(&mldsa_key), 0);
16847+
16848+ for (i = 0; i < sizeof(test_variant) / sizeof(test_variant[0]); ++i) {
16849+ WC_PKCS12* pkcs12Export = NULL;
16850+ WC_PKCS12* pkcs12Import = NULL;
16851+ byte* pkcs12Der = NULL;
16852+ byte* outKey = NULL;
16853+ byte* outCert = NULL;
16854+ word32 inKeySz = 0;
16855+ word32 inCertSz = 0;
16856+ word32 pkcs12DerSz = 0;
16857+ word32 outKeySz = 0;
16858+ word32 outCertSz = 0;
16859+ Cert cert;
16860+ word32 size;
16861+
16862+ if (EXPECT_FAIL())
16863+ break;
16864+
16865+ /* Create a key for wc_PKCS12_create() */
16866+ inKeySz = 0;
16867+ inKey[0] = 0x04; /* ASN.1 OCTET STRING */
16868+ inKey[1] = 0x82; /* 2 bytes length field */
16869+ inKey[2] = (test_variant[i].keySz >> 8) & 0xff; /* MSB of the length */
16870+ inKey[3] = test_variant[i].keySz & 0xff; /* LSB of the length */
16871+ inKeySz += inKeyHeaderSz;
16872+ ExpectIntEQ(wc_dilithium_set_level(&mldsa_key, test_variant[i].wcId),
16873+ 0);
16874+ ExpectIntEQ(wc_dilithium_make_key(&mldsa_key, &rng), 0);
16875+ size = inKeyMaxSz - inKeySz;
16876+ ExpectIntEQ(wc_dilithium_export_private(&mldsa_key, inKey + inKeySz,
16877+ &size), 0);
16878+ inKeySz += size;
16879+ size = inKeyMaxSz - inKeySz;
16880+ ExpectIntEQ(wc_dilithium_export_public(&mldsa_key, inKey + inKeySz,
16881+ &size), 0);
16882+ inKeySz += size;
16883+
16884+ /* Create a certificate for wc_PKCS12_create() */
16885+ ExpectIntEQ(wc_InitCert(&cert), 0);
16886+ XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
16887+ XSTRNCPY(cert.subject.state, "MT", CTC_NAME_SIZE);
16888+ XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
16889+ XSTRNCPY(cert.subject.org, "wolfSSL", CTC_NAME_SIZE);
16890+ XSTRNCPY(cert.subject.unit, "Engineering", CTC_NAME_SIZE);
16891+ XSTRNCPY(cert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
16892+ XSTRNCPY(cert.subject.email, "root@wolfssl.com", CTC_NAME_SIZE);
16893+ XSTRNCPY((char*)cert.beforeDate, "\x18\x0f""20250101000000Z",
16894+ CTC_DATE_SIZE);
16895+ cert.beforeDateSz = 17;
16896+ XSTRNCPY((char*)cert.afterDate, "\x18\x0f""20493112115959Z",
16897+ CTC_DATE_SIZE);
16898+ cert.afterDateSz = 17;
16899+ cert.selfSigned = 1;
16900+ cert.sigType = test_variant[i].sigType;
16901+ cert.isCA = 0;
16902+ ExpectIntGE(inCertSz = wc_MakeCert_ex(&cert, inCert, inCertMaxSz,
16903+ test_variant[i].keyType, &mldsa_key, &rng), 0);
16904+ ExpectIntGE(inCertSz = wc_SignCert_ex(cert.bodySz, cert.sigType, inCert,
16905+ inCertMaxSz, test_variant[i].keyType, &mldsa_key, &rng), 0);
16906+
16907+ ExpectNotNull(pkcs12Export = wc_PKCS12_create(pkcs12Passwd,
16908+ sizeof(pkcs12Passwd) - 1,
16909+ (char*) "friendlyName" /* not used currently */,
16910+ (byte*) inKey, inKeySz, (byte*) inCert, inCertSz,
16911+ NULL, test_variant[i].enc, test_variant[i].enc, 100, 100,
16912+ 0 /* not used currently */, NULL));
16913+ pkcs12Der = NULL;
16914+ ExpectIntGE((pkcs12DerSz = wc_i2d_PKCS12(pkcs12Export, &pkcs12Der,
16915+ NULL)), 0);
16916+
16917+ ExpectNotNull(pkcs12Import = wc_PKCS12_new_ex(NULL));
16918+ ExpectIntGE(wc_d2i_PKCS12(pkcs12Der, pkcs12DerSz, pkcs12Import), 0);
16919+ ExpectIntEQ(wc_PKCS12_parse_ex(pkcs12Import, pkcs12Passwd, &outKey,
16920+ &outKeySz,
16921+ &outCert, &outCertSz, NULL, 1), 0);
16922+ ExpectIntGT(outKeySz, 0);
16923+ ExpectIntGT(outCertSz, 0);
16924+ ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, outKey, outKeySz,
16925+ WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
16926+ ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, outCert, outCertSz,
16927+ WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
16928+
16929+ ExpectIntEQ(inKeySz, outKeySz - pkcs8HeaderSz);
16930+ ExpectIntEQ(XMEMCMP(inKey, outKey + pkcs8HeaderSz, inKeySz), 0);
16931+ ExpectIntEQ(inCertSz, outCertSz);
16932+ ExpectIntEQ(XMEMCMP(inCert, outCert, inCertSz), 0);
16933+
16934+ XFREE(outKey, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
16935+ XFREE(outCert, NULL, DYNAMIC_TYPE_PKCS);
16936+ wc_PKCS12_free(pkcs12Import);
16937+ XFREE(pkcs12Der, NULL, DYNAMIC_TYPE_PKCS);
16938+ wc_PKCS12_free(pkcs12Export);
16939+ }
16940+
16941+ wc_dilithium_free(&mldsa_key);
16942+ ExpectIntEQ(wc_FreeRng(&rng), 0);
16943+ wolfSSL_CTX_free(ctx);
16944+ XFREE(inCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16945+ XFREE(inKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16946+
16947+ #endif
16948+ return EXPECT_RESULT();
16949+ }
0 commit comments