Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to AWS SDK v2 #21

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ In the current version following encryption and signing operations are supported
1. Symmetric encryption (AES based).
1. Classes: `com.nimbusds.jose.aws.kms.crypto.KmsSymmetricEncrypter`
and `com.nimbusds.jose.aws.kms.crypto.KmsSymmetricDecrypter`
1. Asymmetric or Symmetric encryption (RSA or ECDSA based for asymmetric keys and AES based for symmetric keys).
2. Asymmetric or Symmetric encryption (RSA or ECDSA based for asymmetric keys and AES based for symmetric keys).
1. Classes: `com.nimbusds.jose.aws.kms.crypto.KmsDefaultEncrypter`
and `com.nimbusds.jose.aws.kms.crypto.KmsDefaultDecrypter`
1. Asymmetric signing (RSA or ECDSA based).
3. Asymmetric signing (RSA or ECDSA based).
1. Classes: `com.nimbusds.jose.aws.kms.crypto.KmsAsymmetricSigner`
and `com.nimbusds.jose.aws.kms.crypto.KmsAsymmetricVerifier`

Expand Down
8 changes: 5 additions & 3 deletions nimbus-jose-jwt_aws-kms-extension/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ java {
withSourcesJar()
}

tasks.withType(JavaCompile) {
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}

