diff --git a/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs b/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
index 1fb8ff37..db06c0ad 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
@@ -9,8 +9,6 @@ using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using JetBrains.Annotations;
@@ -189,179 +187,6 @@ namespace Microsoft.Extensions.DependencyInjection
key.CryptoProviderFactory.IsSupportedAlgorithm(algorithm, key);
}
- ///
- /// Registers (and generates if necessary) a user-specific development
- /// certificate used to decrypt the tokens issued by OpenIddict.
- ///
- /// The .
- public OpenIddictValidationBuilder AddDevelopmentEncryptionCertificate()
- => AddDevelopmentEncryptionCertificate(new X500DistinguishedName("CN=OpenIddict Validation Encryption Certificate"));
-
- ///
- /// Registers (and generates if necessary) a user-specific development
- /// certificate used to decrypt the tokens issued by OpenIddict.
- ///
- /// The subject name associated with the certificate.
- /// The .
- public OpenIddictValidationBuilder AddDevelopmentEncryptionCertificate([NotNull] X500DistinguishedName subject)
- {
- if (subject == null)
- {
- throw new ArgumentNullException(nameof(subject));
- }
-
- using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
- store.Open(OpenFlags.ReadWrite);
-
- // Try to retrieve the development certificate from the specified store.
- // If a certificate was found but is not yet or no longer valid, remove it
- // from the store before creating and persisting a new encryption certificate.
- var certificate = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, subject.Name, validOnly: false)
- .OfType()
- .SingleOrDefault();
-
- if (certificate != null && (certificate.NotBefore > DateTime.Now || certificate.NotAfter < DateTime.Now))
- {
- store.Remove(certificate);
- certificate = null;
- }
-
-#if SUPPORTS_CERTIFICATE_GENERATION
- // If no appropriate certificate can be found, generate and persist a new certificate in the specified store.
- if (certificate == null)
- {
- using var algorithm = RSA.Create(keySizeInBits: 2048);
-
- var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
- request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true));
-
- certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2));
-
- // Note: setting the friendly name is not supported on Unix machines (including Linux and macOS).
- // To ensure an exception is not thrown by the property setter, an OS runtime check is used here.
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- certificate.FriendlyName = "OpenIddict Validation Development Encryption Certificate";
- }
-
- // Note: CertificateRequest.CreateSelfSigned() doesn't mark the key set associated with the certificate
- // as "persisted", which eventually prevents X509Store.Add() from correctly storing the private key.
- // To work around this issue, the certificate payload is manually exported and imported back
- // into a new X509Certificate2 instance specifying the X509KeyStorageFlags.PersistKeySet flag.
- var data = certificate.Export(X509ContentType.Pfx, string.Empty);
-
- try
- {
- var flags = X509KeyStorageFlags.PersistKeySet;
-
- // Note: macOS requires marking the certificate private key as exportable.
- // If this flag is not set, a CryptographicException is thrown at runtime.
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- flags |= X509KeyStorageFlags.Exportable;
- }
-
- certificate = new X509Certificate2(data, string.Empty, flags);
- }
-
- finally
- {
- Array.Clear(data, 0, data.Length);
- }
-
- store.Add(certificate);
- }
-
- return AddEncryptionCertificate(certificate);
-#else
- throw new PlatformNotSupportedException("X.509 certificate generation is not supported on this platform.");
-#endif
- }
-
- ///
- /// Registers a new ephemeral key used to decrypt the tokens issued by OpenIddict: the key
- /// is discarded when the application shuts down and tokens encrypted using this key are
- /// automatically invalidated. This method should only be used during development.
- /// On production, using a X.509 certificate stored in the machine store is recommended.
- ///
- /// The .
- public OpenIddictValidationBuilder AddEphemeralEncryptionKey()
- => AddEphemeralEncryptionKey(SecurityAlgorithms.RsaOAEP);
-
- ///
- /// Registers a new ephemeral key used to decrypt the tokens issued by OpenIddict: the key
- /// is discarded when the application shuts down and tokens encrypted using this key are
- /// automatically invalidated. This method should only be used during development.
- /// On production, using a X.509 certificate stored in the machine store is recommended.
- ///
- /// The algorithm associated with the encryption key.
- /// The .
- public OpenIddictValidationBuilder AddEphemeralEncryptionKey([NotNull] string algorithm)
- {
- if (string.IsNullOrEmpty(algorithm))
- {
- throw new ArgumentException("The algorithm cannot be null or empty.", nameof(algorithm));
- }
-
- switch (algorithm)
- {
- case SecurityAlgorithms.Aes256KW:
- return AddEncryptionCredentials(new EncryptingCredentials(CreateSymmetricSecurityKey(256),
- algorithm, SecurityAlgorithms.Aes256CbcHmacSha512));
-
- case SecurityAlgorithms.RsaOAEP:
- case SecurityAlgorithms.RsaOaepKeyWrap:
- return AddEncryptionCredentials(new EncryptingCredentials(CreateRsaSecurityKey(2048),
- algorithm, SecurityAlgorithms.Aes256CbcHmacSha512));
-
- default: throw new InvalidOperationException("The specified algorithm is not supported.");
- }
-
- static SymmetricSecurityKey CreateSymmetricSecurityKey(int size)
- {
- var data = new byte[size / 8];
-
-#if SUPPORTS_STATIC_RANDOM_NUMBER_GENERATOR_METHODS
- RandomNumberGenerator.Fill(data);
-#else
- using var generator = RandomNumberGenerator.Create();
- generator.GetBytes(data);
-#endif
-
- return new SymmetricSecurityKey(data);
- }
-
- static RsaSecurityKey CreateRsaSecurityKey(int size)
- {
-#if SUPPORTS_DIRECT_KEY_CREATION_WITH_SPECIFIED_SIZE
- return new RsaSecurityKey(RSA.Create(size));
-#else
- // Note: a 1024-bit key might be returned by RSA.Create() on .NET Desktop/Mono,
- // where RSACryptoServiceProvider is still the default implementation and
- // where custom implementations can be registered via CryptoConfig.
- // To ensure the key size is always acceptable, replace it if necessary.
- var algorithm = RSA.Create();
- if (algorithm.KeySize < size)
- {
- algorithm.KeySize = size;
- }
-
- if (algorithm.KeySize < size && algorithm is RSACryptoServiceProvider)
- {
- algorithm.Dispose();
- algorithm = new RSACryptoServiceProvider(size);
- }
-
- if (algorithm.KeySize < size)
- {
- throw new InvalidOperationException("RSA key generation failed.");
- }
-
- return new RsaSecurityKey(algorithm);
-#endif
- }
- }
-
///
/// Registers a that is used to decrypt the tokens issued by OpenIddict.
///