Skip to content

Commit be5f203

Browse files
authored
Merge pull request #8425 from philljj/ecdsa_mldsa_test_api
dual alg: add ML-DSA test, and misc cleanup.
2 parents ff41eee + 557e43b commit be5f203

5 files changed

Lines changed: 273 additions & 82 deletions

File tree

src/x509.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,10 +1695,10 @@ int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
16951695
* Returns NULL on error or pointer to the v3_ext_method populated with
16961696
* extension type-specific X509V3_EXT_* function(s).
16971697
*
1698-
* NOTE: WC_NID_subject_key_identifier is currently the only extension implementing
1699-
* the X509V3_EXT_* functions, as it is the only type called directly by QT. The
1700-
* other extension types return a pointer to a v3_ext_method struct that
1701-
* contains only the NID.
1698+
* NOTE: WC_NID_subject_key_identifier is currently the only extension
1699+
* implementing the X509V3_EXT_* functions, as it is the only type called
1700+
* directly by QT. The other extension types return a pointer to a
1701+
* v3_ext_method struct that contains only the NID.
17021702
*/
17031703
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
17041704
const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
@@ -4559,7 +4559,8 @@ WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
45594559
* WOLFSSL_SUCCESS otherwise.
45604560
*/
45614561
int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
4562-
WOLFSSL_ASN1_OBJECT* oid, WOLFSSL_ASN1_TYPE* value)
4562+
WOLFSSL_ASN1_OBJECT* oid,
4563+
WOLFSSL_ASN1_TYPE* value)
45634564
{
45644565
WOLFSSL_ASN1_OBJECT *x = NULL;
45654566

@@ -8084,11 +8085,22 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
80848085
}
80858086

80868087
#ifdef WOLFSSL_DUAL_ALG_CERTS
8088+
/* Generate a der preTBS from a decoded cert, and write
8089+
* to buffer.
8090+
*
8091+
* @param [in] cert The decoded cert to parse.
8092+
* @param [out] der The der buffer to write in.
8093+
* @param [in] derSz The der buffer size.
8094+
*
8095+
* @return preTBS der size on success.
8096+
* */
80878097
int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
80888098
int ret = 0;
80898099
WOLFSSL_X509 *x = NULL;
80908100
byte certIsCSR = 0;
80918101

8102+
WOLFSSL_ENTER("wc_GeneratePreTBS");
8103+
80928104
if ((cert == NULL) || (der == NULL) || (derSz <= 0)) {
80938105
return BAD_FUNC_ARG;
80948106
}
@@ -13941,7 +13953,8 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
1394113953
int tmpSz;
1394213954

1394313955
/* reverse name order for RFC2253 and DN_REV */
13944-
if ((flags & WOLFSSL_XN_FLAG_RFC2253) || (flags & WOLFSSL_XN_FLAG_DN_REV)) {
13956+
if ((flags & WOLFSSL_XN_FLAG_RFC2253) ||
13957+
(flags & WOLFSSL_XN_FLAG_DN_REV)) {
1394513958
ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
1394613959
}
1394713960
else {
@@ -15731,6 +15744,17 @@ int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey)
1573115744
return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1573215745
}
1573315746

15747+
/* Loads an x509 attribute certificate from buffer, and returns
15748+
* pointer to new WOLFSSL_X509_ACERT struct on success.
15749+
*
15750+
* @param [in] buf The acert buffer to load.
15751+
* @param [in] sz The size of the buffer.
15752+
* @param [in] format The format of the buffer data.
15753+
* @param [in] heap Dynamic memory allocation hint.
15754+
*
15755+
* @return pointer to WOLFSSL_X509_ACERT on success.
15756+
* @return NULL on error.
15757+
* */
1573415758
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer_ex(
1573515759
const unsigned char* buf, int sz, int format, void * heap)
1573615760
{

tests/api.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,153 @@ static int test_dual_alg_support(void)
16031603
}
16041604
#endif /* WOLFSSL_DUAL_ALG_CERTS && !NO_FILESYSTEM */
16051605

