ebourg / jsign

Java implementation of Microsoft Authenticode for signing Windows executables, installers & scripts
https://ebourg.github.io/jsign
Apache License 2.0
250 stars 107 forks source link

Support for AWSCredentialProviderChain for KMS based signing #187

Closed manishgant closed 5 months ago

manishgant commented 6 months ago

It would be useful to pass the generic AWSCredentialProviderChain to the AWS Signing service, as we have a usecase where we assume a service role through STSAssumeRoleCredentialsProvider and we want to pass this credentials to the KeyStoreBuilder for AWS

ebourg commented 6 months ago

You are using Jsign programmatically with the AWS SDK?

manishgant commented 6 months ago

You are using Jsign programmatically with the AWS SDK?

Yes. I want to use Jsign with AWS SDK, The use case is a webapp that dynamically signs executables on the fly

ebourg commented 6 months ago

In this case you should be able to feed the credentials from the provider to the KeyStoreBuilder, with something like this:

AWSCredentials credentials = provider.getCredentials();
KeyStore keystore = new KeyStoreBuilder()
                           .storetype(AWS)
                           .keystore("eu-west-3")
                           .storepass(credentials.getAWSAccessKeyId() + "|" + credentials.getAWSSecretKey())
                           .build();

Would that work for you?

manishgant commented 6 months ago

It might not in the long run. KMS resources in the environment are behind specific IAM roles and one would need to assume the role and get periodic refreshed credentials. Its simpler if I just pass in a CredentialProviderChain and the chain can have different CredentialProviders based on deployment environment.

ebourg commented 6 months ago

I'm not sure to understand the use case. KeyStoreBuilder needs the access key, the secret key, and optionally the session token. If you pass a credentials provider instead of the actual values, it means KeyStoreBuilder will have to pull the actual values itself. That's not very different and unless I'm missing something it just saves writing the concatenation of the parameters yourself. I understand that would be more convenient, but at the price of an added dependency on the AWS SDK, and that's something I'd like to avoid.

manishgant commented 6 months ago

I understand the this will rely on AWS SDK, however in business constrained environments, one will not have direct access to static AWS credentials to use, but rather use a service role to run the application in AWS. These service roles will need to periodically renew their tokens (every 1 hour in my case), which is way easier by just passing in a CustomCredentialProvider.

Currently I am getting past this by writing a background thread which updates the AWSCredentials inside the keystore object at runtime. But it isn't elegant at all :)

ebourg commented 6 months ago

In your case the keystore created by KeyStoreBuilder is long-lived and not created when needed? Why?

ebourg commented 5 months ago

I've modified the AmazonSigningService class such that a credentials supplier can be specified. The syntax to build an AWS keystore looks like this:

AWSCredentialProviderChain credentials = ...
Provider provider = new SigningServiceJcaProvider(new AmazonSigningService(region, () -> credentials.getAWSAccessKeyId() + "|" + credentials.getAWSSecretKey(), certstore));
KeyStore keystore = KeyStore.getInstance("AWS", provider);
keystore.load(null, null);

Please let me know if that works for you.