Skip to content

Commit 0c7655f

Browse files
committed
Added additional crypt parameter configuration
1 parent aee30ab commit 0c7655f

File tree

6 files changed

+408
-39
lines changed

6 files changed

+408
-39
lines changed

phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptParams.java

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ public class AS4CryptParams implements ICloneable <AS4CryptParams>
5656
public static final ICryptoSessionKeyProvider DEFAULT_SESSION_KEY_PROVIDER = ICryptoSessionKeyProvider.INSTANCE_RANDOM_AES_128;
5757
public static final boolean DEFAULT_ENCRYPT_SYMMETRIC_SESSION_KEY = true;
5858

59+
/**
60+
* HKDF PRF algorithm URI for HMAC-SHA256, as required by eDelivery AS4 2.0
61+
*
62+
* @since 4.4.0
63+
*/
64+
public static final String HKDF_PRF_HMAC_SHA256 = WSS4JConstants.HMAC_SHA256;
65+
5966
private static final Logger LOGGER = Phase4LoggerFactory.getLogger (AS4CryptParams.class);
6067

6168
// The key identifier type to use
@@ -68,6 +75,14 @@ public class AS4CryptParams implements ICloneable <AS4CryptParams>
6875
private String m_sMGFAlgorithm = DEFAULT_MGF_ALGORITHM;
6976
// The digest algorithm to use with the RSA-OAEP key transport algorithm
7077
private String m_sDigestAlgorithm = DEFAULT_DIGEST_ALGORITHM;
78+
// Key agreement method (e.g. X25519, X448, ECDH-ES) - null means no key
79+
// agreement (use key transport instead)
80+
private ECryptoKeyAgreementMethod m_eKeyAgreementMethod;
81+
// Key derivation function (e.g. HKDF, ConcatKDF) - only used with key
82+
// agreement
83+
private ECryptoKeyDerivationMethod m_eKeyDerivationMethod;
84+
// Key wrap algorithm (e.g. AES-128 KeyWrap) - only used with key agreement
85+
private ECryptoKeyWrapAlgorithm m_eKeyWrapAlgorithm;
7186
// The explicit certificate to use - has precedence over the alias
7287
private X509Certificate m_aCert;
7388
// The alias into the WSS4J crypto config
@@ -220,6 +235,121 @@ public final AS4CryptParams setDigestAlgorithm (@NonNull @Nonempty final String
220235
return this;
221236
}
222237