1606+
/**
1607+
* Test dual-alg ECDSA + ML-DSA:
1608+
* - keygen + certgen + cert manager load
1609+
* */
1610+
static int test_dual_alg_ecdsa_mldsa(void)
1611+
{
1612+
EXPECT_DECLS;
1613+
#if defined(WOLFSSL_DUAL_ALG_CERTS) && defined(HAVE_DILITHIUM) && \
1614+
defined(HAVE_ECC) && !defined(WC_NO_RNG) && \
1615+
defined(WOLFSSL_WC_DILITHIUM) && \
1616+
!defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \
1617+
!defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
1618+
!defined(WOLFSSL_DILITHIUM_NO_VERIFY) && !defined(WOLFSSL_SMALL_STACK)
1619+
WOLFSSL_CERT_MANAGER * cm = NULL;
1620+
MlDsaKey alt_ca_key;
1621+
ecc_key ca_key;
1622+
WC_RNG rng;
1623+
int ret = 0;
1624+
DecodedCert d_cert;
1625+
Cert new_cert;
1626+
/* various tmp buffs. */
1627+
byte alt_pub_der[LARGE_TEMP_SZ];
1628+
word32 alt_pub_sz = LARGE_TEMP_SZ;
1629+
byte alt_sig_alg[LARGE_TEMP_SZ];
1630+
word32 alt_sig_alg_sz = LARGE_TEMP_SZ;
1631+
byte tbs_der[LARGE_TEMP_SZ];
1632+
word32 tbs_der_sz = LARGE_TEMP_SZ;
1633+
byte alt_sig[LARGE_TEMP_SZ];
1634+
word32 alt_sig_sz = LARGE_TEMP_SZ;
1635+
/* Intermediate der. */
1636+
byte der[LARGE_TEMP_SZ];
1637+
word32 der_sz = LARGE_TEMP_SZ;
1638+
/* The final der will be large because of ML-DSA signature. */
1639+
byte final_der[2 * LARGE_TEMP_SZ];
1640+
word32 final_der_sz = 2 * LARGE_TEMP_SZ;
1641+
1642+
XMEMSET(alt_pub_der, 0, alt_pub_sz);
1643+
XMEMSET(alt_sig_alg, 0, alt_sig_alg_sz);
1644+
XMEMSET(tbs_der, 0, tbs_der_sz);
1645+
XMEMSET(alt_sig, 0, alt_sig_sz);
1646+
XMEMSET(der, 0, der_sz);
1647+
XMEMSET(final_der, 0, final_der_sz);
1648+
1649+
ExpectIntEQ(wc_InitRng(&rng), 0);
1650+
1651+
/**
1652+
* ML-DSA key gen.
1653+
* */
1654+
ret = wc_MlDsaKey_Init(&alt_ca_key, NULL, INVALID_DEVID);
1655+
ExpectIntEQ(ret, 0);
1656+
ret = wc_MlDsaKey_SetParams(&alt_ca_key, WC_ML_DSA_44);
1657+
ExpectIntEQ(ret, 0);
1658+
ret = wc_MlDsaKey_MakeKey(&alt_ca_key, &rng);
1659+
ExpectIntEQ(ret, 0);
1660+
alt_pub_sz = wc_MlDsaKey_PublicKeyToDer(&alt_ca_key, alt_pub_der,
1661+
alt_pub_sz, 1);
1662+
ExpectIntGT(alt_pub_sz, 0);
1663+
1664+
alt_sig_alg_sz = SetAlgoID(CTC_SHA256wECDSA, alt_sig_alg, oidSigType, 0);
1665+
ExpectIntGT(alt_sig_alg_sz, 0);
1666+
1667+
/**
1668+
* ECC key gen.
1669+
* */
1670+
ret = wc_ecc_init(&ca_key);
1671+
ExpectIntEQ(ret, 0);
1672+
ret = wc_ecc_make_key(&rng, KEY32, &ca_key);
1673+
ExpectIntEQ(ret, 0);
1674+
1675+
/**
1676+
* Cert gen.
1677+
* */
1678+
wc_InitCert(&new_cert);
1679+
strncpy(new_cert.subject.country, "US", CTC_NAME_SIZE);
1680+
strncpy(new_cert.subject.state, "MT", CTC_NAME_SIZE);
1681+
strncpy(new_cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
1682+
strncpy(new_cert.subject.org, "wolfSSL", CTC_NAME_SIZE);
1683+
strncpy(new_cert.subject.unit, "Engineering", CTC_NAME_SIZE);
1684+
strncpy(new_cert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
1685+
strncpy(new_cert.subject.email, "root@wolfssl.com", CTC_NAME_SIZE);
1686+
new_cert.sigType = CTC_SHA256wECDSA;
1687+
new_cert.isCA = 1;
1688+
1689+
ret = wc_SetCustomExtension(&new_cert, 0, "1.2.3.4.5",
1690+
(const byte *)"This is NOT a critical extension", 32);
1691+
ExpectIntEQ(ret, 0);
1692+
1693+
ExpectIntEQ(wc_SetCustomExtension(&new_cert, 0, "2.5.29.72", alt_pub_der,
1694+
alt_pub_sz), 0);
1695+
ExpectIntEQ(wc_SetCustomExtension(&new_cert, 0, "2.5.29.73", alt_sig_alg,
1696+
alt_sig_alg_sz), 0);
1697+
1698+
ret = wc_MakeCert_ex(&new_cert, der, der_sz, ECC_TYPE, &ca_key, &rng);
1699+
ExpectIntGT(ret, 0);
1700+
1701+
der_sz = wc_SignCert_ex(new_cert.bodySz, new_cert.sigType, der, der_sz,
1702+
ECC_TYPE, &ca_key, &rng);
1703+
ExpectIntGT(der_sz, 0);
1704+
1705+
wc_InitDecodedCert(&d_cert, der, der_sz, 0);
1706+
ret = wc_ParseCert(&d_cert, CERT_TYPE, NO_VERIFY, NULL);
1707+
ExpectIntEQ(ret, 0);
1708+
1709+
tbs_der_sz = wc_GeneratePreTBS(&d_cert, tbs_der, tbs_der_sz);
1710+
ExpectIntGT(tbs_der_sz, 0);
1711+
1712+
alt_sig_sz = wc_MakeSigWithBitStr(alt_sig, alt_sig_sz,
1713+
CTC_ML_DSA_LEVEL2, tbs_der, tbs_der_sz,
1714+
ML_DSA_LEVEL2_TYPE, &alt_ca_key, &rng);
1715+
ExpectIntGT(alt_sig_sz, 0);
1716+
1717+
ret = wc_SetCustomExtension(&new_cert, 0, "2.5.29.74", alt_sig, alt_sig_sz);
1718+
ExpectIntEQ(ret, 0);
1719+
1720+
/* Finally generate the new certificate. */
1721+
ret = wc_MakeCert_ex(&new_cert, final_der, final_der_sz, ECC_TYPE, &ca_key,
1722+
&rng);
1723+
ExpectIntGT(ret, 0);
1724+
1725+
final_der_sz = wc_SignCert_ex(new_cert.bodySz, new_cert.sigType, final_der,
1726+
final_der_sz, ECC_TYPE, &ca_key, &rng);
1727+
ExpectIntGT(final_der_sz, 0);
1728+
1729+
cm = wolfSSL_CertManagerNew();
1730+
ExpectNotNull(cm);
1731+
1732+
/* Load the certificate into CertManager. */
1733+
if (cm != NULL && final_der_sz > 0) {
1734+
ret = wolfSSL_CertManagerLoadCABuffer(cm, final_der, final_der_sz,
1735+
WOLFSSL_FILETYPE_ASN1);
1736+
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
1737+
}
1738+
1739+
if (cm != NULL) {
1740+
wolfSSL_CertManagerFree(cm);
1741+
cm = NULL;
1742+
}
1743+
1744+
wc_ecc_free(&ca_key);
1745+
wc_MlDsaKey_Free(&alt_ca_key);
1746+
wc_FreeRng(&rng);
1747+
1748+
#endif /* WOLFSSL_DUAL_ALG_CERTS && DILITHIUM and more */
1749+
return EXPECT_RESULT();
1750+
}
1751+
1752+
16061753
/*----------------------------------------------------------------------------*
16071754
| Context
16081755
*----------------------------------------------------------------------------*/
@@ -99002,6 +99149,8 @@ TEST_CASE testCases[] = {
9900299149

9900399150
TEST_DECL(test_dual_alg_support),
9900499151

99152+
TEST_DECL(test_dual_alg_ecdsa_mldsa),
99153+
9900599154
/*********************************
9900699155
* OpenSSL compatibility API tests
9900799156
*********************************/

0 commit comments

Comments
 (0)