Skip to content

Commit ee4d550

Browse files
committed
BCFKS isKeyEntry() now reports PBE key entries, so KeyStore.getEntry() returns them, relates to github #2164.
1 parent a05cc6b commit ee4d550

4 files changed

Lines changed: 20 additions & 2 deletions

File tree

‎docs/releasenotes.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Date: 2026, TBD
1515

1616
### 2.1.2 Defects Fixed
1717

18+
- A PBEKey stored in a BCFKS KeyStore was not reported as a key entry: isKeyEntry() returned false for it, so KeyStore.getEntry() returned null rather than a SecretKeyEntry, although getKey() recovered it. The PBE key entry type added for github #2164 was missing from engineIsKeyEntry, and is now included.
1819
- A KeyAgreement asked for its shared secret before doPhase returned data rather than refusing. javax.crypto.KeyAgreement specifies IllegalStateException for that state, but nothing in the provider tracked it, so each SPI handed back whatever its result field held: for Diffie-Hellman that was the private value itself - engineInit seeded result with x, so generateSecret() returned the private exponent padded to the prime's length and generateSecret("AES") an all-zero key taken from that padding - while ECDH returned null and its named-algorithm overload raised NullPointerException. BaseAgreementSpi now records whether a doPhase has completed the agreement since the last init and refuses the request with an IllegalStateException naming the algorithm, so every family in the provider - DH, ECDH and ECMQV, the SM2 exchange, both ECGOST families, XDH, SM9 and NewHope - answers the same way, and the DH SPI no longer holds the private value in that field at all.
1920
- Mac.getInstance and KeyGenerator.getInstance by the HMAC SHA-512/224 and SHA-512/256 object identifiers (1.2.840.113549.2.12 and .13) failed, although the same algorithms resolved by name and the matching SecretKeyFactory aliases were registered: the SHA512 mappings called addHMACAlgorithm for the two truncated variants without the addHMACAlias that registers their OIDs against Mac and KeyGenerator. Both are now aliased, as every other HMAC in that class already was.
2021
- A KTSParameterSpec naming an HKDF key-derivation function with a parameters field - a form the provider does not service - was accepted at Cipher init and then failed out of wrap or unwrap with an unchecked IllegalStateException neither method declares. The KTS key-wrapping Ciphers (ML-KEM, Classic McEliece, FrodoKEM, the composite KEM and RSA-KEM) now validate the spec's KDF when they take it, reporting an unserviceable one as the InvalidAlgorithmParameterException engineInit declares, which is what the javax.crypto.KEM services already did through KdfUtil.resolveKemSpec.

‎prov/src/main/java/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,8 @@ public boolean engineIsKeyEntry(String alias)
778778
{
779779
BigInteger entryType = ent.getType();
780780
return entryType.equals(PRIVATE_KEY) || entryType.equals(SECRET_KEY)
781-
|| entryType.equals(PROTECTED_PRIVATE_KEY) || entryType.equals(PROTECTED_SECRET_KEY);
781+
|| entryType.equals(PROTECTED_PRIVATE_KEY) || entryType.equals(PROTECTED_SECRET_KEY)
782+
|| entryType.equals(PBKDF_KEY);
782783
}
783784

784785
return false;

‎prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/keystore/bcfks/BcFKSKeyStoreSpi.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,8 @@ public boolean engineIsKeyEntry(String alias)
717717
{
718718
BigInteger entryType = ent.getType();
719719
return entryType.equals(PRIVATE_KEY) || entryType.equals(SECRET_KEY)
720-
|| entryType.equals(PROTECTED_PRIVATE_KEY) || entryType.equals(PROTECTED_SECRET_KEY);
720+
|| entryType.equals(PROTECTED_PRIVATE_KEY) || entryType.equals(PROTECTED_SECRET_KEY)
721+
|| entryType.equals(PBKDF_KEY);
721722
}
722723

723724
return false;

‎prov/src/test/java/org/bouncycastle/jce/provider/test/BCFKSStoreTest.java‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,21 @@ public void shouldStoreOnePBEKey()
11991199
isTrue("algorithm mismatch: " + rPbe.getAlgorithm(), origAlg.equals(rPbe.getAlgorithm()));
12001200
isTrue("encoded mismatch", Arrays.areEqual(origEncoded, rPbe.getEncoded()));
12011201

1202+
// a PBE key entry is a key entry, so getEntry() must return it as a SecretKeyEntry
1203+
isTrue("PBE key not a key entry", store2.isKeyEntry("pbeKey"));
1204+
isTrue("PBE key reported as certificate entry", !store2.isCertificateEntry("pbeKey"));
1205+
1206+
KeyStore.Entry entry = store2.getEntry("pbeKey", new KeyStore.PasswordProtection(testPassword));
1207+
isTrue("entry not a SecretKeyEntry: " + entry, entry instanceof KeyStore.SecretKeyEntry);
1208+
1209+
SecretKey entryKey = ((KeyStore.SecretKeyEntry)entry).getSecretKey();
1210+
isTrue("entry key not a PBEKey", entryKey instanceof javax.crypto.interfaces.PBEKey);
1211+
1212+
javax.crypto.interfaces.PBEKey ePbe = (javax.crypto.interfaces.PBEKey)entryKey;
1213+
isTrue("entry password mismatch", Arrays.areEqual(pwd, ePbe.getPassword()));
1214+
isTrue("entry salt mismatch", Arrays.areEqual(salt, ePbe.getSalt()));
1215+
isEquals(iterations, ePbe.getIterationCount());
1216+
12021217
// chain must be rejected
12031218
try
12041219
{

0 commit comments

Comments
 (0)