jrihtarsic commented on code in PR #234:
URL:
https://github.com/apache/santuario-xml-security-java/pull/234#discussion_r1428745838
##########
src/main/java/org/apache/xml/security/encryption/XMLCipher.java:
##########
@@ -1500,42 +1542,77 @@ public Key decryptKey(EncryptedKey encryptedKey, String
algorithm)
}
/**
- * Construct an OAEPParameterSpec object from the given parameters
+ * Method validates and updates if needed the KeyAgreementParameterSpec
with the required keys.
+ *
+ * @param keyAgreementParameter KeyAgreementParameterSpec to be validated
and updated
+ * with the required keys if needed
*/
- private OAEPParameterSpec constructOAEPParameters(
- String encryptionAlgorithm,
- String digestAlgorithm,
- String mgfAlgorithm,
- byte[] oaepParams
- ) {
- if (XMLCipher.RSA_OAEP.equals(encryptionAlgorithm)
- || XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
-
- String jceDigestAlgorithm = "SHA-1";
- if (digestAlgorithm != null) {
- jceDigestAlgorithm =
JCEMapper.translateURItoJCEID(digestAlgorithm);
+ public void
validateAndUpdateKeyAgreementParameterKeys(KeyAgreementParameterSpec
keyAgreementParameter) throws XMLEncryptionException {
+ if (keyAgreementParameter == null) {
+ return;
+ }
+ // check if the recipient's public key is set in
keyAgreementParameter, if not, use the recipient's public key
+ // specified in XMLCipher instance init method.
+ if (keyAgreementParameter.getRecipientPublicKey() == null && this.key
!= null) {
+ if (this.key instanceof PublicKey) {
+ LOG.log(Level.DEBUG, "Recipient's public key is not set in
keyAgreementParameter, " +
+ "use the recipient's public key specified in XMLCipher
instance init method.");
+ keyAgreementParameter.setRecipientPublicKey((PublicKey)
this.key);
+ } else {
+ throw new
XMLEncryptionException("algorithms.WrongKeyForThisOperation",
+ this.key.getClass().getName(),
"java.security.PublicKey");
}
+ }
- PSource.PSpecified pSource = PSource.PSpecified.DEFAULT;
- if (oaepParams != null) {
- pSource = new PSource.PSpecified(oaepParams);
- }
+ // check if the originator's private key is still null
+ if (keyAgreementParameter.getRecipientPublicKey() == null) {
+ // recipient's public key is mandatory for key agreement algorithm.
+ throw new XMLEncryptionException("encryption.nokey");
+ }
- MGF1ParameterSpec mgfParameterSpec = new
MGF1ParameterSpec("SHA-1");
- if (XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
- if (EncryptionConstants.MGF1_SHA224.equals(mgfAlgorithm)) {
- mgfParameterSpec = new MGF1ParameterSpec("SHA-224");
- } else if
(EncryptionConstants.MGF1_SHA256.equals(mgfAlgorithm)) {
- mgfParameterSpec = new MGF1ParameterSpec("SHA-256");
- } else if
(EncryptionConstants.MGF1_SHA384.equals(mgfAlgorithm)) {
- mgfParameterSpec = new MGF1ParameterSpec("SHA-384");
- } else if
(EncryptionConstants.MGF1_SHA512.equals(mgfAlgorithm)) {
- mgfParameterSpec = new MGF1ParameterSpec("SHA-512");
- }
- }
- return new OAEPParameterSpec(jceDigestAlgorithm, "MGF1",
mgfParameterSpec, pSource);
+ if (keyAgreementParameter.getOriginatorPrivateKey() == null) {
+ LOG.log(Level.DEBUG, "Originator's private key is not set in
keyAgreementParameter, " +
+ "generate an ephemeral key for the originator's private
key.");
+ KeyPair originatorKeyPair = KeyUtils.generateEphemeralDHKeyPair(
+ keyAgreementParameter.getRecipientPublicKey(), null);
+ keyAgreementParameter.setOriginatorKeyPair(originatorKeyPair);
}
+ }
+ /**
+ * Method resolves the EncryptedKey using the EncryptedKeyResolver
+ *
+ * @param encryptedKey
+ * @return
+ * @throws XMLEncryptionException
+ */
+ private AlgorithmParameterSpec getAlgorithmParameters(EncryptedKey
encryptedKey) throws XMLSecurityException {
+ if (encryptedKey == null
+ || encryptedKey.getEncryptionMethod() == null
+ || encryptedKey.getEncryptionMethod().getAlgorithm() == null) {
+ LOG.log(Level.DEBUG,"EncryptedKey key algorithm is null");
+ return null;
+ }
+
+ EncryptionMethod encMethod = encryptedKey.getEncryptionMethod();
+ String encryptionAlgorithm = encMethod.getAlgorithm();
+
+ if (XMLCipher.RSA_OAEP.equals(encryptionAlgorithm)
+ || XMLCipher.RSA_OAEP_11.equals(encryptionAlgorithm)) {
+ LOG.log(Level.DEBUG,"EncryptedKey key algorithm is RSA OAEP");
+ return XMLCipherUtil.constructOAEPParameters(
+ encryptionAlgorithm, encMethod.getDigestAlgorithm(),
+ encMethod.getMGFAlgorithm(), encMethod.getOAEPparams());
+ }
+
+ KeyInfoEnc keyInfo = encryptedKey.getKeyInfo() instanceof KeyInfoEnc ?
(KeyInfoEnc) encryptedKey.getKeyInfo(): null;
+ if (keyInfo != null && keyInfo.containsAgreementMethod()) {
+ // resolve the agreement method
+ LOG.log(Level.DEBUG,"EncryptedKey key is using Key agreement
data");
+ AgreementMethod agreementMethod = keyInfo.itemAgreementMethod(0);
+ return
XMLCipherUtil.constructRecipientKeyAgreementParameters(encryptionAlgorithm,
+ agreementMethod, (PrivateKey) this.key);
+ }
return null;
Review Comment:
I don't think an error should be thrown there because it would change the
existing behavior of the code.
The method getAlgorithmParameters
is a generic substitute of the constructOAEPParameters
see the:
https://github.com/apache/santuario-xml-security-java/blob/main/src/main/java/org/apache/xml/security/encryption/XMLCipher.java#L1373
where I added the option to construct the KeyAgreementParameters.
Throwing an error would change the behavior of the method
XMLCipher.decryptKey(EncryptedKey encryptedKey, String algorithm)
and would break decryption for Encryption algorithms where additional
parameters are not needed.
In the case of encryption algorithms where parameters are mandatory, the
relevant exceptions are thrown in the particular method that constructs the
parameters, as example in the:
XMLCipherUtil.constructRecipientKeyAgreementParameters
Regarding if the algorithm is not recognized or supported :
A basic validation is already performed at cipher configuration phase
XMLCipher.constructCipher
within the methods:
String jceAlgorithm = JCEMapper.translateURItoJCEID(algorithm)
...
c = Cipher.getInstance(jceAlgorithm)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]