238+
/**
239+
* @return The key agreement method to use. May be <code>null</code>, in which case key transport
240+
* (e.g. RSA-OAEP) is used instead of key agreement.
241+
* @since 4.4.0
242+
*/
243+
@Nullable
244+
public final ECryptoKeyAgreementMethod getKeyAgreementMethod ()
245+
{
246+
return m_eKeyAgreementMethod;
247+
}
248+
249+
/**
250+
* @return <code>true</code> if a key agreement method is set, <code>false</code> if not.
251+
* @since 4.4.0
252+
*/
253+
public final boolean hasKeyAgreementMethod ()
254+
{
255+
return m_eKeyAgreementMethod != null;
256+
}
257+
258+
/**
259+
* Set the key agreement method to use. When set, the encryption will use key agreement (e.g.
260+
* ECDH-ES, X25519) instead of key transport (e.g. RSA-OAEP). If set to <code>null</code>, key
261+
* transport is used.
262+
*
263+
* @param eKeyAgreementMethod
264+
* The key agreement method. May be <code>null</code>.
265+
* @return this for chaining
266+
* @since 4.4.0
267+
*/
268+
@NonNull
269+
public final AS4CryptParams setKeyAgreementMethod (@Nullable final ECryptoKeyAgreementMethod eKeyAgreementMethod)
270+
{
271+
m_eKeyAgreementMethod = eKeyAgreementMethod;
272+
return this;
273+
}
274+
275+
/**
276+
* @return The key derivation function to use with key agreement. May be <code>null</code>.
277+
* @since 4.4.0
278+
*/
279+
@Nullable
280+
public final ECryptoKeyDerivationMethod getKeyDerivationMethod ()
281+
{
282+
return m_eKeyDerivationMethod;
283+
}
284+
285+
/**
286+
* Set the key derivation function to use with key agreement (e.g. HKDF, ConcatKDF).
287+
*
288+
* @param eKeyDerivationMethod
289+
* The key derivation method. May be <code>null</code>.
290+
* @return this for chaining
291+
* @since 4.4.0
292+
*/
293+
@NonNull
294+
public final AS4CryptParams setKeyDerivationMethod (@Nullable final ECryptoKeyDerivationMethod eKeyDerivationMethod)
295+
{
296+
m_eKeyDerivationMethod = eKeyDerivationMethod;
297+
return this;
298+
}
299+
300+
/**
301+
* @return The key wrap algorithm to use with key agreement. May be <code>null</code>.
302+
* @since 4.4.0
303+
*/
304+
@Nullable
305+
public final ECryptoKeyWrapAlgorithm getKeyWrapAlgorithm ()
306+
{
307+
return m_eKeyWrapAlgorithm;
308+
}
309+
310+
/**
311+
* Set the key wrap algorithm to use with key agreement (e.g. AES-128 KeyWrap).
312+
*
313+
* @param eKeyWrapAlgorithm
314+
* The key wrap algorithm. May be <code>null</code>.
315+
* @return this for chaining
316+
* @since 4.4.0
317+
*/
318+
@NonNull
319+
public final AS4CryptParams setKeyWrapAlgorithm (@Nullable final ECryptoKeyWrapAlgorithm eKeyWrapAlgorithm)
320+
{
321+
m_eKeyWrapAlgorithm = eKeyWrapAlgorithm;
322+
return this;
323+
}
324+
325+
/**
326+
* Convenience method to set all parameters required for eDelivery AS4 2.0 EdDSA/X25519 key
327+
* agreement: X25519 key agreement, HKDF key derivation, AES-128 key wrap.
328+
*
329+
* @return this for chaining
330+
* @since 4.4.0
331+
*/
332+
@NonNull
333+
public final AS4CryptParams setEDelivery2KeyAgreementX25519 ()
334+
{
335+
return setKeyAgreementMethod (ECryptoKeyAgreementMethod.X25519).setKeyDerivationMethod (ECryptoKeyDerivationMethod.HKDF)
336+
.setKeyWrapAlgorithm (ECryptoKeyWrapAlgorithm.AES_128);
337+
}
338+
339+
/**
340+
* Convenience method to set all parameters required for eDelivery AS4 2.0 ECDSA/ECDH-ES key
341+
* agreement: ECDH-ES key agreement, HKDF key derivation, AES-128 key wrap.
342+
*
343+
* @return this for chaining
344+
* @since 4.4.0
345+
*/
346+
@NonNull
347+
public final AS4CryptParams setEDelivery2KeyAgreementECDHES ()
348+
{
349+
return setKeyAgreementMethod (ECryptoKeyAgreementMethod.ECDH_ES).setKeyDerivationMethod (ECryptoKeyDerivationMethod.HKDF)
350+
.setKeyWrapAlgorithm (ECryptoKeyWrapAlgorithm.AES_128);
351+
}
352+
223353
/**
224354
* @return The currently set X509 certificate. May be <code>null</code>.
225355
*/
@@ -462,6 +592,9 @@ public void cloneTo (@NonNull final AS4CryptParams aTarget)
462592
.setKeyEncAlgorithm (m_eKeyEncAlgorithm)
463593
.setMGFAlgorithm (m_sMGFAlgorithm)
464594
.setDigestAlgorithm (m_sDigestAlgorithm)
595+
.setKeyAgreementMethod (m_eKeyAgreementMethod)
596+
.setKeyDerivationMethod (m_eKeyDerivationMethod)
597+
.setKeyWrapAlgorithm (m_eKeyWrapAlgorithm)
465598
.setCertificate (m_aCert)
466599
.setAlias (m_sAlias)
467600
.setSessionKeyProvider (m_aSessionKeyProvider)
@@ -488,6 +621,9 @@ public String toString ()
488621
.append ("KeyEncAlgorithm", m_eKeyEncAlgorithm)
489622
.append ("MGFAlgorithm", m_sMGFAlgorithm)
490623
.append ("DigestAlgorithm", m_sDigestAlgorithm)
624+
.appendIfNotNull ("KeyAgreementMethod", m_eKeyAgreementMethod)
625+
.appendIfNotNull ("KeyDerivationMethod", m_eKeyDerivationMethod)
626+
.appendIfNotNull ("KeyWrapAlgorithm", m_eKeyWrapAlgorithm)
491627
.append ("Certificate", m_aCert)
492628
.append ("Alias", m_sAlias)
493629
.append ("SessionKeyProvider", m_aSessionKeyProvider)

