localstack icon indicating copy to clipboard operation
localstack copied to clipboard

bug: KMS signing with PSS always selects a salt length of MAX_SIZE, which creates interoperability problems

Open georgecodes opened this issue 1 year ago • 7 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Current Behavior

When I use an RSA key to sign something with PSS, the salt length is set to be MAX_LENGTH, which whilst acceptable in the strictest sense of the spec, is not in line with those required by RFC 4055

https://datatracker.ietf.org/doc/html/rfc4055#section-3.3

This makes verification of such signatures difficult across platforms. I have written a Java security provider which uses KMS to perform mtls connections, and while it works perfectly with actual KMS, my tests using localstack do not pass. Although verification of signed materials in the unit tests works, the resultant signatures do not necessarily verify with other libraries as the expected salt length is different to what has actually been used.

There is some mildly related discussion about this on the pycrypto repository

https://github.com/pyca/cryptography/issues/3008

Expected Behavior

The salt length should be set appropriately for the signing algorithm being used. I believe this can be fixed simply by setting salt_length to be padding.PSS.DIGEST_LENGTH in services/kms/models.py but I haven't fully tested this yet, merely modified code locally for it to work in my specific case.

How are you starting LocalStack?

Custom (please describe below)

Steps To Reproduce

How are you starting localstack (e.g., bin/localstack command, arguments, or docker-compose.yml)

I have used both the testcontainers version of localstack, and used source code and `make start` to reproduce this

Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

SignRequest signRequest = SignRequest.builder() .keyId(key.getId()) .messageType(MessageType.DIGEST) .signingAlgorithm(SigningAlgorithmSpec.RSASSA_PSS_SHA_512) .message(SdkBytes.fromByteArray(message)) .build(); SignResponse signatureResponse = kmsClient.sign(signRequest);

Produces a signature which verifies fine with localstack's KMS, but not with, say, BouncyCastle, or OpenSSL. An openssl command to verify signatures with the public key is included below

aws kms get-public-key --key-id <keyid>  --output text --query PublicKey --region us-west-2  | base64 -d > pub.der
 openssl pkeyutl -verify -in <digest> -sigfile <signature> -pkeyopt rsa_padding_mode:pss -pubin -inkey  pub.der -pkeyopt rsa_pss_saltlen:64 -pkeyopt digest:sha512 

This verification fails for signatures produced by localstack, but passes fine with real KMS

Environment

- OS: MacOS, Debian 12 slim
- LocalStack: 2.2.0

Anything else?

No response

georgecodes avatar Nov 10 '23 18:11 georgecodes

Welcome to LocalStack! Thanks for reporting your first issue and our team will be working towards fixing the issue for you or reach out for more background information. We recommend joining our Slack Community for real-time help and drop a message to LocalStack Pro Support if you are a Pro user! If you are willing to contribute towards fixing this issue, please have a look at our contributing guidelines and our contributing guide.

localstack-bot avatar Nov 10 '23 18:11 localstack-bot

I chose bug for this but it is potentially an enhancement request, as strictly speaking the behaviour is acceptable, just not parity with the AWS service it models.

georgecodes avatar Nov 10 '23 18:11 georgecodes

Hello 👋! It looks like this issue hasn’t been active in longer than five months. We encourage you to check if this is still an issue in the latest release. In the absence of more information, we will be closing this issue soon. If you find that this is still a problem, please feel free to provide a comment or upvote with a reaction on the initial post to prevent automatic closure. If the issue is already closed, please feel free to open a new one.

localstack-bot avatar Apr 13 '24 07:04 localstack-bot

I experience the same. I would definitely say this is clearly a bug rather than an enhancement.

Verifying a signature is not always done via KMS, that's definitely not the purpose of Asymmetric Cryptography. In most environments the digest(hash) of the message signed is calculated outside KMS (imagine you are signing many GBs, you can't send that in a request). While we can force our code to use KMS salt size and expect clients to do the same, having a different behaviour on LocalStack is definitely the wrong thing.

I'd also argue that the tests should rather use a Python Cryptography library to do the verification rather than the LocalStack KMS implementation, as the bug would be detected by a more meaningful test, at least during AWS Compatibility testing.

FlorinAsavoaie avatar Apr 16 '24 21:04 FlorinAsavoaie

Hello 👋! It looks like this issue hasn’t been active in longer than five months. We encourage you to check if this is still an issue in the latest release. In the absence of more information, we will be closing this issue soon. If you find that this is still a problem, please feel free to provide a comment or upvote with a reaction on the initial post to prevent automatic closure. If the issue is already closed, please feel free to open a new one.

localstack-bot avatar Sep 26 '24 12:09 localstack-bot

I may be able to devote some time to looking at this soon. My team are interested in using localstack for some KMS work, and this fix would enable them.

georgecodes avatar Oct 01 '24 15:10 georgecodes

We have the same problem here. Not having parity with aws is a real problem.

RalphBragg avatar Oct 01 '24 20:10 RalphBragg