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

feat: support FIPS endpoints for AWS KMS #245

Open
wants to merge 3 commits into
base: master
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
23 changes: 21 additions & 2 deletions jsign-crypto/src/main/java/net/jsign/jca/AmazonSigningService.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ public class AmazonSigningService implements SigningService {
algorithmMapping.put("SHA512withRSA/PSS", "RSASSA_PSS_SHA_512");
}

/**
* Generates the endpoint URL for the given AWS region.
*
* @param region the AWS region
* @return the endpoint URL
*/
public static String getEndpointUrl(String region) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make this method non static and package privarte?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed, if I want to test this individually, it needs to be public. Don't know that much about Java ;) Can give it a try later …

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It remains testable from a test class in the same package if the public keyword is removed, that's the "package private" visibility.

String useFipsEndpoint = getenv("AWS_USE_FIPS_ENDPOINT");
if (useFipsEndpoint != null && useFipsEndpoint.equalsIgnoreCase("true")) {
return "https://kms-fips." + region + ".amazonaws.com";
}

return "https://kms." + region + ".amazonaws.com";
}

/**
* Creates a new AWS signing service.
*
Expand All @@ -90,7 +105,7 @@ public class AmazonSigningService implements SigningService {
* @since 6.0
*/
public AmazonSigningService(String region, Supplier<AmazonCredentials> credentials, Function<String, Certificate[]> certificateStore) {
this(credentials, certificateStore, "https://kms." + region + ".amazonaws.com");
this(credentials, certificateStore, getEndpointUrl(region));
}

/**
Expand Down Expand Up @@ -259,7 +274,7 @@ void sign(HttpURLConnection conn, AmazonCredentials credentials, byte[] content,
String host = endpoint.getHost();
Matcher matcher = hostnamePattern.matcher(host);
String regionName = matcher.matches() ? matcher.group(2) : "us-east-1";
String serviceName = matcher.matches() ? matcher.group(1) : "kms";
String serviceName = "kms";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather strip the -fips suffix here, so this method remains generic for any AWS service

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that class is only intended to access KMS or are there other services involved that I miss?


String credentialScope = dateFormat.format(date) + "/" + regionName + "/" + serviceName + "/" + "aws4_request";

Expand Down Expand Up @@ -331,4 +346,8 @@ private String sha256(byte[] data) {
digest.update(data);
return Hex.toHexString(digest.digest()).toLowerCase();
}

static String getenv(String name) {
return System.getenv(name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@
import org.junit.Before;
import org.junit.Test;

import org.mockito.MockedStatic;
import org.mockito.Mockito;

import static net.jadler.Jadler.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class AmazonSigningServiceTest {

Expand Down Expand Up @@ -84,6 +88,20 @@ public void testGetAliases() throws Exception {
assertEquals("aliases", Arrays.asList("2d9ca5b0-6d51-4727-9dfc-186e62e4c5e2", "935ecb66-5c06-495b-babe-5798b1c0e1a8"), aliases);
}

@Test
public void testGetEndpointUrl() throws Exception {
// Test default endpoint
String defaultEndpoint = AmazonSigningService.getEndpointUrl("us-west-2");
assertEquals("https://kms.us-west-2.amazonaws.com", defaultEndpoint);

// Test FIPS endpoint
try (MockedStatic<?> mock = mockStatic(AmazonSigningService.class, CALLS_REAL_METHODS)) {
when(AmazonSigningService.getenv("AWS_USE_FIPS_ENDPOINT")).thenReturn("true");
String fipsEndpoint = AmazonSigningService.getEndpointUrl("us-west-2");
assertEquals("https://kms-fips.us-west-2.amazonaws.com", fipsEndpoint);
}
}

@Test
public void testGetAliasesWithError() {
onRequest()
Expand Down