[java-opensaml] 05/13: Key agreement components must account for both encryption and decryption
Brent Putman
putmanb at georgetown.edu
Wed Jan 6 01:27:19 UTC 2021
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch dev/OSJ-82
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=bc01c2e21f6efdd3931e33441b49674488fcf2c0
commit bc01c2e21f6efdd3931e33441b49674488fcf2c0
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Sat Dec 19 19:51:24 2020 -0500
Key agreement components must account for both encryption and decryption
Terminology of "recipient" and "originator" are reversed in the 2 cases,
so instead use "public" and "private" since that doesn't really change.
For decryption case, need to pass in the recipient/private credential
via KeyAgreementParameters.
In the KeyAgreementCredential production this means that have to
populate the recipientCredential and originatorCredential properties
based on which case it is.
---
.../org/opensaml/security/crypto/ec/ECSupport.java | 14 ++---
.../opensaml/security/crypto/ec/ECSupportTest.java | 11 ++--
.../xmlsec/agreement/KeyAgreementProcessor.java | 8 ++-
.../impl/AbstractKeyAgreementProcessor.java | 64 ++++++++++++++-------
.../agreement/impl/ECDHKeyAgreementProcessor.java | 47 +++++++++------
.../xmlsec/agreement/impl/PrivateCredential.java | 60 ++++++++++++++++++++
.../xmlsec/agreement/impl/StaticStaticMode.java | 33 +++++++++++
.../impl/ECDHKeyAgreementProcessorTest.java | 66 +++++++++++++++++++---
.../agreement/impl/PrivateCredentialTest.java | 55 ++++++++++++++++++
9 files changed, 298 insertions(+), 60 deletions(-)
diff --git a/opensaml-security-api/src/main/java/org/opensaml/security/crypto/ec/ECSupport.java b/opensaml-security-api/src/main/java/org/opensaml/security/crypto/ec/ECSupport.java
index d1ed7a34a..4121f72ba 100644
--- a/opensaml-security-api/src/main/java/org/opensaml/security/crypto/ec/ECSupport.java
+++ b/opensaml-security-api/src/main/java/org/opensaml/security/crypto/ec/ECSupport.java
@@ -41,10 +41,10 @@ public final class ECSupport {
private ECSupport() { }
/**
- * Perform ECDH key agreement between the given originator and recipient keys.
+ * Perform ECDH key agreement between the given public and private keys.
*
- * @param recipientKey the recipient's public key
- * @param originatorKey the originator's private key
+ * @param publicKeyKey the public key
+ * @param privateKey the private key
* @param provider the optional security provider to use
*
* @return the secret produced by key agreement
@@ -53,8 +53,8 @@ public final class ECSupport {
* @throws NoSuchProviderException
* @throws InvalidKeyException
*/
- public static byte[] performKeyAgreement(@Nonnull final ECPublicKey recipientKey,
- @Nonnull final ECPrivateKey originatorKey, @Nullable final String provider)
+ public static byte[] performKeyAgreement(@Nonnull final ECPublicKey publicKeyKey,
+ @Nonnull final ECPrivateKey privateKey, @Nullable final String provider)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
KeyAgreement keyAgreement = null;
@@ -64,8 +64,8 @@ public final class ECSupport {
keyAgreement = KeyAgreement.getInstance(JCAConstants.KEY_AGREEMENT_ECDH);
}
- keyAgreement.init(originatorKey);
- keyAgreement.doPhase(recipientKey, true);
+ keyAgreement.init(privateKey);
+ keyAgreement.doPhase(publicKeyKey, true);
return keyAgreement.generateSecret();
}
diff --git a/opensaml-security-api/src/test/java/org/opensaml/security/crypto/ec/ECSupportTest.java b/opensaml-security-api/src/test/java/org/opensaml/security/crypto/ec/ECSupportTest.java
index ca0d6c5a0..bcff2cbb4 100644
--- a/opensaml-security-api/src/test/java/org/opensaml/security/crypto/ec/ECSupportTest.java
+++ b/opensaml-security-api/src/test/java/org/opensaml/security/crypto/ec/ECSupportTest.java
@@ -62,13 +62,14 @@ public class ECSupportTest {
public void performKeyAgreement(String namedCurve) throws Exception {
final KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance(JCAConstants.KEY_ALGO_EC);
kpGenerator.initialize(new ECGenParameterSpec(namedCurve));
- final KeyPair recipientKeyPair = kpGenerator.generateKeyPair();
- ECPublicKey recipientPublicKey = ECPublicKey.class.cast(recipientKeyPair.getPublic());
+ final KeyPair publicKeyPair = kpGenerator.generateKeyPair();
+ ECPublicKey publicKey = ECPublicKey.class.cast(publicKeyPair.getPublic());
- final KeyPair originatorKeyPair = ECSupport.generateCompatibleKeyPair(recipientPublicKey, null);
- final ECPrivateKey originatorPrivateKey = ECPrivateKey.class.cast(originatorKeyPair.getPrivate());
+ final KeyPair privateKeyPair = ECSupport.generateCompatibleKeyPair(publicKey, null);
- byte[] secret = ECSupport.performKeyAgreement(recipientPublicKey, originatorPrivateKey, null);
+ final ECPrivateKey privateKey = ECPrivateKey.class.cast(privateKeyPair.getPrivate());
+
+ byte[] secret = ECSupport.performKeyAgreement(publicKey, privateKey, null);
Assert.assertNotNull(secret);
}
diff --git a/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementProcessor.java b/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementProcessor.java
index ee51d920d..eaccabc0b 100644
--- a/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementProcessor.java
+++ b/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementProcessor.java
@@ -36,16 +36,18 @@ public interface KeyAgreementProcessor {
/**
* Perform the key agreement operation and return a new credential representing the results.
*
- * @param recipientCredential the recipient credential
+ * @param publicCredential the public credential, which will belong either to the recipient or originator party,
+ * depending on whether encryption or decryption is being performed, respectively
* @param keyAlgorithm the JCA key algorithm for the derived key
* @param keyLength the key length for the derived key
- * @param parameters parameters to the agreement operation
+ * @param parameters parameters to the agreement operation. Internally a copy will be created so this input instance
+ * will not be modified.
*
* @return the agreement credential
*
* @throws KeyAgreementException
*/
- @Nonnull public KeyAgreementCredential execute(@Nonnull final Credential recipientCredential,
+ @Nonnull public KeyAgreementCredential execute(@Nonnull final Credential publicCredential,
@Nonnull final String keyAlgorithm, @Nonnull final Integer keyLength,
@Nonnull final KeyAgreementParameters parameters) throws KeyAgreementException;
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractKeyAgreementProcessor.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractKeyAgreementProcessor.java
index 526881daa..0539a4bd3 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractKeyAgreementProcessor.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractKeyAgreementProcessor.java
@@ -25,53 +25,66 @@ import org.opensaml.xmlsec.agreement.KeyAgreementCredential;
import org.opensaml.xmlsec.agreement.KeyAgreementException;
import org.opensaml.xmlsec.agreement.KeyAgreementParameters;
import org.opensaml.xmlsec.agreement.KeyAgreementProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Abstract base class for {@link KeyAgreementProcessor} implementations.
*/
public abstract class AbstractKeyAgreementProcessor implements KeyAgreementProcessor {
+
+ /** Logger. */
+ private final Logger log = LoggerFactory.getLogger(AbstractKeyAgreementProcessor.class);
/** {@inheritDoc} */
- @Nonnull public KeyAgreementCredential execute(@Nonnull final Credential recipientCredential,
+ @Nonnull public KeyAgreementCredential execute(@Nonnull final Credential publicCredential,
@Nonnull final String keyAlgorithm, @Nonnull final Integer keyLength,
@Nonnull final KeyAgreementParameters parameters) throws KeyAgreementException {
- final Credential originatorCredential = obtainOriginatorCredential(recipientCredential, parameters);
+ final Credential privateCredential = obtainPrivateCredential(publicCredential, parameters);
- final byte[] secret = generateAgreementSecret(recipientCredential, originatorCredential, parameters);
+ final byte[] secret = generateAgreementSecret(publicCredential, privateCredential, parameters);
final SecretKey derivedKey = deriveSecretKey(secret, keyAlgorithm, keyLength, parameters);
- return buildKeyAgreementCredential(derivedKey, recipientCredential, originatorCredential, parameters);
+ return buildKeyAgreementCredential(derivedKey, publicCredential, privateCredential, parameters);
}
/**
- * Obtain an originator credential which is compatible with the given recipient credential.
+ * Obtain the private credential which is compatible with the given public credential.
*
- * @param recipientCredential the recipient credential
+ * @param publicCredential the public credential
* @param parameters the key agreement parameters
*
- * @return the obtained originator credential
+ * @return the obtained private credential
*
* @throws KeyAgreementException
*/
- @Nonnull protected abstract Credential obtainOriginatorCredential(@Nonnull final Credential recipientCredential,
- @Nonnull final KeyAgreementParameters parameters) throws KeyAgreementException;
+ @Nonnull protected Credential obtainPrivateCredential(@Nonnull final Credential publicCredential,
+ @Nonnull final KeyAgreementParameters parameters) throws KeyAgreementException {
+
+ if (parameters.contains(PrivateCredential.class)) {
+ log.debug("Found supplied PrivateCredential in KeyAgreementParameters");
+ return parameters.get(PrivateCredential.class).getCredential();
+ }
+ return null;
+
+ }
/**
* Generate the agreement secret according to the key algorithm and using the supplied
- * originator and recipient credentials.
+ * public and private credentials.
*
- * @param recipientCredential the recipient credential
- * @param originatorCredential the originator credential
+ * @param publicCredential the public credential
+ * @param privateCredential the private credential
* @param parameters the key agreement parameters
*
- * @return the obtained originator credential
+ * @return the secret produced by the key agreement operation
*
* @throws KeyAgreementException
*/
- @Nonnull protected abstract byte[] generateAgreementSecret(@Nonnull final Credential recipientCredential,
- @Nonnull final Credential originatorCredential, @Nonnull final KeyAgreementParameters parameters)
+ @Nonnull protected abstract byte[] generateAgreementSecret(@Nonnull final Credential publicCredential,
+ @Nonnull final Credential privateCredential, @Nonnull final KeyAgreementParameters parameters)
throws KeyAgreementException;
/**
@@ -94,8 +107,8 @@ public abstract class AbstractKeyAgreementProcessor implements KeyAgreementProce
* Build the final {@link KeyAgreementCredential} from the given inputs.
*
* @param derivedKey the derived secret key
- * @param recipientCredential the recipient credential
- * @param originatorCredential the originator credential
+ * @param publicCredential the public credential
+ * @param privateCredential the private credential
* @param parameters the key agreement parameters
*
* @return the new key agreement credential
@@ -103,11 +116,24 @@ public abstract class AbstractKeyAgreementProcessor implements KeyAgreementProce
* @throws KeyAgreementException
*/
@Nonnull protected KeyAgreementCredential buildKeyAgreementCredential(@Nonnull final SecretKey derivedKey,
- @Nonnull final Credential recipientCredential, @Nonnull final Credential originatorCredential,
+ @Nonnull final Credential publicCredential, @Nonnull final Credential privateCredential,
@Nonnull final KeyAgreementParameters parameters) throws KeyAgreementException {
+ Credential recipient = null;
+ Credential originator = null;
+
+ if (parameters.contains(PrivateCredential.class) && ! parameters.contains(StaticStaticMode.class)) {
+ // Decrypting party case
+ recipient = privateCredential;
+ originator = publicCredential;
+ } else {
+ // Encrypting party case
+ recipient = publicCredential;
+ originator = privateCredential;
+ }
+
final KeyAgreementCredential cred = new BasicKeyAgreementCredential(derivedKey, getAlgorithm(),
- originatorCredential, recipientCredential);
+ originator, recipient);
cred.getParameters().addAll(parameters);
return cred;
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessor.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessor.java
index 6cfb0d51a..ba2ef0286 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessor.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessor.java
@@ -34,12 +34,17 @@ import org.opensaml.xmlsec.agreement.KeyAgreementException;
import org.opensaml.xmlsec.agreement.KeyAgreementParameters;
import org.opensaml.xmlsec.agreement.KeyAgreementProcessor;
import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Implementation of {@link KeyAgreementProcessor} which performs Elliptic Curve Diffie-Hellman (ECDH)
* Ephemeral-Static Mode key agreement as defined in XML Encryption 1.1.
*/
public class ECDHKeyAgreementProcessor extends AbstractDerivationKeyAgreementProcessor {
+
+ /** Logger. */
+ private final Logger log = LoggerFactory.getLogger(ECDHKeyAgreementProcessor.class);
/** {@inheritDoc} */
public String getAlgorithm() {
@@ -47,42 +52,50 @@ public class ECDHKeyAgreementProcessor extends AbstractDerivationKeyAgreementPro
}
/** {@inheritDoc} */
- protected Credential obtainOriginatorCredential(@Nonnull final Credential recipientCredential,
+ protected Credential obtainPrivateCredential(@Nonnull final Credential publicCredential,
@Nonnull final KeyAgreementParameters parameters) throws KeyAgreementException {
- if (!ECPublicKey.class.isInstance(recipientCredential.getPublicKey())) {
- throw new KeyAgreementException("Recipient credential's public key is not an instance of ECPublicKey");
+ final Credential suppliedCredential = super.obtainPrivateCredential(publicCredential, parameters);
+ if (suppliedCredential != null) {
+ return suppliedCredential;
}
- final ECPublicKey recipientPublicKey = ECPublicKey.class.cast(recipientCredential.getPublicKey());
+ log.debug("Found no supplied PrivateCredential in KeyAgreementParameters, generating ephemeral key pair");
+
+
+ if (!ECPublicKey.class.isInstance(publicCredential.getPublicKey())) {
+ throw new KeyAgreementException("Public credential's public key is not an instance of ECPublicKey");
+ }
+
+ final ECPublicKey publicKey = ECPublicKey.class.cast(publicCredential.getPublicKey());
try {
- final KeyPair originatorKeyPair = ECSupport.generateCompatibleKeyPair(recipientPublicKey, null);
- return new BasicCredential(originatorKeyPair.getPublic(), originatorKeyPair.getPrivate());
+ final KeyPair privateKeyPair = ECSupport.generateCompatibleKeyPair(publicKey, null);
+ return new BasicCredential(privateKeyPair.getPublic(), privateKeyPair.getPrivate());
} catch (final NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
- throw new KeyAgreementException("Error generating originator KeyPair from recipient EC public key", e);
+ throw new KeyAgreementException("Error generating private KeyPair from EC public key", e);
}
}
/** {@inheritDoc} */
- protected byte[] generateAgreementSecret(@Nonnull final Credential recipientCredential,
- @Nonnull final Credential originatorCredential, @Nonnull final KeyAgreementParameters parameters)
+ protected byte[] generateAgreementSecret(@Nonnull final Credential publicCredential,
+ @Nonnull final Credential privateCredential, @Nonnull final KeyAgreementParameters parameters)
throws KeyAgreementException {
- if (!ECPublicKey.class.isInstance(recipientCredential.getPublicKey())) {
- throw new KeyAgreementException("Recipient credential's public key is not an instance of ECPublicKey");
+ if (!ECPublicKey.class.isInstance(publicCredential.getPublicKey())) {
+ throw new KeyAgreementException("Public credential's public key is not an instance of ECPublicKey");
}
- if (!ECPrivateKey.class.isInstance(originatorCredential.getPrivateKey())) {
- throw new KeyAgreementException("Originator credential's private key is not an instance of ECPublicKey");
+ if (!ECPrivateKey.class.isInstance(privateCredential.getPrivateKey())) {
+ throw new KeyAgreementException("Private credential's private key is not an instance of ECPublicKey");
}
- final ECPublicKey recipient = ECPublicKey.class.cast(recipientCredential.getPublicKey());
- final ECPrivateKey originator = ECPrivateKey.class.cast(originatorCredential.getPrivateKey());
+ final ECPublicKey publicKey = ECPublicKey.class.cast(publicCredential.getPublicKey());
+ final ECPrivateKey privateKey = ECPrivateKey.class.cast(privateCredential.getPrivateKey());
try {
- return ECSupport.performKeyAgreement(recipient, originator, null);
+ return ECSupport.performKeyAgreement(publicKey, privateKey, null);
} catch (final InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException e) {
- throw new KeyAgreementException("Error generating secret from recipient and originator EC keys", e);
+ throw new KeyAgreementException("Error generating secret from public and private EC keys", e);
}
}
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/PrivateCredential.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/PrivateCredential.java
new file mode 100644
index 000000000..203f51211
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/PrivateCredential.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.xmlsec.agreement.impl;
+
+import java.security.PrivateKey;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.security.credential.Credential;
+import org.opensaml.xmlsec.agreement.KeyAgreementParameter;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * Key agreement parameter used to pass a Credential holding a required private key.
+ *
+ * <p>
+ * This is typically used in the decryption case to pass in the recipient's private credential.
+ * </p>
+ */
+public class PrivateCredential implements KeyAgreementParameter {
+
+ /** The wrapped Credential. */
+ private Credential credential;
+
+ /**
+ * Constructor.
+ *
+ * @param newCredential the private credential, containing a {@link PrivateKey}
+ */
+ public PrivateCredential(@Nonnull final Credential newCredential) {
+ credential = Constraint.isNotNull(newCredential, "Private Credential was null");
+ Constraint.isNotNull(credential.getPrivateKey(), "Credential did not contain required PrivateKey");
+ }
+
+ /**
+ * Get the wrapped credential.
+ *
+ * @return the credential
+ */
+ @Nonnull public Credential getCredential() {
+ return credential;
+ }
+
+}
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/StaticStaticMode.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/StaticStaticMode.java
new file mode 100644
index 000000000..1a9509d07
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/StaticStaticMode.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.xmlsec.agreement.impl;
+
+import org.opensaml.xmlsec.agreement.KeyAgreementParameter;
+
+/**
+ * Key agreement parameter whose presence indicates Static-Static mode is being used.
+ *
+ * <p>
+ * This is typically used in the encryption case for Static-Static mode, along with passing the originator's
+ * (encrypting party's) credential via {@link PrivateCredential}.
+ * </p>
+ */
+public class StaticStaticMode implements KeyAgreementParameter {
+
+
+}
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java
index 1d8f51daf..c5d28d405 100644
--- a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java
@@ -46,9 +46,9 @@ public class ECDHKeyAgreementProcessorTest {
}
@Test
- public void basic() throws Exception {
- KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
- Credential recipientCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
+ public void encryptingCase() throws Exception {
+ KeyPair recipientKeyPair = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+ Credential recipientCredential = CredentialSupport.getSimpleCredential(recipientKeyPair.getPublic(), null);
KeyAgreementParameters params = new KeyAgreementParameters();
params.add(new MockKeyDerivation());
@@ -70,6 +70,7 @@ public class ECDHKeyAgreementProcessorTest {
Assert.assertNotNull(keyAgreementCredential.getRecipientCredential());
Assert.assertNotNull(keyAgreementCredential.getRecipientCredential().getPublicKey());
+ Assert.assertNull(keyAgreementCredential.getRecipientCredential().getPrivateKey());
Assert.assertNull(keyAgreementCredential.getRecipientCredential().getSecretKey());
Assert.assertNotNull(keyAgreementCredential.getOriginatorCredential());
@@ -85,17 +86,64 @@ public class ECDHKeyAgreementProcessorTest {
Assert.assertEquals(keyAgreementCredential.getParameters().get(KANonce.class).getValue(), "someBase64");
}
+
+ @Test
+ public void decryptingCase() throws Exception {
+ KeyPair originatorKeyPair = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+ Credential originatorCredential = CredentialSupport.getSimpleCredential(originatorKeyPair.getPublic(), null);
+
+ KeyPair recipientKeyPair = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+ Credential recipientCredential = CredentialSupport.getSimpleCredential(recipientKeyPair.getPublic(), recipientKeyPair.getPrivate());
+
+ KeyAgreementParameters params = new KeyAgreementParameters();
+ params.add(new PrivateCredential(recipientCredential));
+ params.add(new MockKeyDerivation());
+ params.add(new KANonce("someBase64"));
+
+ KeyAgreementCredential keyAgreementCredential = processor.execute(originatorCredential,
+ JCAConstants.KEY_ALGO_AES,
+ 128,
+ params);
+
+ Assert.assertNotNull(keyAgreementCredential);
+
+ Assert.assertNotNull(keyAgreementCredential.getSecretKey());
+ Assert.assertEquals(keyAgreementCredential.getSecretKey().getAlgorithm(), JCAConstants.KEY_ALGO_AES);
+ Assert.assertEquals(KeySupport.getKeyLength(keyAgreementCredential.getSecretKey()), Integer.valueOf(128));
+
+ Assert.assertNull(keyAgreementCredential.getPublicKey());
+ Assert.assertNull(keyAgreementCredential.getPrivateKey());
+
+ Assert.assertNotNull(keyAgreementCredential.getRecipientCredential());
+ Assert.assertNotNull(keyAgreementCredential.getRecipientCredential().getPublicKey());
+ Assert.assertNotNull(keyAgreementCredential.getRecipientCredential().getPrivateKey());
+ Assert.assertNull(keyAgreementCredential.getRecipientCredential().getSecretKey());
+
+ Assert.assertNotNull(keyAgreementCredential.getOriginatorCredential());
+ Assert.assertNotNull(keyAgreementCredential.getOriginatorCredential().getPublicKey());
+ Assert.assertNull(keyAgreementCredential.getOriginatorCredential().getPrivateKey());
+ Assert.assertNull(keyAgreementCredential.getOriginatorCredential().getSecretKey());
+
+ Assert.assertEquals(keyAgreementCredential.getAlgorithm(), EncryptionConstants.ALGO_ID_KEYAGREEMENT_ECDH_ES);
+
+ Assert.assertEquals(keyAgreementCredential.getParameters().size(), 3);
+ Assert.assertTrue(keyAgreementCredential.getParameters().contains(PrivateCredential.class));
+ Assert.assertTrue(keyAgreementCredential.getParameters().contains(MockKeyDerivation.class));
+ Assert.assertTrue(keyAgreementCredential.getParameters().contains(KANonce.class));
+ Assert.assertEquals(keyAgreementCredential.getParameters().get(KANonce.class).getValue(), "someBase64");
+
+ }
@Test(expectedExceptions = KeyAgreementException.class)
public void nonECCred() throws Exception {
KeyPair kp = KeySupport.generateKeyPair("RSA", 2048, null);
- Credential recipientCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
+ Credential publicCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
KeyAgreementParameters params = new KeyAgreementParameters();
params.add(new MockKeyDerivation());
params.add(new KANonce("someBase64"));
- processor.execute(recipientCredential,
+ processor.execute(publicCredential,
JCAConstants.KEY_ALGO_AES,
128,
params);
@@ -104,13 +152,13 @@ public class ECDHKeyAgreementProcessorTest {
@Test(expectedExceptions = KeyAgreementException.class)
public void keyDerivationError() throws Exception {
KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
- Credential recipientCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
+ Credential publicCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
KeyAgreementParameters params = new KeyAgreementParameters();
params.add(new MockKeyDerivation());
params.add(new KANonce("someBase64"));
- processor.execute(recipientCredential,
+ processor.execute(publicCredential,
"INVALID",
128,
params);
@@ -119,12 +167,12 @@ public class ECDHKeyAgreementProcessorTest {
@Test(expectedExceptions = KeyAgreementException.class)
public void missingKeyDerivationParam() throws Exception {
KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
- Credential recipientCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
+ Credential publicCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
KeyAgreementParameters params = new KeyAgreementParameters();
params.add(new KANonce("someBase64"));
- processor.execute(recipientCredential,
+ processor.execute(publicCredential,
JCAConstants.KEY_ALGO_AES,
128,
params);
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/PrivateCredentialTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/PrivateCredentialTest.java
new file mode 100644
index 000000000..e772d772c
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/PrivateCredentialTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.xmlsec.agreement.impl;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.spec.ECGenParameterSpec;
+
+import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
+import org.opensaml.security.credential.CredentialSupport;
+import org.opensaml.security.crypto.KeySupport;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
+
+/**
+ *
+ */
+public class PrivateCredentialTest extends OpenSAMLInitBaseTestCase {
+
+ @Test
+ public void basic() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
+ KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+
+ PrivateCredential privateCredential = new PrivateCredential(CredentialSupport.getSimpleCredential(kp.getPublic(), kp.getPrivate()));
+ Assert.assertNotNull(privateCredential.getCredential());
+
+
+ try {
+ privateCredential = new PrivateCredential(CredentialSupport.getSimpleCredential(kp.getPublic(), null));
+ Assert.fail("PrivateCredential accepted Credential without PrivateKey");
+ } catch (ConstraintViolationException e) {
+ // expected, do nothing
+ }
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list