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

NullReferenceException error when trying to get a recipient based on SubjectKeyIdentifier #541

Open
rosco12345 opened this issue May 31, 2024 · 1 comment

Comments

@rosco12345
Copy link

rosco12345 commented May 31, 2024

We recently tried to update from version 2.3.1 to 2.4.0

This caused our encryption tests to break. I've produced a minimal example here. It's simply a test that encrypts a string then decrypts it, asserting that the original plaintext and the decrypted plaintext are the same.

The test in that example passes with version 2.3.1 and fails with a null reference error when using GetFirstRecipient().

I wonder if this could be related to changes made in a35474d

@peterdettman
Copy link
Collaborator

peterdettman commented Jun 3, 2024

Yes, there was a fix around CMS recipients using SubjectKeyIdentifier that caused a breaking change. It arose out of this reported issue: #532 (not so much the initial report, but the followup discoveries).

Considering the example code you linked: the decryption code is technically wrong because RecipientID is an X509CertStoreSelector subclass, and the SubjectKeyIdentifier property should not be the raw SKI value (usually a 20 byte SHA-1 output), but rather a DER-encoding of that raw value (usually 22 bytes). The DER encoding corresponds to the expected format when used as an X.509 extension; we copied the behaviour apparently from java.security.cert.X509CertSelector.

The actual CMS messages (recipient infos) are supposed to store the raw SKI value (e.g. 20 byte OCTET STRING), but before 2.4.0 BC was using that value directly for the RecipientID.SubjectKeyIdentifier property and so would fail to match certificates. It was still possible to round-trip encrypt/decrypt (by fudging the encryption code) but then the messages would be invalid i.e. not interoperable with other implementations.

TLDR; Your example decryption code would have to use this to work correctly with 2.4.0:

var recipientID = new RecipientID {
    SubjectKeyIdentifier = new DerOctetString(SubjectKeyIdentifier).GetEncoded()
};

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

No branches or pull requests

2 participants