Skip to content

Commit d7dd4f5

Browse files
committed
fix: check key type in C_SignInit/C_VerifyInit to prevent crash
Passing a wrong asymmetric key type (e.g. EC key) to a mismatched mechanism (e.g. CKM_RSA_PKCS) caused a crash (segfault or abort) because the code tried to read RSA attributes from an EC key object, then passed invalid data to OpenSSL. Add key type validation after the mechanism switch in both functions, returning CKR_KEY_TYPE_INCONSISTENT on mismatch. Also convert the GOST catch-all else branch to an explicit else-if(isGOST) check. Move MLDSA check also - to be consistent with other checks. Regression tests use cross-matched asymmetric keys (EC key with RSA mechanisms, RSA key with ECDSA/EdDSA mechanisms) to verify the fix. Without the fix, C_SignInit accepts the wrong key type and the subsequent C_Sign crashes.
1 parent 3e6e6c3 commit d7dd4f5

File tree

3 files changed

+258
-24
lines changed

3 files changed

+258
-24
lines changed

src/lib/SoftHSM.cpp

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4190,6 +4190,9 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
41904190
if (!isMechanismPermitted(key, pMechanism->mechanism))
41914191
return CKR_MECHANISM_INVALID;
41924192

4193+
// Get key info
4194+
CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
4195+
41934196
// Get the asymmetric algorithm matching the mechanism
41944197
AsymMech::Type mechanism = AsymMech::Unknown;
41954198
void* param = NULL;
@@ -4202,13 +4205,15 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
42024205
#ifdef WITH_ECC
42034206
bool isECDSA = false;
42044207
#endif
4208+
#ifdef WITH_GOST
4209+
bool isGOST = false;
4210+
#endif
42054211
#ifdef WITH_EDDSA
42064212
bool isEDDSA = false;
42074213
#endif
42084214
#ifdef WITH_ML_DSA
42094215
bool isMLDSA = false;
42104216
MLDSAMechanismParam mldsaParam;
4211-
CK_KEY_TYPE keyType;
42124217
#endif
42134218
switch(pMechanism->mechanism) {
42144219
case CKM_RSA_PKCS:
@@ -4463,10 +4468,12 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
44634468
case CKM_GOSTR3410:
44644469
mechanism = AsymMech::GOST;
44654470
bAllowMultiPartOp = false;
4471+
isGOST = true;
44664472
break;
44674473
case CKM_GOSTR3410_WITH_GOSTR3411:
44684474
mechanism = AsymMech::GOST_GOST;
44694475
bAllowMultiPartOp = true;
4476+
isGOST = true;
44704477
break;
44714478
#endif
44724479
#ifdef WITH_EDDSA
@@ -4478,12 +4485,6 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
44784485
#endif
44794486
#ifdef WITH_ML_DSA
44804487
case CKM_ML_DSA:
4481-
// Get key info
4482-
keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
4483-
if (keyType != CKK_ML_DSA)
4484-
{
4485-
return CKR_KEY_TYPE_INCONSISTENT;
4486-
}
44874488
mechanism = AsymMech::MLDSA;
44884489
bAllowMultiPartOp = false;
44894490
isMLDSA = true;
@@ -4531,6 +4532,9 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
45314532
PrivateKey* privateKey = NULL;
45324533
if (isRSA)
45334534
{
4535+
if (keyType != CKK_RSA)
4536+
return CKR_KEY_TYPE_INCONSISTENT;
4537+
45344538
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
45354539
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
45364540

@@ -4550,6 +4554,9 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
45504554
}
45514555
else if (isDSA)
45524556
{
4557+
if (keyType != CKK_DSA)
4558+
return CKR_KEY_TYPE_INCONSISTENT;
4559+
45534560
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
45544561
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
45554562

@@ -4570,6 +4577,9 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
45704577
#ifdef WITH_ECC
45714578
else if (isECDSA)
45724579
{
4580+
if (keyType != CKK_EC)
4581+
return CKR_KEY_TYPE_INCONSISTENT;
4582+
45734583
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
45744584
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
45754585

@@ -4591,6 +4601,9 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
45914601
#ifdef WITH_EDDSA
45924602
else if (isEDDSA)
45934603
{
4604+
if (keyType != CKK_EC_EDWARDS)
4605+
return CKR_KEY_TYPE_INCONSISTENT;
4606+
45944607
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
45954608
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
45964609

@@ -4612,6 +4625,9 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
46124625
#ifdef WITH_ML_DSA
46134626
else if (isMLDSA)
46144627
{
4628+
if (keyType != CKK_ML_DSA)
4629+
return CKR_KEY_TYPE_INCONSISTENT;
4630+
46154631
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::MLDSA);
46164632
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
46174633

@@ -4630,9 +4646,12 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
46304646
}
46314647
}
46324648
#endif
4633-
else
4634-
{
46354649
#ifdef WITH_GOST
4650+
else if (isGOST)
4651+
{
4652+
if (keyType != CKK_GOSTR3410)
4653+
return CKR_KEY_TYPE_INCONSISTENT;
4654+
46364655
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
46374656
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
46384657

@@ -4649,10 +4668,12 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
46494668
CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
46504669
return CKR_GENERAL_ERROR;
46514670
}
4652-
#else
4653-
return CKR_MECHANISM_INVALID;
4671+
}
46544672
#endif
4655-
}
4673+
else
4674+
{
4675+
return CKR_MECHANISM_INVALID;
4676+
}
46564677

46574678
// Initialize signing
46584679
if (bAllowMultiPartOp && !asymCrypto->signInit(privateKey,mechanism,param,paramLen))
@@ -5269,6 +5290,9 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
52695290
if (!isMechanismPermitted(key, pMechanism->mechanism))
52705291
return CKR_MECHANISM_INVALID;
52715292

5293+
// Get key info
5294+
CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
5295+
52725296
// Get the asymmetric algorithm matching the mechanism
52735297
AsymMech::Type mechanism = AsymMech::Unknown;
52745298
void* param = NULL;
@@ -5281,13 +5305,15 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
52815305
#ifdef WITH_ECC
52825306
bool isECDSA = false;
52835307
#endif
5308+
#ifdef WITH_GOST
5309+
bool isGOST = false;
5310+
#endif
52845311
#ifdef WITH_EDDSA
52855312
bool isEDDSA = false;
52865313
#endif
52875314
#ifdef WITH_ML_DSA
52885315
bool isMLDSA = false;
52895316
MLDSAMechanismParam mldsaParam;
5290-
CK_KEY_TYPE keyType;
52915317
#endif
52925318
switch(pMechanism->mechanism) {
52935319
case CKM_RSA_PKCS:
@@ -5540,10 +5566,12 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
55405566
case CKM_GOSTR3410:
55415567
mechanism = AsymMech::GOST;
55425568
bAllowMultiPartOp = false;
5569+
isGOST = true;
55435570
break;
55445571
case CKM_GOSTR3410_WITH_GOSTR3411:
55455572
mechanism = AsymMech::GOST_GOST;
55465573
bAllowMultiPartOp = true;
5574+
isGOST = true;
55475575
break;
55485576
#endif
55495577
#ifdef WITH_EDDSA
@@ -5555,12 +5583,6 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
55555583
#endif
55565584
#ifdef WITH_ML_DSA
55575585
case CKM_ML_DSA:
5558-
// Get key info
5559-
keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
5560-
if (keyType != CKK_ML_DSA)
5561-
{
5562-
return CKR_KEY_TYPE_INCONSISTENT;
5563-
}
55645586
mechanism = AsymMech::MLDSA;
55655587
bAllowMultiPartOp = false;
55665588
isMLDSA = true;
@@ -5608,6 +5630,9 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
56085630
PublicKey* publicKey = NULL;
56095631
if (isRSA)
56105632
{
5633+
if (keyType != CKK_RSA)
5634+
return CKR_KEY_TYPE_INCONSISTENT;
5635+
56115636
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
56125637
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
56135638

@@ -5627,6 +5652,9 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
56275652
}
56285653
else if (isDSA)
56295654
{
5655+
if (keyType != CKK_DSA)
5656+
return CKR_KEY_TYPE_INCONSISTENT;
5657+
56305658
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
56315659
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
56325660

@@ -5647,6 +5675,9 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
56475675
#ifdef WITH_ECC
56485676
else if (isECDSA)
56495677
{
5678+
if (keyType != CKK_EC)
5679+
return CKR_KEY_TYPE_INCONSISTENT;
5680+
56505681
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
56515682
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
56525683

@@ -5668,6 +5699,9 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
56685699
#ifdef WITH_EDDSA
56695700
else if (isEDDSA)
56705701
{
5702+
if (keyType != CKK_EC_EDWARDS)
5703+
return CKR_KEY_TYPE_INCONSISTENT;
5704+
56715705
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
56725706
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
56735707

@@ -5689,6 +5723,9 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
56895723
#ifdef WITH_ML_DSA
56905724
else if (isMLDSA)
56915725
{
5726+
if (keyType != CKK_ML_DSA)
5727+
return CKR_KEY_TYPE_INCONSISTENT;
5728+
56925729
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::MLDSA);
56935730
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
56945731

@@ -5707,9 +5744,12 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
57075744
}
57085745
}
57095746
#endif
5710-
else
5711-
{
57125747
#ifdef WITH_GOST
5748+
else if (isGOST)
5749+
{
5750+
if (keyType != CKK_GOSTR3410)
5751+
return CKR_KEY_TYPE_INCONSISTENT;
5752+
57135753
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
57145754
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
57155755

@@ -5726,10 +5766,12 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
57265766
CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
57275767
return CKR_GENERAL_ERROR;
57285768
}
5729-
#else
5730-
return CKR_MECHANISM_INVALID;
5769+
}
57315770
#endif
5732-
}
5771+
else
5772+
{
5773+
return CKR_MECHANISM_INVALID;
5774+
}
57335775

57345776
// Initialize verifying
57355777
if (bAllowMultiPartOp && !asymCrypto->verifyInit(publicKey,mechanism,param,paramLen))

0 commit comments

Comments
 (0)