Skip to content

Add a test case to illustrate a256gcm decipher fail#34

Open
dmulder wants to merge 1 commit into
kanidm:mainfrom
dmulder:dmulder/a256gcm_decipher_fail
Open

Add a test case to illustrate a256gcm decipher fail#34
dmulder wants to merge 1 commit into
kanidm:mainfrom
dmulder:dmulder/a256gcm_decipher_fail

Conversation

@dmulder
Copy link
Copy Markdown
Collaborator

@dmulder dmulder commented Nov 1, 2024

This is a real access token response from MS, using their oauth2 version 2 protocol and PRT version 3 request (and the encrypted token is no longer valid, as the enrolled object has been deleted).

  • cargo fmt has been run
  • cargo test has been run and passes
  • documentation has been updated with relevant examples (if relevant)

Signed-off-by: David Mulder <dmulder@samba.org>
@dmulder dmulder requested a review from Firstyear November 1, 2024 19:23
@Firstyear
Copy link
Copy Markdown
Member

I went through this test and the associated code and I don't see anything wrong in compact_jwt. We get the jwec with direct + aes256gcm, which you then correct attempt to deserialise with the direct key.

The decryption fails in the "decrypted.finalise" step which indicates that the authentication tag didn't match. The most likely explanation is that the aes key you are using isn't correct for the payload.

@dmulder
Copy link
Copy Markdown
Collaborator Author

dmulder commented Nov 4, 2024

I went through this test and the associated code and I don't see anything wrong in compact_jwt. We get the jwec with direct + aes256gcm, which you then correct attempt to deserialise with the direct key.

The decryption fails in the "decrypted.finalise" step which indicates that the authentication tag didn't match. The most likely explanation is that the aes key you are using isn't correct for the payload.

Ok, that was my belief as well after analyzing things. I just don't understand why this would have failed. Unless I'm formatting the public key incorrectly in the previous request (so it's encrypted using the wrong public key)? This could be. I've seen MS accept garbage before for the public key.

@Firstyear
Copy link
Copy Markdown
Member

Yeah, it could be something like that. It's hard when you're trying to poke at a black box to work out what's going on :(

@dmulder
Copy link
Copy Markdown
Collaborator Author

dmulder commented Feb 3, 2025

I think I've finally tracked down this issue (maybe). When I examine traffic from a MS application, I see that in the request for this un-decryptable PRT, I'm supposed to send a stk_jwk, which looks like this:

{"e":"AQAB","kty":"RSA","n":"AMBIy7nfnekGD74imrS6Y3teAg5pDX4Z1iVptx-krTQok-X_NAUOptdVS-5dphlz9MSV32tEsnle8oexXPSrfAuGLJD0MmMD4-FSVSnquXElZRKoLcWBWH7wABSRRGRwU15dUq93b1Q6lvgTNKSO0xe7BjmLivzlPqDZI4dhp6oUffHcWF0wX3YVvvwYB--IjJCA9F5ynpLas8vdHYrge6C-ZD4ufItfDSbbin5gq-uftvUOK8B04-cyQxZivZu7Fo3Q_G4PdnOlLf5NG9_ROTBBXXD0RdpAP9rYh3EUB6p9BOctbcdnLUUPOnqu7WhsW5RE9HLQIeyiKUNdL_HQwn0"}

So in order to request an initial PRTv3, I have to supply an RSA public key in the request. We've been trying to decrypt this PRTv3 with the AES256GCM session key. Looking around, some Entra Id error message refers to the stk_jwk as the 'session transport key'. So, perhaps the transport key, or some other RSA key entirely?

So here's what I think is expected:

  1. The initial PRTv3 request is sent with an RSA public key, and the response is decrypted using that RSA key's private key.
  2. Subsequent PRTv3 requests are then encrypted/decrypted using the session key obtained in step 1.
  3. Rinse and repeat step 2.

@dmulder
Copy link
Copy Markdown
Collaborator Author

dmulder commented Feb 3, 2025

This so-called 'initial' response has a header of {"enc":"A256GCM","alg":"RSA-OAEP"}, whereas your typical response has a jwe header of {"alg":"dir","enc":"A256GCM","ctx":"ZJdQriBJqfS7UFA2b8Ed+aOqeelTDwPm"}.

@dmulder
Copy link
Copy Markdown
Collaborator Author

dmulder commented Feb 3, 2025

A sample 'initial' session_key_jwe looks like this:

eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.E675R3vtw7CIHie6vo2qFRmP_y8g9roWYnIrsD9k11sY2O87M6ZrSBRObXXj2ORS1gP2ImbqAEQzl4OJKRC8BEQB6R9-tMXWpUjt8w27IhxzATpQINAtHmXUN6cFCkapVVqUUYMdbXSnbc30WjsqU-ovZfbQBeye9zF1AD180DToDnkBbSLJGMn1GHC2ETGelKLqpogbuJFImFo5Zl7CAG8S4TtGaho-37f4YrsbUBR-rYLosMRZ5zc_7sy7aGxXb1ze92Z80-9ODKFbf3dqgTWbXD035Gbdl3dqw13IYSbjjWZwsM985pLBasm24BAOcaPU4CBOhjUzZqdB_SvCDA.jHz5rlz2gmqD8Nxx.-A.ydsQrUjR3Qv6oXAbJTBFWQ

@Firstyear
Copy link
Copy Markdown
Member

Right, so from your messages/outputs I think:

  • Send the RSA public key (which could even be an ephemeral/session key)?
  • The first response we get back is RSA-OAEP encrypted and yields an AES256GCM key.
  • Once we have that AES256GCM key, that can be used with the subsequent messages which alg: dir(ect).

So in that case, don't we have all the parts in place here to solve this? The only concern I'd have is about exporting the publickey here as a jwk, since we aren't setting the kty field https://github.com/kanidm/compact-jwt/blob/main/src/crypto/rs256.rs#L141

It looks like it's valid from https://www.rfc-editor.org/rfc/rfc7517#section-4.1 so I don't see a reason we couldn't add it. My final concern would be that we also are adding in extra fields MS may not like, so we may need an "azure optimised" jwk function.

@dmulder
Copy link
Copy Markdown
Collaborator Author

dmulder commented Feb 5, 2025

Right, so from your messages/outputs I think:

* Send the RSA public key (which could even be an ephemeral/session key)?

* The first response we get back is RSA-OAEP encrypted and yields an AES256GCM key.

* Once we have that AES256GCM key, that can be used with the subsequent messages which alg: dir(ect).

So in that case, don't we have all the parts in place here to solve this? The only concern I'd have is about exporting the publickey here as a jwk, since we aren't setting the kty field https://github.com/kanidm/compact-jwt/blob/main/src/crypto/rs256.rs#L141

It looks like it's valid from https://www.rfc-editor.org/rfc/rfc7517#section-4.1 so I don't see a reason we couldn't add it. My final concern would be that we also are adding in extra fields MS may not like, so we may need an "azure optimised" jwk function.

I need to investigate more. After some more testing, I think my assumptions here might be incorrect.

@Firstyear
Copy link
Copy Markdown
Member

It's been a while on this one @dmulder is it still relevant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants