Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -363,20 +363,22 @@
<schemaInclude>bindings/schemas/exc-c14n.xsd</schemaInclude>
<schemaInclude>bindings/schemas/xmldsig-core-schema.xsd</schemaInclude>
<schemaInclude>bindings/schemas/xmldsig11-schema.xsd</schemaInclude>
<schemaInclude>bindings/schemas/dsig-more_2001_04.xsd</schemaInclude>
<schemaInclude>bindings/schemas/dsig-more_2007_05.xsd</schemaInclude>
<schemaInclude>bindings/schemas/dsig-more_2021_04.xsd</schemaInclude>
<schemaInclude>bindings/schemas/xenc-schema.xsd</schemaInclude>
<schemaInclude>bindings/schemas/xenc-schema-11.xsd</schemaInclude>
<schemaInclude>bindings/schemas/rsa-pss.xsd</schemaInclude>
</schemaIncludes>
<bindingDirectory>${basedir}/src/main/resources/bindings/</bindingDirectory>
<bindingIncludes>
<bindingInclude>c14n.xjb</bindingInclude>
<bindingInclude>dsig.xjb</bindingInclude>
<bindingInclude>dsig11.xjb</bindingInclude>
<bindingInclude>dsig-more.xjb</bindingInclude>
<bindingInclude>xenc.xjb</bindingInclude>
<bindingInclude>xenc11.xjb</bindingInclude>
<bindingInclude>security-config.xjb</bindingInclude>
<bindingInclude>xop.xjb</bindingInclude>
<bindingInclude>rsa-pss.xjb</bindingInclude>
</bindingIncludes>
<catalog>${basedir}/src/main/resources/bindings/bindings.cat</catalog>
<forceRegenerate>false</forceRegenerate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ public interface AgreementMethod {
*/
void setKANonce(byte[] kanonce);


/**
* Returns KeyDerivationMethod information used in the <code>AgreementMethod</code>.
* @return The KeyDerivationMethod information regarding the <code>AgreementMethod</code>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@

package org.apache.xml.security.encryption;

import org.apache.xml.security.encryption.keys.content.derivedKey.KDFParams;
import org.apache.xml.security.exceptions.XMLSecurityException;

/**
* The key derivation is to generate new cryptographic key material from existing key material such as the shared
* secret and any other (private or public) information. The purpose of the key derivation is an extension of a given
* but limited set of original key materials and to limit the use (exposure) of such key material.
* The key derivation is to generate new cryptographic key material from existing
* key material such as the shared secret and any other (private or public)
* information. The implementations of this interface provides XML serializing/deserializing
* of the: {@link org.apache.xml.security.encryption.params.KeyDerivationParameters} for
* various key derivation algorithms.
*
* The Schema for KeyDerivationMethod is as follows:
* <pre>
Expand All @@ -40,7 +45,19 @@ public interface KeyDerivationMethod {
/**
* Returns the algorithm URI of this <code>KeyDerivationMethod</code>.
*
* @return the algorithm URI of this <code>KeyDerivationMethod</code>
* @return the algorithm URI string
*/
String getAlgorithm();

/**
* Returns the KDF parameters used by the key derivation algorithm.
* Currently supported types are:
* {@link org.apache.xml.security.encryption.params.ConcatKDFParams} and
* {@link org.apache.xml.security.encryption.params.HKDFParams}.
*
* @return the KDFParams used by the key derivation algorithm
* @throws XMLSecurityException if the KDFParams cannot be created
*/
KDFParams getKDFParams() throws XMLSecurityException;

}
151 changes: 77 additions & 74 deletions src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,45 @@
*/
package org.apache.xml.security.encryption;

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.security.AccessController;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.PublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;

import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;

import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.encryption.keys.content.derivedKey.ConcatKDFParamsImpl;
import org.apache.xml.security.encryption.keys.content.derivedKey.HKDFParamsImpl;
import org.apache.xml.security.encryption.keys.content.derivedKey.KDFParams;
import org.apache.xml.security.encryption.params.ConcatKDFParams;
import org.apache.xml.security.encryption.params.HKDFParams;
import org.apache.xml.security.encryption.params.KeyAgreementParameters;
import org.apache.xml.security.encryption.params.KeyDerivationParameters;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.encryption.keys.content.derivedKey.ConcatKDFParamsImpl;
import org.apache.xml.security.encryption.keys.content.derivedKey.KeyDerivationMethodImpl;
import org.apache.xml.security.utils.EncryptionConstants;
import org.apache.xml.security.utils.KeyUtils;

