Comments (22)
So the problem turned out to be that the selector's SubjectKeyIdentifier is not being set appropriately by the CMS recipients (KeyAgreeRecipientInformation and KeyTransRecipientInformation).
It might be a good idea to change the way AuthorityKeyIdentifier and SubjectKeyIdentifier are set on X509CertStoreSelector, but for the moment I've just fixed the recipients.
from bc-csharp.
@jstedfast This issue affects selection of CMS recipients (KeyAgree/KeyTrans) that are specifying SubjectKeyIdentifier (instead of the more common IssuerAndSerialNumber). I am a bit surprised that we have no test coverage of that option between BouncyCastle (even bc-java) and MimeKit, so we probably should add some.
from bc-csharp.
MimeKit sets the SubjectKeyIdentifier incorrectly in RsaOaepAwareRecipientInfoGenerator.Generate (also in CmsEnvelopeAddEllipticCurve method just below there). That was "cancelling out" this issue in BouncyCastle.
After updating MimeKit to use 2.4.0-beta.61, then fixing those two places in MimeKit, things go back to working (but now would be correct for third-party messages - which our test suites ought to incorporate examples of).
Edit: @ggrote presumably saw the error because he was decrypting something with MimeKit that wasn't generated by MimeKit.
from bc-csharp.
@peterdettman what are your plans for releasing 2.4.0? I didn't realize that 2.3.1 fixed some security issues and so I'm getting requests to make a release with >= 2.3.1.
@jstedfast I'm planning to release 2.4.0 this coming weekend.
from bc-csharp.
@ggrote Do you have an example? When I tried to reproduce this with:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
var sr = File.OpenText("cert.pem");
var pr = new PemReader(sr);
var o = pr.ReadPemObject();
var cert = new X509Certificate(o.Content);
var e = cert.GetExtensionValue(X509Extensions.SubjectKeyIdentifier);
Console.WriteLine("e=" + Hex.ToHexString(e.GetOctets()));
I got:
$ dotnet run
e=0414b18deae423a77e098eb5ee31e06add9e343765ac
Where e
here seems to be the correct encoding of this parsed octet value.
from bc-csharp.
I think you got the same problem with your example.
The subject identifier should be:
b18deae423a77e098eb5ee31e06add9e343765ac
The 0414 at the beginning marks another octet string (0x04) with the length 0x14 inside the octet string for the extension. Just have a look in the pen with openssl or any other tool. Or just create the sha1 hash of the public key which should be the subject identifier.
from bc-csharp.
@ggrote I don't see any bug, you just aren't parsing the extension value.
An Extension has a value which is an OCTET STRING. In your example, the OCTET STRING is "041406a9...", encoded as "0416041406a9..." in the ASN.1. In the case of SubjectKeyIdentifier, that value is interpreted as an encoding of an ("inner") OCTET STRING. So to process this extension correctly, you need to actually parse the contents octets of the value OCTET STRING, which would give you back the OCTET STRING "06a9...".
Anyway, we have a convenience method for this type of thing, so just try:
cert.GetX509Extensions()?.GetExtensionParsedValue(X509Extensions.SubjectKeyIdentifier)
and you should get back the Asn1OctetString that you expect.
from bc-csharp.
Okay got it.
We faced the problem using MimeKit for decrypting S/Mime Mails which uses BouncyCastle.
The Implementation is as follows:
protected override AsymmetricKeyParameter GetPrivateKey (ISelector<X509Certificate> selector)
{
foreach (var certificate in certificates) {
var fingerprint = certificate.GetFingerprint ();
if (!keys.TryGetValue (fingerprint, out var key))
continue;
if (selector != null && !selector.Match (certificate))
continue;
return key;
}
return null;
}
Which uses the X509CertStoreSelectors Match function in which the SubjectKeyIdentifier is compared:
if (!MatchExtension(subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier))
return false;
private static bool MatchExtension(byte[] b, X509Certificate c, DerObjectIdentifier oid)
{
if (b == null)
return true;
Asn1OctetString extVal = c.GetExtensionValue(oid);
if (extVal == null)
return false;
return Arrays.AreEqual(b, extVal.GetOctets());
}
Shouldn't this be cert.GetX509Extensions()?.GetExtensionParsedValue(X509Extensions.SubjectKeyIdentifier)
like you said?
Because now the parsed value from the incoming Mail is compared to the unparsed value from the certificate.
I think the Java Version gives two values. One Raw Value and one parsed Value.
I'm sorry but the code formatting doesn't like me.
@cipherboy edited for formatting.
from bc-csharp.
Any news about it?
from bc-csharp.
I agree that there seems to be a problem in the selector. This code was all ported from bc-java so I think the confusion arises partly because of the behaviour of the JDK X509CertSelector class.
from bc-csharp.
Okay maybe there is a problem too. In my opinion the selector should compare the inner most octet string with the given value, as this could be the only option where it could match. Otherwise this whole selector can not work.
from bc-csharp.
Thank you!
from bc-csharp.
@jstedfast I've published 2.4.0-beta.61 to allow testing of the fix.
from bc-csharp.
@jstedfast With the "fix" I now get errors from MimeKit tests, and I have to take back the claim that you don't have test coverage for this case. I'm a bit confused how things used to work and why they break now though; needs more investigation.
from bc-csharp.
@peterdettman I'll try to look into the test failures this weekend. Is the published fix on nuget.org?
from bc-csharp.
Hmmm, odd, I installed the 2.4.0-beta.61 version and MimeKit UnitTests all passed?
from bc-csharp.
Added more tests for this and now I'm getting failures for SubjectKeyIdentifier but not IssuerAndSerialNumber (using 2.4.0-beta.61). I'll check v2.3.1 as soon as the meeting I'm in is over.
from bc-csharp.
all tests pass on v2.3.1
from bc-csharp.
Ah, got it.
from bc-csharp.
Edit: @ggrote presumably saw the error because he was decrypting something with MimeKit that wasn't generated by MimeKit.
I can't 100% confirm, but I'm pretty sure the service provider we got the mail from does not use MimeKit.
from bc-csharp.
The commit above depends on BouncyCastle 2.4.0-beta.61
@peterdettman What I ended up doing is writing unit tests for MimeKit that would encrypt using the System.Security backend and then verifying that the BouncyCastle backend could decrypt it. Likewise, I also added a unit test that would encrypt using the BouncyCastle backend and verifying that the System.Security backend could decrypt it.
Both tests try IssuerAndSerialNumber and SubjectKeyIdentifier so that we make sure that both work in both directions.
from bc-csharp.
@peterdettman what are your plans for releasing 2.4.0? I didn't realize that 2.3.1 fixed some security issues and so I'm getting requests to make a release with >= 2.3.1.
from bc-csharp.
Related Issues (20)
- itext7 - 'Pkcs12Store' exists in BouncyCastle.Crypto and BouncyCastle.Cryptography in c# HOT 1
- DefaultTlsServer TLS 1.2 Async Handshake Problems. HOT 1
- Support for ParamSets: TS26-B, TS26-C, TS26-D for GOST34.10-2012-256 HOT 2
- Convert Ed25519PrivateKeyParameters to X25519PrivateKeyParameters HOT 5
- DTLS fragmentation error? HOT 4
- Issues with ECC, S/MIME and BouncyCastle HOT 3
- Warning using Bouncy Castle v.2.3.0 HOT 3
- Release notes for v2.3.0 HOT 2
- SPHINCS+ key info encoding fails HOT 2
- SECG Key Agreement / Key Derivation functions not supported? HOT 4
- RSA/ECB/OAEPWithSHA-256AndMGF1Padding HOT 3
- Set Licence type expression on package info HOT 1
- Allow removal of "Version" header in PGP encryption HOT 6
- Where is IESCipher.ECIESwithAESCBC?
- I need SM9
- `NullReferenceException` error when trying to get a recipient based on `SubjectKeyIdentifier` HOT 1
- Broken space handling in Common Name since version 2.3.0 HOT 1
- CmsEnvelope decryption ECCP256 / AES128CBC failed HOT 2
- PgpPublicKey.RemoveCert can delete wrong items.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bc-csharp.