// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Security.Cryptography.X509Certificates; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.DataProtection { /// /// Contains factory methods for creating an where keys are stored /// at a particular location on the file system. /// /// Use these methods when not using dependency injection to provide the service to the application. public static class DataProtectionProvider { /// /// Creates a that store keys in a location based on /// the platform and operating system. /// /// An identifier that uniquely discriminates this application from all other /// applications on the machine. public static IDataProtectionProvider Create(string applicationName) { if (string.IsNullOrEmpty(applicationName)) { throw new ArgumentNullException(nameof(applicationName)); } return CreateProvider( keyDirectory: null, setupAction: builder => { builder.SetApplicationName(applicationName); }, certificate: null); } /// /// Creates an given a location at which to store keys. /// /// The in which keys should be stored. This may /// represent a directory on a local disk or a UNC share. public static IDataProtectionProvider Create(DirectoryInfo keyDirectory) { if (keyDirectory == null) { throw new ArgumentNullException(nameof(keyDirectory)); } return CreateProvider(keyDirectory, setupAction: builder => { }, certificate: null); } /// /// Creates an given a location at which to store keys and an /// optional configuration callback. /// /// The in which keys should be stored. This may /// represent a directory on a local disk or a UNC share. /// An optional callback which provides further configuration of the data protection /// system. See for more information. public static IDataProtectionProvider Create( DirectoryInfo keyDirectory, Action setupAction) { if (keyDirectory == null) { throw new ArgumentNullException(nameof(keyDirectory)); } if (setupAction == null) { throw new ArgumentNullException(nameof(setupAction)); } return CreateProvider(keyDirectory, setupAction, certificate: null); } #if !NETSTANDARD1_3 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml /// /// Creates a that store keys in a location based on /// the platform and operating system and uses the given to encrypt the keys. /// /// An identifier that uniquely discriminates this application from all other /// applications on the machine. /// The to be used for encryption. public static IDataProtectionProvider Create(string applicationName, X509Certificate2 certificate) { if (string.IsNullOrEmpty(applicationName)) { throw new ArgumentNullException(nameof(applicationName)); } if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } return CreateProvider( keyDirectory: null, setupAction: builder => { builder.SetApplicationName(applicationName); }, certificate: certificate); } /// /// Creates an given a location at which to store keys /// and a used to encrypt the keys. /// /// The in which keys should be stored. This may /// represent a directory on a local disk or a UNC share. /// The to be used for encryption. public static IDataProtectionProvider Create( DirectoryInfo keyDirectory, X509Certificate2 certificate) { if (keyDirectory == null) { throw new ArgumentNullException(nameof(keyDirectory)); } if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } return CreateProvider(keyDirectory, setupAction: builder => { }, certificate: certificate); } /// /// Creates an given a location at which to store keys, an /// optional configuration callback and a used to encrypt the keys. /// /// The in which keys should be stored. This may /// represent a directory on a local disk or a UNC share. /// An optional callback which provides further configuration of the data protection /// system. See for more information. /// The to be used for encryption. public static IDataProtectionProvider Create( DirectoryInfo keyDirectory, Action setupAction, X509Certificate2 certificate) { if (keyDirectory == null) { throw new ArgumentNullException(nameof(keyDirectory)); } if (setupAction == null) { throw new ArgumentNullException(nameof(setupAction)); } if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } return CreateProvider(keyDirectory, setupAction, certificate); } #endif private static IDataProtectionProvider CreateProvider( DirectoryInfo keyDirectory, Action setupAction, X509Certificate2 certificate) { // build the service collection var serviceCollection = new ServiceCollection(); var builder = serviceCollection.AddDataProtection(); if (keyDirectory != null) { builder.PersistKeysToFileSystem(keyDirectory); } #if !NETSTANDARD1_3 // [[ISSUE60]] Remove this #ifdef when Core CLR gets support for EncryptedXml if (certificate != null) { builder.ProtectKeysWithCertificate(certificate); } #endif setupAction(builder); // extract the provider instance from the service collection return serviceCollection.BuildServiceProvider().GetRequiredService(); } } }