phase4-lib/src/main/java/com/helger/phase4/crypto/AS4CryptoFactoryConfiguration.java

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,10 @@
3838
import com.helger.security.keystore.LoadedKeyStore;
3939

4040
/**
41-
* phase4 crypto factory settings based on {@link IConfig}. The configuration
42-
* elements are solely taken from the global configuration and not from
43-
* arbitrary files. Multiple different crypto factory configurations can be
44-
* handled uses different configuration property prefixes. This class only
45-
* supports {@link Merlin} as the crypto implementation.
41+
* phase4 crypto factory settings based on {@link IConfig}. The configuration elements are solely
42+
* taken from the global configuration and not from arbitrary files. Multiple different crypto
43+
* factory configurations can be handled uses different configuration property prefixes. This class
44+
* only supports {@link Merlin} as the crypto implementation.
4645
*
4746
* @author Philip Helger
4847
* @since 3.0.0
@@ -53,9 +52,8 @@ public class AS4CryptoFactoryConfiguration extends AS4CryptoFactoryInMemoryKeySt
5352
private static final Logger LOGGER = Phase4LoggerFactory.getLogger (AS4CryptoFactoryConfiguration.class);
5453

5554
/**
56-
* @return The default instance, created by reading the default properties
57-
* from the configuration sources (application.properties, environment
58-
* variables and Java system properties).
55+
* @return The default instance, created by reading the default properties from the configuration
56+
* sources (application.properties, environment variables and Java system properties).
5957
* @throws Phase4RuntimeException
6058
* if one of the mandatory configuration parameters is not present.
6159
*/
@@ -68,8 +66,8 @@ public static AS4CryptoFactoryConfiguration getDefaultInstance () throws Phase4R
6866
}
6967

7068
/**
71-
* Same as {@link #getDefaultInstance()} just that it returns
72-
* <code>null</code> instead of throwing a RuntimeException.
69+
* Same as {@link #getDefaultInstance()} just that it returns <code>null</code> instead of
70+
* throwing a RuntimeException.
7371
*
7472
* @return <code>null</code> in case of error.
7573
*/
@@ -93,8 +91,8 @@ public static AS4CryptoFactoryConfiguration getDefaultInstanceOrNull ()
9391
private final ITrustStoreDescriptor m_aTrustStorDesc;
9492

9593
/**
96-
* This constructor takes the configuration object and uses the default prefix
97-
* for backwards compatibility. This is kind of the default constructor.
94+
* This constructor takes the configuration object and uses the default prefix for backwards
95+
* compatibility. This is kind of the default constructor.
9896
*
9997
* @param aConfig
10098
* The configuration object to be used. May not be <code>null</code>.
@@ -175,14 +173,14 @@ private static ITrustStoreDescriptor _loadTrustStore (@NonNull final IConfigWith
175173
}
176174

177175
/**
178-
* This constructor takes the configuration object and uses the provided
179-
* configuration prefix. This is kind of the default constructor.
176+
* This constructor takes the configuration object and uses the provided configuration prefix.
177+
* This is kind of the default constructor.
180178
*
181179
* @param aConfig
182180
* The configuration object to be used. May not be <code>null</code>.
183181
* @param sConfigPrefix
184-
* The configuration prefix to be used. May neither be
185-
* <code>null</code> nor empty and must end with a dot ('.').
182+
* The configuration prefix to be used. May neither be <code>null</code> nor empty and must
183+
* end with a dot ('.').
186184
* @throws Phase4RuntimeException
187185
* If loading the key store configuration from configuration fails.
188186
*/
@@ -194,14 +192,14 @@ public AS4CryptoFactoryConfiguration (@NonNull final IConfigWithFallback aConfig
194192
}
195193

