Skip to content

Commit 36a4eb8

Browse files
committed
Added EllipticCurve S/MIME unit tests and fixed bugs that resulted
Completes the fix for issue #998
1 parent bc0c227 commit 36a4eb8

25 files changed

+2057
-1693
lines changed

MimeKit/Cryptography/BouncyCastleSecureMimeContext.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,17 +1327,17 @@ void CmsEnvelopeAddEllipticCurve (CmsEnvelopedDataGenerator cms, CmsRecipient re
13271327
var subjectKeyIdentifier = recipient.Certificate.GetExtensionValue (X509Extensions.SubjectKeyIdentifier);
13281328
cms.AddKeyAgreementRecipient (
13291329
CmsEnvelopedGenerator.ECDHSha1Kdf,
1330-
keyPair.Public,
13311330
keyPair.Private,
1331+
keyPair.Public,
13321332
subjectKeyIdentifier.GetOctets (),
13331333
publicKey,
13341334
CmsEnvelopedGenerator.Aes128Wrap
13351335
);
13361336
} else {
13371337
cms.AddKeyAgreementRecipient (
13381338
CmsEnvelopedGenerator.ECDHSha1Kdf,
1339-
keyPair.Public,
13401339
keyPair.Private,
1340+
keyPair.Public,
13411341
certificate,
13421342
CmsEnvelopedGenerator.Aes128Wrap
13431343
);
@@ -1355,7 +1355,7 @@ Stream Envelope (CmsRecipientCollection recipients, Stream content, Cancellation
13551355
var certificate = recipient.Certificate;
13561356
var pub = certificate.GetPublicKey ();
13571357

1358-
if (pub is RsaKeyParameters || pub is DsaKeyParameters) {
1358+
if (pub is RsaKeyParameters) {
13591359
// Bouncy Castle dispatches OAEP based on the certificate type. However, MimeKit users
13601360
// expect to be able to specify the use of OAEP in S/MIME with certificates that have
13611361
// PKCS#1v1.5 OIDs as these tend to be more broadly compatible across the ecosystem.
@@ -1366,7 +1366,7 @@ Stream Envelope (CmsRecipientCollection recipients, Stream content, Cancellation
13661366
} else {
13671367
var oid = certificate.SubjectPublicKeyInfo.Algorithm.Algorithm.ToString ();
13681368

1369-
throw new ArgumentException ($"Unknown type of recipient certificate: {pub.GetType ().Name} (SubjectPublicKeyInfo OID = {oid})");
1369+
throw new NotSupportedException ($"Unsupported type of recipient certificate: {pub.GetType ().Name} (SubjectPublicKeyInfo OID = {oid})");
13701370
}
13711371

13721372
count++;

MimeKit/Cryptography/DefaultSecureMimeContext.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -615,17 +615,20 @@ public override void Import (X509Certificate2 certificate, CancellationToken can
615615
X509CertificateRecord record;
616616

617617
if ((record = dbase.Find (cert, ImportPkcs12Fields)) == null) {
618-
record = new X509CertificateRecord (cert, privateKey) {
619-
Algorithms = EnabledEncryptionAlgorithms,
620-
AlgorithmsUpdated = DateTime.UtcNow,
621-
IsTrusted = true
622-
};
618+
if (privateKey != null)
619+
record = new X509CertificateRecord (cert, privateKey);
620+
else
621+
record = new X509CertificateRecord (cert);
622+
623+
record.Algorithms = EnabledEncryptionAlgorithms;
624+
record.AlgorithmsUpdated = DateTime.UtcNow;
625+
record.IsTrusted = privateKey != null;
623626
dbase.Add (record);
624627
} else {
625628
record.AlgorithmsUpdated = DateTime.UtcNow;
626629
record.Algorithms = EnabledEncryptionAlgorithms;
627630
record.PrivateKey ??= privateKey;
628-
record.IsTrusted = true;
631+
record.IsTrusted = record.IsTrusted || privateKey != null;
629632
dbase.Update (record, ImportPkcs12Fields);
630633
}
631634
} else {

MimeKit/Cryptography/X509Certificate2Extensions.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,22 @@ public static AsymmetricKeyParameter GetPrivateKeyAsAsymmetricKeyParameter (this
172172
throw new ArgumentNullException (nameof (certificate));
173173

174174
#if NET6_0_OR_GREATER
175-
AsymmetricAlgorithm privateKey;
175+
AsymmetricAlgorithm privateKey = null;
176176

177-
privateKey = certificate.GetRSAPrivateKey ();
178-
privateKey ??= certificate.GetDSAPrivateKey ();
179-
privateKey ??= certificate.GetECDsaPrivateKey ();
180-
privateKey ??= certificate.GetECDiffieHellmanPrivateKey ();
177+
if (certificate.HasPrivateKey) {
178+
switch (GetPublicKeyAlgorithm (certificate)) {
179+
case PublicKeyAlgorithm.Dsa:
180+
privateKey = certificate.GetDSAPrivateKey ();
181+
break;
182+
case PublicKeyAlgorithm.RsaGeneral:
183+
privateKey = certificate.GetRSAPrivateKey ();
184+
break;
185+
case PublicKeyAlgorithm.EllipticCurve:
186+
//privateKey = certificate.GetECDsaPrivateKey ();
187+
privateKey = certificate.GetECDiffieHellmanPrivateKey ();
188+
break;
189+
}
190+
}
181191

182192
return privateKey?.AsAsymmetricKeyParameter ();
183193
#else

0 commit comments

Comments
 (0)