core icon indicating copy to clipboard operation
core copied to clipboard

Keys from keystore do not work

Open grthor opened this issue 3 years ago • 2 comments

In the algorithms perspective, the keys supplied from the keystore do not work. The algorithms themselves work. You can test this by creating a new key and executing the algorithm. With a newly created key, the algorithms work.

If you restart the JCT with the newly created key, the new key will also no longer work. The same error message appears as with the keys from the keystore.

!ENTRY org.jcryptool.core.logging 4 0 2021-04-16 09:03:33.760
!MESSAGE unknown object in getInstance: org.bouncycastle.asn1.DERNull
!STACK 0
java.lang.IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.DERNull
	at org.bouncycastle.asn1.ASN1Sequence.getInstance(ASN1Sequence.java:105)
	at org.bouncycastle.asn1.oiw.ElGamalParameter.getInstance(Unknown Source)
	at org.bouncycastle.jcajce.provider.asymmetric.elgamal.BCElGamalPublicKey.<init>(Unknown Source)
	at org.bouncycastle.jcajce.provider.asymmetric.elgamal.KeyFactorySpi.generatePublic(Unknown Source)
	at org.bouncycastle.jce.provider.BouncyCastleProvider.getPublicKey(BouncyCastleProvider.java:347)
	at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateImpl.getPublicKey(Unknown Source)
	at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject.getPublicKey(Unknown Source)
	at java.base/java.security.KeyStore$PrivateKeyEntry.<init>(KeyStore.java:556)
	at java.base/java.security.KeyStore$PrivateKeyEntry.<init>(KeyStore.java:506)
	at java.base/java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:497)
	at java.base/java.security.KeyStore.getEntry(KeyStore.java:1555)
	at org.jcryptool.crypto.keystore.backend.KeyStoreManager.getPrivateKey(KeyStoreManager.java:454)
        ...

I traced the problem and found a (probably) broken certificate chain. The certificate chain seems to break when saving or loading the keystore. The following text is an example of a certificate chain before and after saving:

Before saving (working):

[X.509 Certificate {TBS Certificate {
X509 certificate V3
serial number:Integer 0
signature algorithm:X.509 AlgorithmIdentifier 0.0
issuer:CN=JCrypTool, C=Germany, ST=Hessen, L=Frankfurt, O=JCrypTool.org, OU=JCrypTool Core
subject:CN=JCrypTool, C=Germany, ST=Hessen, L=Frankfurt, O=JCrypTool.org, OU=JCrypTool Core
validity:UTCTime "991231230000Z" - UTCTime "491230230000Z"
subject public key algorithm:X.509 AlgorithmIdentifier 1.3.14.7.2.1.1 (ELGAMAL)
subject public key:
modulus  : 0xd483124ecc898119ef81ad966083a2a9a5c902ae38ad6425077f2164e285e0b7f3ae10373f407fcf46bddfeda9f52e031200d18485031b28c6de10bda2616ae39e3fb04a48d011d293d4bac70b3c505dca302411e5598445024ab593ed52a66866b9dcaafb6ad2fa97ac1b5131d92abc1e455369bc2598a9b2315597c4274557
generator: 0x650250509de2ee45c0a29f66477d02124f623f1105619770fd5a8dec3bd4cf69836944d12d6d77c475e14af013beda03b79aeb21314216f546315d001e86090baf7a4d608553c592a56957f395ca5808cc0cf7f42d11ae3ef201085c479ba1aa7ffba3a6b227dcfa9d34727a7cade466d811ce697d2f7a24481f1af74b5a2573
public A : 0x45d7606b0577659ef710a5e126b6930d672ff8686d74806871994ad6060f81d99db7191baf75542fbef069e83ee28874f0ab2965fc4182c7a415f570be2bb50ff2275c693c91871d8d124ecd561f93a8a1e3fcd1bf1f45dda07c9be2e9c6f87fc2b163830d93f105cf89cbaf975912ff9ded4c37854d505e4974156102c21253

(V3)extensions (1)
 1:Extension 2.5.29.15 (CRITICAL) Value=BitString '0011'

signature:
BitString '']

After loading (broken):

[  [0]         Version: 3
         SerialNumber: 0
             IssuerDN: OU=JCrypTool Core,O=JCrypTool.org,L=Frankfurt,ST=Hessen,C=Germany,CN=JCrypTool
           Start Date: Sat Jan 01 00:00:00 CET 2000
           Final Date: Fri Dec 31 00:00:00 CET 2049
            SubjectDN: OU=JCrypTool Core,O=JCrypTool.org,L=Frankfurt,ST=Hessen,C=Germany,CN=JCrypTool
           Public Key: null
  Signature Algorithm: 0.0
            Signature: 
       Extensions: 
                       critical(true) KeyUsage: 0x30
]

The broken certificate chain will be most likely the problem why the provided keys from the keystore do not work.

My starting point is currently to track whether saving or loading is the problem.

grthor avatar Apr 16 '21 07:04 grthor

Some of my thoughts while looking at this:

  • the class from the log: DERNull -- exists. Originally I hypothesized that it would be a classname compositing mechanism that maybe would append org.bouncycastle.asn1.DER + {Encoder,Decoder,...} and have a String that evaluates to Null for the hind part.
  • Second hypothesis is, that the keystore loading code lacks the bouncycastle crypto provider in its context, i.e.
import org.jcryptool.core.operations.providers.ProviderManager2;
try {
    getInstance().pushFlexiProviderPromotion();
    your.code();
} finally {
    getInstance().popCryptoProviderPromotion();
}

see #224, https://github.com/jcryptool/core/commit/2ca1760287d845d94274412d73a09a01d8283c9a

  • Third hypothesis is that maybe in-memory keys (created while running JCT) work because they are created by another plug-in where the dependency to org.bouncycastle in the MANIFEST.MF is properly declared. De-serializing objects from a file however -- late-binding classname to constructors at run-time -- as done while reading .ksf files is not checked by Java+Eclipse+OSGi classpath mechanisms. It may be possible that the invoking plugin (org.jcryptool.crypto.keystore.backend) just needs Require-Bundle: org.bouncycastle.

If I were to check these, I'd start with the third as it's the least labor-intensive.

simlei avatar Apr 16 '21 08:04 simlei

I have investigated the problem further and have come to the following results:

  • Solution 3, the missing requirements, is unfortunately not. I have added bcprov and bcpkix to all Flexiprovider plugins. This did not change or fix the error.
  • The problem is more specific than "All keys from the keystore do not work". All keys created with the Flexiprovider do not work. Keys created with Bouncycastle work, but not in the Algorithm perspective. The reason for this is a cast in the logic of the algorithm perspective. The cast only works for flexiprovider keys. For bouncycastle a class cast exception occurs. This is the problematic cast: https://github.com/jcryptool/core/blob/e2a3c3de98820b2c329ab34b9981be9c3f363331/org.jcryptool.crypto.flexiprovider.engines/src/org/jcryptool/crypto/flexiprovider/engines/cipher/AsymmetricBlockCipherEngine.java#L47 The code casts a key, no matter which type (flexiprovider, bouncycastle, sun), to a flexiprovider key. This is simply not possible, since the different types do not implement/subclass the same interface/class. The problem described in this issue refers only to keys created with the flexiprovider.

grthor avatar May 03 '21 17:05 grthor