Skip to content

Commit 53697f0

Browse files
committed
Started abstracting out the CryptographyContext stuff
1 parent ebc9976 commit 53697f0

12 files changed

+1547
-209
lines changed

MimeKit/Cryptography/ApplicationPkcs7Mime.cs

+74-74
Large diffs are not rendered by default.

MimeKit/Cryptography/CryptographyContext.cs

+42-31
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
using System;
2828
using System.IO;
2929
using System.Threading;
30-
using System.Reflection;
3130
using System.Threading.Tasks;
3231
using System.Collections.Generic;
3332

@@ -43,8 +42,8 @@ namespace MimeKit.Cryptography {
4342
public abstract class CryptographyContext : ICryptographyContext
4443
{
4544
const string SubclassAndRegisterFormat = "You need to subclass {0} and then register it with MimeKit.Cryptography.CryptographyContext.Register().";
46-
static Func<SecureMimeContext> SecureMimeContextFactory;
47-
static Func<OpenPgpContext> PgpContextFactory;
45+
static Func<ISecureMimeContext> SecureMimeContextFactory;
46+
static Func<IOpenPgpContext> OpenPgpContextFactory;
4847
static readonly object mutex = new object ();
4948

5049
EncryptionAlgorithm[] encryptionAlgorithmRank;
@@ -715,7 +714,7 @@ public void Dispose ()
715714
/// There are no supported <see cref="CryptographyContext"/>s that support
716715
/// the specified <paramref name="protocol"/>.
717716
/// </exception>
718-
public static CryptographyContext Create (string protocol)
717+
public static ICryptographyContext Create (string protocol)
719718
{
720719
if (protocol == null)
721720
throw new ArgumentNullException (nameof (protocol));
@@ -740,8 +739,8 @@ public static CryptographyContext Create (string protocol)
740739
case "application/pgp-encrypted":
741740
case "application/x-pgp-keys":
742741
case "application/pgp-keys":
743-
if (PgpContextFactory != null)
744-
return PgpContextFactory ();
742+
if (OpenPgpContextFactory != null)
743+
return OpenPgpContextFactory ();
745744

746745
throw new NotSupportedException (string.Format (SubclassAndRegisterFormat, "MimeKit.Cryptography.OpenPgpContext or MimeKit.Cryptography.GnuPGContext"));
747746
default:
@@ -751,20 +750,20 @@ public static CryptographyContext Create (string protocol)
751750
}
752751

753752
/// <summary>
754-
/// Registers a default <see cref="SecureMimeContext"/> or <see cref="OpenPgpContext"/>.
753+
/// Registers a default <see cref="ISecureMimeContext"/> or <see cref="IOpenPgpContext"/>.
755754
/// </summary>
756755
/// <remarks>
757-
/// Registers the specified type as the default <see cref="SecureMimeContext"/> or
758-
/// <see cref="OpenPgpContext"/>.
756+
/// Registers the specified type as the default <see cref="ISecureMimeContext"/> or
757+
/// <see cref="IOpenPgpContext"/> implementation.
759758
/// </remarks>
760-
/// <param name="type">A custom subclass of <see cref="SecureMimeContext"/> or
761-
/// <see cref="OpenPgpContext"/>.</param>
759+
/// <param name="type">A custom class that implements the <see cref="ISecureMimeContext"/> or
760+
/// <see cref="IOpenPgpContext"/> interface.</param>
762761
/// <exception cref="System.ArgumentNullException">
763762
/// <paramref name="type"/> is <c>null</c>.
764763
/// </exception>
765764
/// <exception cref="System.ArgumentException">
766-
/// <para><paramref name="type"/> is not a subclass of
767-
/// <see cref="SecureMimeContext"/> or <see cref="OpenPgpContext"/>.</para>
765+
/// <para><paramref name="type"/> does not implement the <see cref="ISecureMimeContext"/> or
766+
/// <see cref="IOpenPgpContext"/> interface.</para>
768767
/// <para>-or-</para>
769768
/// <para><paramref name="type"/> does not have a parameterless constructor.</para>
770769
/// </exception>
@@ -773,36 +772,48 @@ public static void Register (Type type)
773772
if (type == null)
774773
throw new ArgumentNullException (nameof (type));
775774

775+
if (!type.IsClass || type.IsAbstract)
776+
throw new ArgumentException ("The specified type must be a concrete class.", nameof (type));
777+
776778
var ctor = type.GetConstructor (Array.Empty<Type> ());
777-
var args = Array.Empty<object> ();
778779

779780
if (ctor == null)
780781
throw new ArgumentException ("The specified type must have a parameterless constructor.", nameof (type));
781782

782-
if (type.IsSubclassOf (typeof (SecureMimeContext))) {
783-
lock (mutex) {
784-
SecureMimeContextFactory = () => (SecureMimeContext) ctor.Invoke (args);
783+
var interfaces = type.GetInterfaces ();
784+
bool registered = false;
785+
786+
for (int i = 0; i < interfaces.Length; i++) {
787+
if (interfaces[i] == typeof (ISecureMimeContext)) {
788+
lock (mutex) {
789+
SecureMimeContextFactory = () => (ISecureMimeContext) ctor.Invoke (Array.Empty<object> ());
790+
}
791+
registered = true;
785792
}
786-
} else if (type.IsSubclassOf (typeof (OpenPgpContext))) {
787-
lock (mutex) {
788-
PgpContextFactory = () => (OpenPgpContext) ctor.Invoke (args);
793+
794+
if (interfaces[i] == typeof (IOpenPgpContext)) {
795+
lock (mutex) {
796+
OpenPgpContextFactory = () => (IOpenPgpContext) ctor.Invoke (Array.Empty<object> ());
797+
}
798+
registered = true;
789799
}
790-
} else {
791-
throw new ArgumentException ("The specified type must be a subclass of SecureMimeContext or OpenPgpContext.", nameof (type));
792800
}
801+
802+
if (!registered)
803+
throw new ArgumentException ("The specified type must implement the ISecureMimeContext or IOpenPgpContext interface.", nameof (type));
793804
}
794805

795806
/// <summary>
796-
/// Registers a default <see cref="SecureMimeContext"/> factory.
807+
/// Registers a default <see cref="ISecureMimeContext"/> factory.
797808
/// </summary>
798809
/// <remarks>
799-
/// Registers a factory that will return a new instance of the default <see cref="SecureMimeContext"/>.
810+
/// Registers a factory that will return a new instance of the default <see cref="ISecureMimeContext"/>.
800811
/// </remarks>
801-
/// <param name="factory">A factory that creates a new instance of <see cref="SecureMimeContext"/>.</param>
812+
/// <param name="factory">A factory that creates a new instance of <see cref="ISecureMimeContext"/>.</param>
802813
/// <exception cref="System.ArgumentNullException">
803814
/// <paramref name="factory"/> is <c>null</c>.
804815
/// </exception>
805-
public static void Register (Func<SecureMimeContext> factory)
816+
public static void Register (Func<ISecureMimeContext> factory)
806817
{
807818
if (factory == null)
808819
throw new ArgumentNullException (nameof (factory));
@@ -813,22 +824,22 @@ public static void Register (Func<SecureMimeContext> factory)
813824
}
814825

815826
/// <summary>
816-
/// Registers a default <see cref="OpenPgpContext"/> factory.
827+
/// Registers a default <see cref="IOpenPgpContext"/> factory.
817828
/// </summary>
818829
/// <remarks>
819-
/// Registers a factory that will return a new instance of the default <see cref="OpenPgpContext"/>.
830+
/// Registers a factory that will return a new instance of the default <see cref="IOpenPgpContext"/>.
820831
/// </remarks>
821-
/// <param name="factory">A factory that creates a new instance of <see cref="OpenPgpContext"/>.</param>
832+
/// <param name="factory">A factory that creates a new instance of <see cref="IOpenPgpContext"/>.</param>
822833
/// <exception cref="System.ArgumentNullException">
823834
/// <paramref name="factory"/> is <c>null</c>.
824835
/// </exception>
825-
public static void Register (Func<OpenPgpContext> factory)
836+
public static void Register (Func<IOpenPgpContext> factory)
826837
{
827838
if (factory == null)
828839
throw new ArgumentNullException (nameof (factory));
829840

830841
lock (mutex) {
831-
PgpContextFactory = factory;
842+
OpenPgpContextFactory = factory;
832843
}
833844
}
834845
}

MimeKit/Cryptography/IApplicationPkcs7Mime.cs

+16-16
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ SecureMimeType SecureMimeType {
5252
/// Decompress the compressed-data.
5353
/// </summary>
5454
/// <remarks>
55-
/// Decompresses the compressed-data using the specified <see cref="SecureMimeContext"/>.
55+
/// Decompresses the compressed-data using the specified <see cref="ISecureMimeContext"/>.
5656
/// </remarks>
5757
/// <returns>The decompressed <see cref="MimeEntity"/>.</returns>
5858
/// <param name="ctx">The S/MIME context to use for decompressing.</param>
@@ -72,13 +72,13 @@ SecureMimeType SecureMimeType {
7272
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
7373
/// An error occurred in the cryptographic message syntax subsystem.
7474
/// </exception>
75-
MimeEntity Decompress (SecureMimeContext ctx, CancellationToken cancellationToken = default);
75+
MimeEntity Decompress (ISecureMimeContext ctx, CancellationToken cancellationToken = default);
7676

7777
/// <summary>
7878
/// Asynchronously decompress the compressed-data.
7979
/// </summary>
8080
/// <remarks>
81-
/// Asynchronously decompresses the compressed-data using the specified <see cref="SecureMimeContext"/>.
81+
/// Asynchronously decompresses the compressed-data using the specified <see cref="ISecureMimeContext"/>.
8282
/// </remarks>
8383
/// <returns>The decompressed <see cref="MimeEntity"/>.</returns>
8484
/// <param name="ctx">The S/MIME context to use for decompressing.</param>
@@ -98,13 +98,13 @@ SecureMimeType SecureMimeType {
9898
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
9999
/// An error occurred in the cryptographic message syntax subsystem.
100100
/// </exception>
101-
Task<MimeEntity> DecompressAsync (SecureMimeContext ctx, CancellationToken cancellationToken = default);
101+
Task<MimeEntity> DecompressAsync (ISecureMimeContext ctx, CancellationToken cancellationToken = default);
102102

103103
/// <summary>
104104
/// Decompress the compressed-data.
105105
/// </summary>
106106
/// <remarks>
107-
/// Decompresses the compressed-data using the default <see cref="SecureMimeContext"/>.
107+
/// Decompresses the compressed-data using the default <see cref="ISecureMimeContext"/>.
108108
/// </remarks>
109109
/// <returns>The decompressed <see cref="MimeEntity"/>.</returns>
110110
/// <param name="cancellationToken">The cancellation token.</param>
@@ -126,7 +126,7 @@ SecureMimeType SecureMimeType {
126126
/// Asynchronously decompress the compressed-data.
127127
/// </summary>
128128
/// <remarks>
129-
/// Asynchronously decompresses the compressed-data using the default <see cref="SecureMimeContext"/>.
129+
/// Asynchronously decompresses the compressed-data using the default <see cref="ISecureMimeContext"/>.
130130
/// </remarks>
131131
/// <returns>The decompressed <see cref="MimeEntity"/>.</returns>
132132
/// <param name="cancellationToken">The cancellation token.</param>
@@ -148,7 +148,7 @@ SecureMimeType SecureMimeType {
148148
/// Decrypt the enveloped-data.
149149
/// </summary>
150150
/// <remarks>
151-
/// Decrypts the enveloped-data using the specified <see cref="SecureMimeContext"/>.
151+
/// Decrypts the enveloped-data using the specified <see cref="ISecureMimeContext"/>.
152152
/// </remarks>
153153
/// <returns>The decrypted <see cref="MimeEntity"/>.</returns>
154154
/// <param name="ctx">The S/MIME context to use for decrypting.</param>
@@ -168,13 +168,13 @@ SecureMimeType SecureMimeType {
168168
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
169169
/// An error occurred in the cryptographic message syntax subsystem.
170170
/// </exception>
171-
MimeEntity Decrypt (SecureMimeContext ctx, CancellationToken cancellationToken = default);
171+
MimeEntity Decrypt (ISecureMimeContext ctx, CancellationToken cancellationToken = default);
172172

173173
/// <summary>
174174
/// Asynchronously decrypt the enveloped-data.
175175
/// </summary>
176176
/// <remarks>
177-
/// Asynchronously decrypts the enveloped-data using the specified <see cref="SecureMimeContext"/>.
177+
/// Asynchronously decrypts the enveloped-data using the specified <see cref="ISecureMimeContext"/>.
178178
/// </remarks>
179179
/// <returns>The decrypted <see cref="MimeEntity"/>.</returns>
180180
/// <param name="ctx">The S/MIME context to use for decrypting.</param>
@@ -194,13 +194,13 @@ SecureMimeType SecureMimeType {
194194
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
195195
/// An error occurred in the cryptographic message syntax subsystem.
196196
/// </exception>
197-
Task<MimeEntity> DecryptAsync (SecureMimeContext ctx, CancellationToken cancellationToken = default);
197+
Task<MimeEntity> DecryptAsync (ISecureMimeContext ctx, CancellationToken cancellationToken = default);
198198

199199
/// <summary>
200200
/// Decrypt the enveloped-data.
201201
/// </summary>
202202
/// <remarks>
203-
/// Decrypts the enveloped-data using the default <see cref="SecureMimeContext"/>.
203+
/// Decrypts the enveloped-data using the default <see cref="ISecureMimeContext"/>.
204204
/// </remarks>
205205
/// <returns>The decrypted <see cref="MimeEntity"/>.</returns>
206206
/// <param name="cancellationToken">The cancellation token.</param>
@@ -222,7 +222,7 @@ SecureMimeType SecureMimeType {
222222
/// Asynchronously decrypt the enveloped-data.
223223
/// </summary>
224224
/// <remarks>
225-
/// Asynchronously decrypts the enveloped-data using the default <see cref="SecureMimeContext"/>.
225+
/// Asynchronously decrypts the enveloped-data using the default <see cref="ISecureMimeContext"/>.
226226
/// </remarks>
227227
/// <returns>The decrypted <see cref="MimeEntity"/>.</returns>
228228
/// <param name="cancellationToken">The cancellation token.</param>
@@ -263,7 +263,7 @@ SecureMimeType SecureMimeType {
263263
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
264264
/// An error occurred in the cryptographic message syntax subsystem.
265265
/// </exception>
266-
void Import (SecureMimeContext ctx, CancellationToken cancellationToken = default);
266+
void Import (ISecureMimeContext ctx, CancellationToken cancellationToken = default);
267267

268268
/// <summary>
269269
/// Asynchronously import the certificates contained in the application/pkcs7-mime content.
@@ -289,7 +289,7 @@ SecureMimeType SecureMimeType {
289289
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
290290
/// An error occurred in the cryptographic message syntax subsystem.
291291
/// </exception>
292-
Task ImportAsync (SecureMimeContext ctx, CancellationToken cancellationToken = default);
292+
Task ImportAsync (ISecureMimeContext ctx, CancellationToken cancellationToken = default);
293293

294294
/// <summary>
295295
/// Verify the signed-data and return the unencapsulated <see cref="MimeEntity"/>.
@@ -319,13 +319,13 @@ SecureMimeType SecureMimeType {
319319
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
320320
/// An error occurred in the cryptographic message syntax subsystem.
321321
/// </exception>
322-
DigitalSignatureCollection Verify (SecureMimeContext ctx, out MimeEntity entity, CancellationToken cancellationToken = default);
322+
DigitalSignatureCollection Verify (ISecureMimeContext ctx, out MimeEntity entity, CancellationToken cancellationToken = default);
323323

324324
/// <summary>
325325
/// Verifies the signed-data and returns the unencapsulated <see cref="MimeEntity"/>.
326326
/// </summary>
327327
/// <remarks>
328-
/// Verifies the signed-data using the default <see cref="SecureMimeContext"/> and returns the
328+
/// Verifies the signed-data using the default <see cref="ISecureMimeContext"/> and returns the
329329
/// unencapsulated <see cref="MimeEntity"/>.
330330
/// </remarks>
331331
/// <returns>The list of digital signatures.</returns>

MimeKit/Cryptography/IMultipartEncrypted.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public interface IMultipartEncrypted : IMultipart
5555
/// <para>The multipart is malformed in some way.</para>
5656
/// </exception>
5757
/// <exception cref="System.NotSupportedException">
58-
/// The provided <see cref="OpenPgpContext"/> does not support the protocol parameter.
58+
/// The provided <see cref="IOpenPgpContext"/> does not support the protocol parameter.
5959
/// </exception>
6060
/// <exception cref="PrivateKeyNotFoundException">
6161
/// The private key could not be found to decrypt the encrypted data.
@@ -71,7 +71,7 @@ public interface IMultipartEncrypted : IMultipart
7171
/// <exception cref="System.UnauthorizedAccessException">
7272
/// 3 bad attempts were made to unlock the secret key.
7373
/// </exception>
74-
MimeEntity Decrypt (OpenPgpContext ctx, out DigitalSignatureCollection signatures, CancellationToken cancellationToken = default);
74+
MimeEntity Decrypt (IOpenPgpContext ctx, out DigitalSignatureCollection signatures, CancellationToken cancellationToken = default);
7575

7676
/// <summary>
7777
/// Decrypts the <see cref="IMultipartEncrypted"/> part.
@@ -91,7 +91,7 @@ public interface IMultipartEncrypted : IMultipart
9191
/// <para>The multipart is malformed in some way.</para>
9292
/// </exception>
9393
/// <exception cref="System.NotSupportedException">
94-
/// The provided <see cref="OpenPgpContext"/> does not support the protocol parameter.
94+
/// The provided <see cref="IOpenPgpContext"/> does not support the protocol parameter.
9595
/// </exception>
9696
/// <exception cref="PrivateKeyNotFoundException">
9797
/// The private key could not be found to decrypt the encrypted data.
@@ -107,7 +107,7 @@ public interface IMultipartEncrypted : IMultipart
107107
/// <exception cref="System.UnauthorizedAccessException">
108108
/// 3 bad attempts were made to unlock the secret key.
109109
/// </exception>
110-
MimeEntity Decrypt (OpenPgpContext ctx, CancellationToken cancellationToken = default);
110+
MimeEntity Decrypt (IOpenPgpContext ctx, CancellationToken cancellationToken = default);
111111

112112
/// <summary>
113113
/// Decrypts the <see cref="IMultipartEncrypted"/> part.
@@ -125,7 +125,7 @@ public interface IMultipartEncrypted : IMultipart
125125
/// <para>The multipart is malformed in some way.</para>
126126
/// </exception>
127127
/// <exception cref="System.NotSupportedException">
128-
/// A suitable <see cref="CryptographyContext"/> for
128+
/// A suitable <see cref="ICryptographyContext"/> for
129129
/// decrypting could not be found.
130130
/// </exception>
131131
/// <exception cref="PrivateKeyNotFoundException">
@@ -158,7 +158,7 @@ public interface IMultipartEncrypted : IMultipart
158158
/// <para>The multipart is malformed in some way.</para>
159159
/// </exception>
160160
/// <exception cref="System.NotSupportedException">
161-
/// A suitable <see cref="CryptographyContext"/> for
161+
/// A suitable <see cref="ICryptographyContext"/> for
162162
/// decrypting could not be found.
163163
/// </exception>
164164
/// <exception cref="PrivateKeyNotFoundException">

MimeKit/Cryptography/IMultipartSigned.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public interface IMultipartSigned : IMultipart
6565
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
6666
/// An error occurred in the cryptographic message syntax subsystem.
6767
/// </exception>
68-
DigitalSignatureCollection Verify (CryptographyContext ctx, CancellationToken cancellationToken = default);
68+
DigitalSignatureCollection Verify (ICryptographyContext ctx, CancellationToken cancellationToken = default);
6969

7070
/// <summary>
7171
/// Verify the multipart/signed part.
@@ -94,7 +94,7 @@ public interface IMultipartSigned : IMultipart
9494
/// <exception cref="Org.BouncyCastle.Cms.CmsException">
9595
/// An error occurred in the cryptographic message syntax subsystem.
9696
/// </exception>
97-
Task<DigitalSignatureCollection> VerifyAsync (CryptographyContext ctx, CancellationToken cancellationToken = default);
97+
Task<DigitalSignatureCollection> VerifyAsync (ICryptographyContext ctx, CancellationToken cancellationToken = default);
9898

9999
/// <summary>
100100
/// Verify the multipart/signed part.

0 commit comments

Comments
 (0)