196194
/**
197-
* This constructor takes the configuration object and uses the provided
198-
* configuration prefix. This is kind of the default constructor.
195+
* This constructor takes the configuration object and uses the provided configuration prefix.
196+
* This is kind of the default constructor.
199197
*
200198
* @param aConfig
201199
* The configuration object to be used. May not be <code>null</code>.
202200
* @param sConfigPrefix
203-
* The configuration prefix to be used. May neither be
204-
* <code>null</code> nor empty and must end with a dot ('.').
201+
* The configuration prefix to be used. May neither be <code>null</code> nor empty and must
202+
* end with a dot ('.').
205203
* @param bLogError
206204
* <code>true</code> if errors should be logged if loading fails.
207205
* @throws Phase4RuntimeException
@@ -220,8 +218,8 @@ public AS4CryptoFactoryConfiguration (@NonNull final IConfigWithFallback aConfig
220218
* @param aKeyStoreDesc
221219
* The key store descriptor. May not be <code>null</code>.
222220
* @param aTrustStoreDesc
223-
* The trust store descriptor. May be <code>null</code> in which case
224-
* the global JRE CA certs list will be used.
221+
* The trust store descriptor. May be <code>null</code> in which case the global JRE CA
222+
* certs list will be used.
225223
*/
226224
private AS4CryptoFactoryConfiguration (@NonNull final IKeyStoreAndKeyDescriptor aKeyStoreDesc,
227225
@Nullable final ITrustStoreDescriptor aTrustStoreDesc)
@@ -241,8 +239,7 @@ public IKeyStoreAndKeyDescriptor getKeyStoreDescriptor ()
241239
}
242240

243241
/**
244-
* @return The descriptor used to load the trust store. Never
245-
* <code>null</code>.
242+
* @return The descriptor used to load the trust store. Never <code>null</code>.
246243
*/
247244
@NonNull
248245
public ITrustStoreDescriptor getTrustStoreDescriptor ()
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (C) 2015-2026 Philip Helger (www.helger.com)
3+
* philip[at]helger[dot]com
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.helger.phase4.crypto;
18+
19+
import org.apache.wss4j.common.WSS4JConstants;
20+
import org.jspecify.annotations.NonNull;
21+
import org.jspecify.annotations.Nullable;
22+
23+
import com.helger.annotation.Nonempty;
24+
import com.helger.base.id.IHasID;
25+
import com.helger.base.lang.EnumHelper;
26+
27+
/**
28+
* Enumeration of key agreement methods for XML Encryption. Key agreement is an alternative to key
29+
* transport (e.g. RSA-OAEP) where both parties contribute to deriving a shared secret.
30+
*
31+
* @author Philip Helger
32+
* @since 4.4.0
33+
*/
34+
public enum ECryptoKeyAgreementMethod implements IHasID <String>
35+
{
36+
/** ECDH-ES key agreement (generic, for EC keys on standard curves like secp256r1) */
37+
ECDH_ES (WSS4JConstants.AGREEMENT_METHOD_ECDH_ES),
38+
/** X25519 key agreement (Curve25519, eDelivery AS4 2.0 Common Usage Profile) */
39+
X25519 (WSS4JConstants.AGREEMENT_METHOD_X25519),
40+
/** X448 key agreement (Curve448) */
41+
X448 (WSS4JConstants.AGREEMENT_METHOD_X448);
42+
43+
private final String m_sID;
44+
45+
ECryptoKeyAgreementMethod (@NonNull @Nonempty final String sID)
46+
{
47+
m_sID = sID;
48+
}
49+
50+
@NonNull
51+
@Nonempty
52+
public String getID ()
53+
{
54+
return m_sID;
55+
}
56+
57+
@Nullable
58+
public static ECryptoKeyAgreementMethod getFromIDOrNull (@Nullable final String sID)
59+
{
60+
return EnumHelper.getFromIDOrNull (ECryptoKeyAgreementMethod.class, sID);
61+
}
62+
63+
@Nullable
64+
public static ECryptoKeyAgreementMethod getFromIDOrDefault (@Nullable final String sID,
65+
@Nullable final ECryptoKeyAgreementMethod eDefault)
66+
{
67+
return EnumHelper.getFromIDOrDefault (ECryptoKeyAgreementMethod.class, sID, eDefault);
68+
}
69+
}

0 commit comments

Comments
 (0)