bcgit / bc-csharp

BouncyCastle.NET Cryptography Library (Mirror)
https://www.bouncycastle.org/csharp
MIT License
1.68k stars 559 forks source link

Issues with ECC, S/MIME and BouncyCastle #516

Closed myst3rium closed 9 months ago

myst3rium commented 10 months ago

Hi guys - i've been forwarded to you from jstedfast to you with an question regarding S/MIME encryption with an ECC certificate. (see: https://github.com/jstedfast/MimeKit/issues/998)

I thought it would be a good idea to switch from RSA certificates to ECC certificates in order to encrypt mails with "state-of-the-art" technology. Therefore I use the library "MimeKit" from jstedfast that uses bouncycastle underneath.

I started creating some certificates using bouncycastle with yet very limited knowledge about ECC and all seemed to be fine. When I tried to use that certificate somewhere from the bouncycastle library throws:

To get an deeper insight of whats going on you may review my question on stackoverflow: https://stackoverflow.com/questions/77906972/difficulties-with-ecc-bouncycastle-and-mimekit

Maybe I just screwed things up in my certificate generator but maybe there is an issue in bouncycastle and/or MimeKit - so maybe you guys can help out?

grafik

If you need any more information I'm happy to provide it. I just don't know yet, where to start and where to stop. Thanks

jstedfast commented 10 months ago

@peterdettman For what it's worth, here's a link to the MimeKit code that calls WrapperUtilities.GetWrapper():

https://github.com/jstedfast/MimeKit/blob/master/MimeKit/Cryptography/BouncyCastleSecureMimeContext.cs#L1237-L1251

I have a feeling that code above probably needs to be changed to handle ECC AlgorithmIdentifiers.

cipherboy commented 9 months ago

\o hello @jstedfast and @myst3rium

I think you're down the right trail. https://datatracker.ietf.org/doc/html/rfc5652#section-6.2.2 is likely what you'll want to refer to here: RSA can support direct encryption of keys, but EC cannot (EC in the regular form is "just" a signature algorithm, but there's a variant that allows for ECDH shared secret negotiation). This shared secret can be converted to an encryption scheme (e.g., ECIES) -- CMS's version of this scheme is noted in that RFC section linked above (on KeyAgreeRecipientInfo). These are all implementation details in the weeds though...

I suspect though, you could simplify your linked code.

I think most of what you've implemented is a re-implementation of Org.BouncyCastle.Cms.KeyTransRecipientInfoGenerator, and I don't quite understand why you chose that route. :-)

Since you already have a CmsEnvelopedDataGenerator (in Envelope), rather than calling AddRecipientInfoGenerator(...), you could call either AddKeyTransRecipient(...) or AddKeyAgreementRecipient(...) as appropriate for your key type. See the note in the abstract CmsEnvelopedGenerator that shows this usage.

(Note that CMS allows either a static Key Agreement sender's key via various lookups or explicitly sending it on the wire, I think the CMSEnvelopedDataGenerator only does the latter -- but this isn't relevant for your existing KeyTransRecipientInfo usage with RSA.)


I do not have a test environment for ECC S/MIME, but here's a PR with what I was thinking. The first commit is the refactor of the existing code, which passes tests locally (minus a test that is already failing on master for me), the second commit attempts ECC code integration.

Feel free to do with it what you wish :-)

cipherboy commented 9 months ago

Closing this as I've now added OAEP interfaces which should show up in the next release. Thanks all and let me know if you run into any more problems! :-)