Expand All @@ -32,13 +32,15 @@ dependencies {
api 'com.nimbusds:nimbus-jose-jwt:[9,9.31]'

// These dependencies is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.amazonaws:aws-java-sdk-kms:[1.12, 2)'
implementation 'commons-cli:commons-cli:[1.4, 2)'
implementation 'software.amazon.awssdk:kms:2.30.18'
implementation 'commons-cli:commons-cli:1.9.0'
implementation 'commons-codec:commons-codec:1.18.0'
implementation 'com.google.guava:guava:[32,)'

// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.+'
testImplementation 'org.assertj:assertj-core:[3,4)'
testImplementation 'org.junit.platform:junit-platform-launcher:1.11.4'

// Mockito
testImplementation 'org.mockito:mockito-core:[3,4)'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
package com.nimbusds.jose.aws.kms.crypto;


import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.model.MessageType;
import com.nimbusds.jose.aws.kms.crypto.impl.KmsAsymmetricRSASSAProvider;
import javax.annotation.concurrent.ThreadSafe;
import lombok.NonNull;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.MessageType;

import javax.annotation.concurrent.ThreadSafe;


/**
Expand All @@ -37,7 +38,7 @@
public class KmsAsymmetricRSASSASigner extends KmsAsymmetricSigner {

public KmsAsymmetricRSASSASigner(
@NonNull final AWSKMS kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
@NonNull final KmsClient kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
super(kms, privateKeyId, messageType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
package com.nimbusds.jose.aws.kms.crypto;


import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.model.MessageType;
import com.nimbusds.jose.aws.kms.crypto.impl.KmsAsymmetricRSASSAProvider;
import java.util.Set;
import javax.annotation.concurrent.ThreadSafe;
import lombok.NonNull;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.MessageType;

import javax.annotation.concurrent.ThreadSafe;
import java.util.Set;

/**
* Sign verifier implementation for RSA-SSA signing with public/private key stored in AWS KMS.
Expand All @@ -37,12 +38,12 @@
public class KmsAsymmetricRSASSAVerifier extends KmsAsymmetricVerifier {

public KmsAsymmetricRSASSAVerifier(
@NonNull final AWSKMS kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
@NonNull final KmsClient kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
super(kms, privateKeyId, messageType);
}

public KmsAsymmetricRSASSAVerifier(
@NonNull final AWSKMS kms, @NonNull String privateKeyId, @NonNull final MessageType messageType,
@NonNull final KmsClient kms, @NonNull String privateKeyId, @NonNull final MessageType messageType,
@NonNull final Set<String> defCritHeaders) {
super(kms, privateKeyId, messageType, defCritHeaders);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,20 @@
package com.nimbusds.jose.aws.kms.crypto;


import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.model.DependencyTimeoutException;
import com.amazonaws.services.kms.model.DisabledException;
import com.amazonaws.services.kms.model.InvalidGrantTokenException;
import com.amazonaws.services.kms.model.InvalidKeyUsageException;
import com.amazonaws.services.kms.model.KMSInternalException;
import com.amazonaws.services.kms.model.KMSInvalidStateException;
import com.amazonaws.services.kms.model.KeyUnavailableException;
import com.amazonaws.services.kms.model.MessageType;
import com.amazonaws.services.kms.model.NotFoundException;
import com.amazonaws.services.kms.model.SignRequest;
import com.amazonaws.services.kms.model.SignResult;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.RemoteKeySourceException;
import com.nimbusds.jose.aws.kms.crypto.impl.KmsAsymmetricSigningCryptoProvider;
import com.nimbusds.jose.aws.kms.exceptions.TemporaryJOSEException;
import com.nimbusds.jose.util.Base64URL;
import javax.annotation.concurrent.ThreadSafe;
import lombok.NonNull;
import lombok.var;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.*;

import javax.annotation.concurrent.ThreadSafe;


/**
Expand All @@ -51,28 +43,29 @@
public class KmsAsymmetricSigner extends KmsAsymmetricSigningCryptoProvider implements JWSSigner {

public KmsAsymmetricSigner(
@NonNull final AWSKMS kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
@NonNull final KmsClient kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
super(kms, privateKeyId, messageType);
}

@Override
public Base64URL sign(@NonNull final JWSHeader header, @NonNull final byte[] signingInput) throws JOSEException {

final var message = getMessage(header, signingInput);
SignResult signResult;
SignResponse signResponse;
try {
signResult = getKms().sign(new SignRequest()
.withKeyId(getPrivateKeyId())
.withMessageType(getMessageType())
.withMessage(message)
.withSigningAlgorithm(JWS_ALGORITHM_TO_SIGNING_ALGORITHM_SPEC.get(header.getAlgorithm()).toString()));
signResponse = getKms().sign(SignRequest.builder()
.keyId(getPrivateKeyId())
.messageType(getMessageType())
.message(SdkBytes.fromByteBuffer(message))
.signingAlgorithm(JWS_ALGORITHM_TO_SIGNING_ALGORITHM_SPEC.get(header.getAlgorithm()).toString())
.build());
} catch (NotFoundException | DisabledException | KeyUnavailableException | InvalidKeyUsageException
| KMSInvalidStateException e) {
| KmsInvalidStateException e) {
throw new RemoteKeySourceException("An exception was thrown from KMS due to invalid key.", e);
} catch (DependencyTimeoutException | InvalidGrantTokenException | KMSInternalException e) {
} catch (DependencyTimeoutException | InvalidGrantTokenException | KmsInternalException e) {
throw new TemporaryJOSEException("A temporary exception was thrown from KMS.", e);
}

return Base64URL.encode(signResult.getSignature().array());
return Base64URL.encode(signResponse.signature().asByteArray());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,20 @@
package com.nimbusds.jose.aws.kms.crypto;


import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.model.DependencyTimeoutException;
import com.amazonaws.services.kms.model.DisabledException;
import com.amazonaws.services.kms.model.InvalidGrantTokenException;
import com.amazonaws.services.kms.model.InvalidKeyUsageException;
import com.amazonaws.services.kms.model.KMSInternalException;
import com.amazonaws.services.kms.model.KMSInvalidSignatureException;
import com.amazonaws.services.kms.model.KMSInvalidStateException;
import com.amazonaws.services.kms.model.KeyUnavailableException;
import com.amazonaws.services.kms.model.MessageType;
import com.amazonaws.services.kms.model.NotFoundException;
import com.amazonaws.services.kms.model.VerifyRequest;
import com.amazonaws.services.kms.model.VerifyResult;
import com.nimbusds.jose.CriticalHeaderParamsAware;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.RemoteKeySourceException;
import com.nimbusds.jose.*;
import com.nimbusds.jose.aws.kms.crypto.impl.KmsAsymmetricSigningCryptoProvider;
import com.nimbusds.jose.aws.kms.exceptions.TemporaryJOSEException;
import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral;
import com.nimbusds.jose.util.Base64URL;
import java.nio.ByteBuffer;
import java.util.Set;
import javax.annotation.concurrent.ThreadSafe;
import lombok.NonNull;
import lombok.var;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.*;

import javax.annotation.concurrent.ThreadSafe;
import java.nio.ByteBuffer;
import java.util.Set;

/**
* Sign verifier implementation for asymmetric signing with public/private key stored in AWS KMS.
Expand All @@ -52,9 +39,7 @@
* constructor parameters.
*/
@ThreadSafe
public class KmsAsymmetricVerifier
extends KmsAsymmetricSigningCryptoProvider
implements JWSVerifier, CriticalHeaderParamsAware {
public class KmsAsymmetricVerifier extends KmsAsymmetricSigningCryptoProvider implements JWSVerifier, CriticalHeaderParamsAware {

/**
* The critical header policy.
Expand All @@ -63,13 +48,13 @@ public class KmsAsymmetricVerifier


public KmsAsymmetricVerifier(
@NonNull final AWSKMS kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
@NonNull final KmsClient kms, @NonNull final String privateKeyId, @NonNull final MessageType messageType) {
super(kms, privateKeyId, messageType);
}


public KmsAsymmetricVerifier(
@NonNull final AWSKMS kms, @NonNull String privateKeyId, @NonNull final MessageType messageType,
@NonNull final KmsClient kms, @NonNull String privateKeyId, @NonNull final MessageType messageType,
@NonNull final Set<String> defCritHeaders) {
super(kms, privateKeyId, messageType);
critPolicy.setDeferredCriticalHeaderParams(defCritHeaders);
Expand Down Expand Up @@ -101,24 +86,25 @@ public boolean verify(

var message = getMessage(header, signedContent);

VerifyResult verifyResult;
VerifyResponse verifyResponse;
try {
verifyResult = getKms().verify(new VerifyRequest()
.withKeyId(getPrivateKeyId())
.withSigningAlgorithm(JWS_ALGORITHM_TO_SIGNING_ALGORITHM_SPEC.get(header.getAlgorithm()).toString())
.withMessageType(getMessageType())
.withMessage(message)
.withSignature(ByteBuffer.wrap(signature.decode())));
} catch (KMSInvalidSignatureException e) {
verifyResponse = getKms().verify(VerifyRequest.builder()
.keyId(getPrivateKeyId())
.signingAlgorithm(JWS_ALGORITHM_TO_SIGNING_ALGORITHM_SPEC.get(header.getAlgorithm()).toString())
.messageType(getMessageType())
.message(SdkBytes.fromByteBuffer(message))
.signature(SdkBytes.fromByteBuffer(ByteBuffer.wrap(signature.decode())))
.build());
} catch (KmsInvalidSignatureException e) {
return false;
} catch (NotFoundException | DisabledException | KeyUnavailableException | InvalidKeyUsageException
| KMSInvalidStateException e) {
| KmsInvalidStateException e) {
throw new RemoteKeySourceException("An exception was thrown from KMS due to invalid key.", e);
} catch (DependencyTimeoutException | InvalidGrantTokenException | KMSInternalException e) {
} catch (DependencyTimeoutException | InvalidGrantTokenException | KmsInternalException e) {
throw new TemporaryJOSEException("A temporary exception was thrown from KMS.", e);
}

return verifyResult.isSignatureValid();
return verifyResponse.signatureValid();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.nimbusds.jose.aws.kms.crypto;

import com.amazonaws.services.kms.AWSKMS;
import com.nimbusds.jose.CriticalHeaderParamsAware;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEDecrypter;
Expand All @@ -25,9 +24,11 @@
import com.nimbusds.jose.aws.kms.crypto.utils.JWEDecrypterUtil;
import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral;
import com.nimbusds.jose.util.Base64URL;
import lombok.NonNull;
import software.amazon.awssdk.services.kms.KmsClient;

import java.util.Map;
import java.util.Set;
import lombok.NonNull;

/**
* Decrypter implementation for a symmetric or asymmetric key stored in AWS KMS.
Expand All @@ -43,25 +44,25 @@ public class KmsDefaultDecrypter extends KmsDefaultEncryptionCryptoProvider impl
*/
private final CriticalHeaderParamsDeferral critPolicy = new CriticalHeaderParamsDeferral();

public KmsDefaultDecrypter(@NonNull final AWSKMS kms,
public KmsDefaultDecrypter(@NonNull final KmsClient kms,
@NonNull final String keyId,
@NonNull final Map<String, String> encryptionContext) {
super(kms, keyId, encryptionContext);
}

public KmsDefaultDecrypter(@NonNull final AWSKMS kms,
public KmsDefaultDecrypter(@NonNull final KmsClient kms,
@NonNull final String keyId) {
super(kms, keyId);
}

public KmsDefaultDecrypter(@NonNull final AWSKMS kms,
public KmsDefaultDecrypter(@NonNull final KmsClient kms,
@NonNull final String keyId,
@NonNull final Set<String> defCritHeaders) {
this(kms, keyId);
critPolicy.setDeferredCriticalHeaderParams(defCritHeaders);
}

public KmsDefaultDecrypter(@NonNull final AWSKMS kms,
public KmsDefaultDecrypter(@NonNull final KmsClient kms,
@NonNull final String keyId,
@NonNull final Map<String, String> encryptionContext,
@NonNull final Set<String> defCritHeaders) {
Expand Down
Loading