import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.util.Base64;

public final class XMLCipherUtil {

private static final Logger LOG = System.getLogger(XMLCipherUtil.class.getName());

private static final boolean gcmUseIvParameterSpec =
AccessController.doPrivileged((PrivilegedAction<Boolean>)
() -> Boolean.getBoolean("org.apache.xml.security.cipher.gcm.useIvParameterSpec"));
AccessController.doPrivileged((PrivilegedAction<Boolean>)
() -> Boolean.getBoolean("org.apache.xml.security.cipher.gcm.useIvParameterSpec"));

/**
* Build an <code>AlgorithmParameterSpec</code> instance used to initialize a <code>Cipher</code> instance
* for block cipher encryption and decryption.
*
* @param algorithm the XML encryption algorithm URI
* @param iv the initialization vector
* @param iv the initialization vector
* @return the newly constructed AlgorithmParameterSpec instance, appropriate for the
* specified algorithm
* specified algorithm
*/
public static AlgorithmParameterSpec constructBlockCipherParameters(String algorithm, byte[] iv) {
if (EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM.equals(algorithm)
Expand Down Expand Up @@ -140,7 +139,7 @@ public static OAEPParameterSpec constructOAEPParameters(
public static MGF1ParameterSpec constructMGF1Parameter(String mgh1AlgorithmURI) {
LOG.log(Level.DEBUG, "Creating MGF1ParameterSpec for [{0}]", mgh1AlgorithmURI);
if (mgh1AlgorithmURI == null || mgh1AlgorithmURI.isEmpty()) {
LOG.log(Level.WARNING,"MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
LOG.log(Level.WARNING, "MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
return new MGF1ParameterSpec("SHA-1");
}

Expand Down Expand Up @@ -187,7 +186,6 @@ public static String getMgf1URIForParameter(MGF1ParameterSpec parameterSpec) {
}
}


/**
* Construct an KeyAgreementParameterSpec object from the given parameters
*
Expand Down Expand Up @@ -216,7 +214,8 @@ public static KeyAgreementParameters constructRecipientKeyAgreementParameters(St
/**
* Construct an KeyAgreementParameterSpec object from the given parameters
*
* @param agreementAlgorithmURI agreement algorithm
* @param agreementAlgorithmURI agreement algorithm URI
* @param actorType the actor type (originator or recipient)
* @param keyDerivationParameter key derivation parameters (e.g. ConcatKDFParams for ConcatKDF key derivation)
* @param keyAgreementPrivateKey private key to derive the shared secret in case of Diffie-Hellman key agreements
* @param keyAgreementPublicKey public key to derive the shared secret in case of Diffie-Hellman key agreements
Expand All @@ -229,7 +228,7 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
KeyAgreementParameters ecdhKeyAgreementParameters = new KeyAgreementParameters(
actorType,
agreementAlgorithmURI, keyDerivationParameter);
if (actorType == KeyAgreementParameters.ActorType.RECIPIENT ) {
if (actorType == KeyAgreementParameters.ActorType.RECIPIENT) {
ecdhKeyAgreementParameters.setRecipientPrivateKey(keyAgreementPrivateKey);
ecdhKeyAgreementParameters.setOriginatorPublicKey(keyAgreementPublicKey);
} else {
Expand All @@ -241,65 +240,69 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
}

/**
* Construct a KeyDerivationParameter object from the given keyDerivationMethod and keyBitLength
* Construct a KeyDerivationParameter object from the given keyDerivationMethod data
* and keyBitLength.
*
* @param keyDerivationMethod element to parse
* @param keyBitLength expected derived key length
* @return KeyDerivationParameter object
* @throws XMLSecurityException if the keyDerivationMethod is not supported
* @param keyDerivationMethod element with the key derivation method data
* @param keyBitLength expected derived key length in bits
* @return KeyDerivationParameters data
* @throws XMLEncryptionException if KDFParams cannot be created or the
* KDF URI is not supported or the key derivation parameters are invalid
*/
public static KeyDerivationParameters constructKeyDerivationParameter(KeyDerivationMethod keyDerivationMethod, int keyBitLength) throws XMLSecurityException {
public static KeyDerivationParameters constructKeyDerivationParameter(KeyDerivationMethod keyDerivationMethod,
int keyBitLength) throws XMLEncryptionException {
String keyDerivationAlgorithm = keyDerivationMethod.getAlgorithm();
if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
throw new XMLEncryptionException("unknownAlgorithm", keyDerivationAlgorithm);
KDFParams kdfParams;
try {
kdfParams = keyDerivationMethod.getKDFParams();
} catch (XMLSecurityException e) {
throw new XMLEncryptionException(e);
}
ConcatKDFParamsImpl concatKDFParams = ((KeyDerivationMethodImpl) keyDerivationMethod).getConcatKDFParams();

return constructConcatKeyDerivationParameter(keyBitLength, concatKDFParams.getDigestMethod(), concatKDFParams.getAlgorithmId(),
concatKDFParams.getPartyUInfo(), concatKDFParams.getPartyVInfo(),
concatKDFParams.getSuppPubInfo(),concatKDFParams.getSuppPrivInfo());

}

if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
if (!(kdfParams instanceof ConcatKDFParamsImpl)) {
throw new XMLEncryptionException("KeyDerivation.InvalidParametersType", keyDerivationAlgorithm, ConcatKDFParamsImpl.class.getName());
}
ConcatKDFParamsImpl concatKDFParams = (ConcatKDFParamsImpl) kdfParams;
return ConcatKDFParams.createBuilder(keyBitLength, concatKDFParams.getDigestMethod())
.algorithmID(concatKDFParams.getAlgorithmId())
.partyUInfo(concatKDFParams.getPartyUInfo())
.partyVInfo(concatKDFParams.getPartyVInfo())
.suppPubInfo(concatKDFParams.getSuppPubInfo())
.suppPrivInfo(concatKDFParams.getSuppPrivInfo())
.build();

/**
* Construct a ConcatKeyDerivationParameter object from the key length and digest method.
*
* @param keyBitLength expected derived key length
* @param digestMethod digest method
* @return ConcatKeyDerivationParameter object
*/
public static ConcatKDFParams constructConcatKeyDerivationParameter(int keyBitLength,
String digestMethod){
return constructConcatKeyDerivationParameter(keyBitLength, digestMethod, null, null, null, null, null);
} else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(keyDerivationAlgorithm)) {
if (!(kdfParams instanceof HKDFParamsImpl)) {
throw new XMLEncryptionException("KeyDerivation.InvalidParametersType", keyDerivationAlgorithm, HKDFParamsImpl.class.getName());
}
HKDFParamsImpl hKDFParams = (HKDFParamsImpl) kdfParams;
return HKDFParams.createBuilder(keyBitLength, hKDFParams.getPRFAlgorithm())
.salt(hKDFParams.getSalt() != null ? Base64.getDecoder().decode(hKDFParams.getSalt()) : null)
.info(hKDFParams.getInfo() != null ? Base64.getDecoder().decode(hKDFParams.getInfo()) : null)
.build();
}
throw new XMLEncryptionException("unknownAlgorithm", keyDerivationAlgorithm);
}

/**
* Construct a ConcatKeyDerivationParameter object from the given parameters
* Method hexStringToByteArray converts hex string to byte array.
*
* @param keyBitLength expected derived key length
* @param digestMethod digest method
* @param algorithmId algorithm id
* @param partyUInfo partyUInfo
* @param partyVInfo partyVInfo
* @param suppPubInfo suppPubInfo
* @param suppPrivInfo suppPrivInfo
* @return ConcatKeyDerivationParameter object
* @param hexString the hex string to convert
* @return the byte array of the input param, empty array if the hex string is empty, or null if input param is null
*/
public static ConcatKDFParams constructConcatKeyDerivationParameter(int keyBitLength,
String digestMethod,
String algorithmId,
String partyUInfo,
String partyVInfo,
String suppPubInfo,
String suppPrivInfo) {

ConcatKDFParams kdp = new ConcatKDFParams(keyBitLength, digestMethod);
kdp.setAlgorithmID(algorithmId);
kdp.setPartyUInfo(partyUInfo);
kdp.setPartyVInfo(partyVInfo);
kdp.setSuppPubInfo(suppPubInfo);
kdp.setSuppPrivInfo(suppPrivInfo);
return kdp;
public static byte[] hexStringToByteArray(String hexString) {
if (hexString == null){
return null;
}
if (hexString.isEmpty()) {
return new byte[0];
}
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ Character.digit(hexString.charAt(i+1), 16));
}
return data;
}
}
Loading