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]

Reply via email to