-
Notifications
You must be signed in to change notification settings - Fork 18
Fix key compatibility problem in XDHKeyAgreement #723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Is there an issue to look at for this? This seems like a very normal issue for ANY key that comes from a different provider than the one that key is being used with. I do no think this issue is only for these keys. |
Yes, there is an issue that the PR addresses (https://github.ibm.com/runtimes/jit-crypto/issues/839). |
Okay so the issue is that the key that was passed into the OpenJCEPlus provider was created by the SUN provider. I doubt the test was meant to cross test providers. Meaning that a key was created by one provider and than passed to another provider to verify compatibility and function. This sounds like a test case issue or a test set up issue. Please check the test case and determine why the key was created by the SUN provider and not the OpenJCEPlus provider. Since, this test was for XDHKeyAgreement I would have expected ALL keys to be created by the same provider or at least all operations including key creation to be done separately on each side. |
I looked into the test case and you are correct, the test was not meant to cross test providers. When it gets key pair (link), the function |
Are you sure this is a JCK test? If it is try adding OpenJCEPlus first in the provider list and rerun the test. |
I tried adding |
Interesting but I guess not surprising since the issues you show indicate that the failure is in the Native code version of SunEC. The actual code for this version of the SunEC provider does not seem to have been open sourced. So we can not determine what the SunEC code was looking for in order for this to work. Now, if you put OpenJCEPlus last in the list and add code to do the translate that will only fix that scenario. The real thing we want to do is to put OpenJCEPlus first in the list and have the JCK work. However, doing that will cause the at least the Native SunEC provider to have issues with the keys from OpenJCEPlus. Therefore, I think the best thing to do for this issue is to go back to Oracle to have them remove the test for now and to correct it in the future. @jasonkatonica Lets discuss this when you return from vacation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code is fine.
However, we need an interop test case to be created to verify that this code is working as expected.
Also, I want to voice comcern, Doing this can set an expectation that all operations in OpenJCEPlus have a similar feature. So, if we do this here. We should probably do this for ALL operations: Key Agreement, signnatures, Ciphers, etc.
968f950
to
683feb6
Compare
} catch (ClassCastException cce) { | ||
throw new InvalidKeyException("Key is not an instance of XDHPublicKeyImpl", cce); | ||
} catch (Exception exception) { | ||
throw new InvalidKeyException("KeyFactory is not working as expected", exception); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we could come up with an exception message here that is more generalized such as Unable to translate key
. Only reason I am thinking that is that the message is a bit deceiving since at this point we dont know if the key was an unknown / incorrect format or class OR the KeyFactory simply could not translate the key. This could be working as expected in those cases.
} catch (ClassCastException cce) { | ||
throw new InvalidKeyException("Key is not an instance of XDHPrivateKeyImpl", cce); | ||
} catch (Exception exception) { | ||
throw new InvalidKeyException("KeyFactory is not working as expected", exception); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment as above.
The tests also seem to be failing in the associated CI pipeline :
|
It is also strange that all platforms are failing EXCEPT for AIX which is not expected. |
This might be failing due to the interop problem on the Sun side. The |
try { | ||
key = (XDHPublicKeyImpl) XDHKeyFactory.toXECKey(this.provider, this.alg, key); | ||
} catch (ClassCastException cce) { | ||
throw new InvalidKeyException("Key is not an instance of XDHPublicKeyImpl", cce); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear in this exception message which key is not an instance of XDHPublicKeyImpl
. It sounds as if the user provided key has an issue, when it's the one produced by the factory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no KeyFactory involved here. In this code it has not idea what has or has not been done to the key. It is just making sure that the passed in key is what it expects.
try { | ||
key = (XDHPrivateKeyImpl) XDHKeyFactory.toXECKey(this.provider, this.alg, key); | ||
} catch (ClassCastException cce) { | ||
throw new InvalidKeyException("Key is not an instance of XDHPrivateKeyImpl", cce); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
KeyPair kp1 = kpg1.generateKeyPair(); | ||
KeyPair kp2 = kpg2.generateKeyPair(); | ||
|
||
ka1.init(kp1.getPrivate()); | ||
ka1.doPhase(kp2.getPublic(), true); | ||
|
||
ka2.init(kp2.getPrivate()); | ||
ka2.doPhase(kp1.getPublic(), true); | ||
|
||
byte[] ss1 = ka1.generateSecret(); | ||
byte[] ss2 = ka2.generateSecret(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add some more combinations. In the ones you have now the KeyAgreement instance and private key are always coming from the same provider. I think we should try the inverse too where the private key comes from the other provider.
Update XDHKeyAgreement to handle different providers using XDHKeyFactory. Signed-off-by: Dev Agarwal <[email protected]>
683feb6
to
57cd8d1
Compare
The KeyAgreement test was failing because the key passed in the parameter was an instance of
Sun
. Resolved by usingXDHKeyFactory
for private and public keys passed as parameters inengineInit()
andengineDoPhase()
. Added a check to throwInvalidKeyException
when the key is not an instance ofXECPrivateKey
orXECPublicKey
as required.Consistency is also ensured between the two function with respect to the order that the checks are taking place.