├── .appveyor.yml ├── .gitattributes ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── .vscode └── launch.json ├── .vsts-pipelines └── builds │ └── ci-public.yml ├── CONTRIBUTING.md ├── DataProtection.sln ├── DataProtection.sln.DotSettings ├── Directory.Build.props ├── Directory.Build.targets ├── LICENSE.txt ├── NuGet.config ├── NuGetPackageVerifier.json ├── Provision-AutoGenKeys.ps1 ├── README.md ├── build.cmd ├── build.sh ├── build ├── Key.snk ├── dependencies.props ├── repo.props └── sources.props ├── korebuild-lock.txt ├── korebuild.json ├── run.cmd ├── run.ps1 ├── run.sh ├── samples ├── AzureBlob │ ├── AzureBlob.csproj │ └── Program.cs ├── AzureKeyVault │ ├── AzureKeyVault.csproj │ ├── Program.cs │ └── settings.json ├── CustomEncryptorSample │ ├── CustomBuilderExtensions.cs │ ├── CustomEncryptorSample.csproj │ ├── CustomXmlDecryptor.cs │ ├── CustomXmlEncryptor.cs │ └── Program.cs ├── EntityFrameworkCoreSample │ ├── EntityFrameworkCoreSample.csproj │ └── Program.cs ├── KeyManagementSample │ ├── KeyManagementSample.csproj │ └── Program.cs ├── NonDISample │ ├── NonDISample.csproj │ └── Program.cs └── Redis │ ├── Program.cs │ └── Redis.csproj ├── shared ├── EncodingUtil.cs └── ExceptionExtensions.cs ├── src ├── Directory.Build.props ├── Microsoft.AspNetCore.Cryptography.Internal │ ├── Cng │ │ ├── BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.cs │ │ ├── BCRYPT_KEY_LENGTHS_STRUCT.cs │ │ ├── BCryptBuffer.cs │ │ ├── BCryptBufferDesc.cs │ │ ├── BCryptEncryptFlags.cs │ │ ├── BCryptGenRandomFlags.cs │ │ ├── BCryptKeyDerivationBufferType.cs │ │ ├── BCryptUtil.cs │ │ ├── CachedAlgorithmHandles.cs │ │ ├── NCryptEncryptFlags.cs │ │ └── OSVersionUtil.cs │ ├── Constants.cs │ ├── CryptoUtil.cs │ ├── DATA_BLOB.cs │ ├── Microsoft.AspNetCore.Cryptography.Internal.csproj │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ ├── Resources.resx │ ├── SafeHandles │ │ ├── BCryptAlgorithmHandle.cs │ │ ├── BCryptHandle.cs │ │ ├── BCryptHashHandle.cs │ │ ├── BCryptKeyHandle.cs │ │ ├── LocalAllocHandle.cs │ │ ├── NCryptDescriptorHandle.cs │ │ ├── SafeLibraryHandle.cs │ │ └── SecureLocalAllocHandle.cs │ ├── UnsafeBufferUtil.cs │ ├── UnsafeNativeMethods.cs │ ├── WeakReferenceHelpers.cs │ └── baseline.netcore.json ├── Microsoft.AspNetCore.Cryptography.KeyDerivation │ ├── KeyDerivation.cs │ ├── KeyDerivationPrf.cs │ ├── Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj │ ├── PBKDF2 │ │ ├── IPbkdf2Provider.cs │ │ ├── ManagedPbkdf2Provider.cs │ │ ├── NetCorePbkdf2Provider.cs │ │ ├── Pbkdf2Util.cs │ │ ├── Win7Pbkdf2Provider.cs │ │ └── Win8Pbkdf2Provider.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── baseline.netcore.json ├── Microsoft.AspNetCore.DataProtection.Abstractions │ ├── CryptoUtil.cs │ ├── DataProtectionCommonExtensions.cs │ ├── Error.cs │ ├── IDataProtectionProvider.cs │ ├── IDataProtector.cs │ ├── Infrastructure │ │ └── IApplicationDiscriminator.cs │ ├── Microsoft.AspNetCore.DataProtection.Abstractions.csproj │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ ├── Resources.resx │ └── baseline.netcore.json ├── Microsoft.AspNetCore.DataProtection.AzureKeyVault │ ├── AzureDataProtectionBuilderExtensions.cs │ ├── AzureKeyVaultXmlDecryptor.cs │ ├── AzureKeyVaultXmlEncryptor.cs │ ├── IKeyVaultWrappingClient.cs │ ├── KeyVaultClientWrapper.cs │ ├── Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj │ └── Properties │ │ └── AssemblyInfo.cs ├── Microsoft.AspNetCore.DataProtection.AzureStorage │ ├── AzureBlobXmlRepository.cs │ ├── AzureDataProtectionBuilderExtensions.cs │ ├── Microsoft.AspNetCore.DataProtection.AzureStorage.csproj │ └── baseline.netcore.json ├── Microsoft.AspNetCore.DataProtection.EntityFrameworkCore │ ├── DataProtectionKey.cs │ ├── EntityFrameworkCoreDataProtectionExtensions.cs │ ├── EntityFrameworkCoreXmlRepository.cs │ ├── IDataProtectionKeyContext.cs │ ├── LoggingExtensions.cs │ ├── Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj │ └── baseline.netcore.json ├── Microsoft.AspNetCore.DataProtection.Extensions │ ├── BitHelpers.cs │ ├── DataProtectionAdvancedExtensions.cs │ ├── DataProtectionProvider.cs │ ├── ITimeLimitedDataProtector.cs │ ├── Microsoft.AspNetCore.DataProtection.Extensions.csproj │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ ├── Resources.resx │ ├── TimeLimitedDataProtector.cs │ └── baseline.netcore.json ├── Microsoft.AspNetCore.DataProtection.StackExchangeRedis │ ├── Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj │ ├── RedisDataProtectionBuilderExtensions.cs │ └── RedisXmlRepository.cs ├── Microsoft.AspNetCore.DataProtection.SystemWeb │ ├── CompatibilityDataProtector.cs │ ├── DataProtectionStartup.cs │ ├── Microsoft.AspNetCore.DataProtection.SystemWeb.csproj │ ├── Properties │ │ └── Resources.Designer.cs │ ├── Resources.resx │ ├── baseline.netframework.json │ └── web.config.transform └── Microsoft.AspNetCore.DataProtection │ ├── ActivatorExtensions.cs │ ├── ApplyPolicyAttribute.cs │ ├── ArraySegmentExtensions.cs │ ├── AuthenticatedEncryption │ ├── AlgorithmAssert.cs │ ├── AuthenticatedEncryptorExtensions.cs │ ├── AuthenticatedEncryptorFactory.cs │ ├── CngCbcAuthenticatedEncryptorFactory.cs │ ├── CngGcmAuthenticatedEncryptorFactory.cs │ ├── ConfigurationModel │ │ ├── AlgorithmConfiguration.cs │ │ ├── AuthenticatedEncryptorConfiguration.cs │ │ ├── AuthenticatedEncryptorDescriptor.cs │ │ ├── AuthenticatedEncryptorDescriptorDeserializer.cs │ │ ├── CngCbcAuthenticatedEncryptorConfiguration.cs │ │ ├── CngCbcAuthenticatedEncryptorDescriptor.cs │ │ ├── CngCbcAuthenticatedEncryptorDescriptorDeserializer.cs │ │ ├── CngGcmAuthenticatedEncryptorConfiguration.cs │ │ ├── CngGcmAuthenticatedEncryptorDescriptor.cs │ │ ├── CngGcmAuthenticatedEncryptorDescriptorDeserializer.cs │ │ ├── IAuthenticatedEncryptorDescriptor.cs │ │ ├── IAuthenticatedEncryptorDescriptorDeserializer.cs │ │ ├── IInternalAlgorithmConfiguration.cs │ │ ├── ManagedAuthenticatedEncryptorConfiguration.cs │ │ ├── ManagedAuthenticatedEncryptorDescriptor.cs │ │ ├── ManagedAuthenticatedEncryptorDescriptorDeserializer.cs │ │ ├── SecretExtensions.cs │ │ ├── XmlExtensions.cs │ │ └── XmlSerializedDescriptorInfo.cs │ ├── EncryptionAlgorithm.cs │ ├── IAuthenticatedEncryptor.cs │ ├── IAuthenticatedEncryptorFactory.cs │ ├── IOptimizedAuthenticatedEncryptor.cs │ ├── ManagedAuthenticatedEncryptorFactory.cs │ └── ValidationAlgorithm.cs │ ├── BitHelpers.cs │ ├── Cng │ ├── BCryptGenRandomImpl.cs │ ├── CbcAuthenticatedEncryptor.cs │ ├── DpapiSecretSerializerHelper.cs │ ├── GcmAuthenticatedEncryptor.cs │ ├── IBCryptGenRandom.cs │ └── Internal │ │ └── CngAuthenticatedEncryptorBase.cs │ ├── DataProtectionBuilderExtensions.cs │ ├── DataProtectionOptions.cs │ ├── DataProtectionServiceCollectionExtensions.cs │ ├── DataProtectionUtilityExtensions.cs │ ├── EphemeralDataProtectionProvider.cs │ ├── Error.cs │ ├── IDataProtectionBuilder.cs │ ├── IPersistedDataProtector.cs │ ├── IRegistryPolicyResolver.cs │ ├── ISecret.cs │ ├── Internal │ ├── DataProtectionBuilder.cs │ ├── DataProtectionOptionsSetup.cs │ ├── DataProtectionStartupFilter.cs │ ├── DockerUtils.cs │ ├── HostingApplicationDiscriminator.cs │ ├── IActivator.cs │ └── KeyManagementOptionsSetup.cs │ ├── KeyManagement │ ├── DefaultKeyResolver.cs │ ├── DeferredKey.cs │ ├── IKey.cs │ ├── IKeyEscrowSink.cs │ ├── IKeyManager.cs │ ├── Internal │ │ ├── CacheableKeyRing.cs │ │ ├── DefaultKeyResolution.cs │ │ ├── ICacheableKeyRingProvider.cs │ │ ├── IDefaultKeyResolver.cs │ │ ├── IInternalXmlKeyManager.cs │ │ ├── IKeyRing.cs │ │ └── IKeyRingProvider.cs │ ├── Key.cs │ ├── KeyBase.cs │ ├── KeyEscrowServiceProviderExtensions.cs │ ├── KeyExtensions.cs │ ├── KeyManagementOptions.cs │ ├── KeyRing.cs │ ├── KeyRingBasedDataProtectionProvider.cs │ ├── KeyRingBasedDataProtector.cs │ ├── KeyRingProvider.cs │ └── XmlKeyManager.cs │ ├── LoggingExtensions.cs │ ├── LoggingServiceProviderExtensions.cs │ ├── Managed │ ├── HashAlgorithmExtensions.cs │ ├── IManagedGenRandom.cs │ ├── ManagedAuthenticatedEncryptor.cs │ ├── ManagedGenRandomImpl.cs │ └── SymmetricAlgorithmExtensions.cs │ ├── MemoryProtection.cs │ ├── Microsoft.AspNetCore.DataProtection.csproj │ ├── Properties │ ├── AssemblyInfo.cs │ └── Resources.Designer.cs │ ├── RegistryPolicy.cs │ ├── RegistryPolicyResolver.cs │ ├── Repositories │ ├── DefaultKeyStorageDirectories.cs │ ├── EphemeralXmlRepository.cs │ ├── FileSystemXmlRepository.cs │ ├── IDefaultKeyStorageDirectory.cs │ ├── IXmlRepository.cs │ └── RegistryXmlRepository.cs │ ├── Resources.resx │ ├── SP800_108 │ ├── ISP800_108_CTR_HMACSHA512Provider.cs │ ├── ManagedSP800_108_CTR_HMACSHA512.cs │ ├── SP800_108_CTR_HMACSHA512Extensions.cs │ ├── SP800_108_CTR_HMACSHA512Util.cs │ ├── Win7SP800_108_CTR_HMACSHA512Provider.cs │ └── Win8SP800_108_CTR_HMACSHA512Provider.cs │ ├── Secret.cs │ ├── SimpleActivator.cs │ ├── TypeExtensions.cs │ ├── TypeForwardingActivator.cs │ ├── XmlConstants.cs │ ├── XmlEncryption │ ├── CertificateResolver.cs │ ├── CertificateXmlEncryptor.cs │ ├── DpapiNGProtectionDescriptorFlags.cs │ ├── DpapiNGXmlDecryptor.cs │ ├── DpapiNGXmlEncryptor.cs │ ├── DpapiXmlDecryptor.cs │ ├── DpapiXmlEncryptor.cs │ ├── EncryptedXmlDecryptor.cs │ ├── EncryptedXmlInfo.cs │ ├── ICertificateResolver.cs │ ├── IInternalCertificateXmlEncryptor.cs │ ├── IInternalEncryptedXmlDecryptor.cs │ ├── IXmlDecryptor.cs │ ├── IXmlEncryptor.cs │ ├── NullXmlDecryptor.cs │ ├── NullXmlEncryptor.cs │ ├── XmlEncryptionExtensions.cs │ └── XmlKeyDecryptionOptions.cs │ ├── XmlExtensions.cs │ └── baseline.netcore.json ├── test ├── CreateTestCert.ps1 ├── Directory.Build.props ├── Microsoft.AspNetCore.Cryptography.Internal.Test │ ├── Cng │ │ ├── BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_Tests.cs │ │ ├── BCRYPT_KEY_LENGTHS_STRUCT_Tests.cs │ │ ├── BCryptUtilTests.cs │ │ └── CachedAlgorithmHandlesTests.cs │ ├── CryptoUtilTests.cs │ ├── Microsoft.AspNetCore.Cryptography.Internal.Test.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SafeHandles │ │ └── SecureLocalAllocHandleTests.cs │ ├── UnsafeBufferUtilTests.cs │ └── WeakReferenceHelpersTests.cs ├── Microsoft.AspNetCore.Cryptography.KeyDerivation.Test │ ├── Microsoft.AspNetCore.Cryptography.KeyDerivation.Test.csproj │ ├── Pbkdf2Tests.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── Microsoft.AspNetCore.DataProtection.Abstractions.Test │ ├── DataProtectionCommonExtensionsTests.cs │ └── Microsoft.AspNetCore.DataProtection.Abstractions.Test.csproj ├── Microsoft.AspNetCore.DataProtection.AzureKeyVault.Test │ ├── AzureKeyVaultXmlEncryptorTests.cs │ └── Microsoft.AspNetCore.DataProtection.AzureKeyVault.Test.csproj ├── Microsoft.AspNetCore.DataProtection.AzureStorage.Test │ ├── AzureBlobXmlRepositoryTests.cs │ ├── AzureDataProtectionBuilderExtensionsTest.cs │ └── Microsoft.AspNetCore.DataProtection.AzureStorage.Test.csproj ├── Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test │ ├── DataProtectionEntityFrameworkTests.cs │ ├── DataProtectionKeyContext.cs │ ├── EntityFrameworkCoreDataProtectionBuilderExtensionsTests.cs │ └── Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test.csproj ├── Microsoft.AspNetCore.DataProtection.Extensions.Test │ ├── DataProtectionAdvancedExtensionsTests.cs │ ├── DataProtectionProviderTests.cs │ ├── Microsoft.AspNetCore.DataProtection.Extensions.Test.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── TestFiles │ │ ├── TestCert.pfx │ │ ├── TestCert2.pfx │ │ ├── TestCert3.pfx │ │ ├── TestCert3WithoutPrivateKey.pfx │ │ └── TestCertWithoutPrivateKey.pfx │ ├── TimeLimitedDataProtectorTests.cs │ └── X509StoreIsAvailableAttribute.cs ├── Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test │ ├── DataProtectionRedisTests.cs │ ├── Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test.csproj │ ├── RedisDataProtectionBuilderExtensionsTest.cs │ ├── TestRedisServer.cs │ ├── TestRedisServerIsAvailableAttribute.cs │ └── testconfig.json ├── Microsoft.AspNetCore.DataProtection.Test │ ├── ActivatorTests.cs │ ├── AnonymousImpersonation.cs │ ├── AuthenticatedEncryption │ │ ├── CngCbcAuthenticatedEncryptorFactoryTest.cs │ │ ├── CngGcmAuthenticatedEncryptorFactoryTest.cs │ │ ├── ConfigurationModel │ │ │ ├── AuthenticatedEncryptorDescriptorDeserializerTests.cs │ │ │ ├── AuthenticatedEncryptorDescriptorTests.cs │ │ │ ├── CngCbcAuthenticatedEncryptorConfigurationTests.cs │ │ │ ├── CngCbcAuthenticatedEncryptorDescriptorDeserializerTests.cs │ │ │ ├── CngCbcAuthenticatedEncryptorDescriptorTests.cs │ │ │ ├── CngGcmAuthenticatedEncryptorConfigurationTests.cs │ │ │ ├── CngGcmAuthenticatedEncryptorDescriptorDeserializerTests.cs │ │ │ ├── CngGcmAuthenticatedEncryptorDescriptorTests.cs │ │ │ ├── ManagedAuthenticatedEncryptorConfigurationTests.cs │ │ │ ├── ManagedAuthenticatedEncryptorDescriptorDeserializerTests.cs │ │ │ └── ManagedAuthenticatedEncryptorDescriptorTests.cs │ │ └── ManagedAuthenticatedEncryptorFactoryTest.cs │ ├── Cng │ │ ├── CbcAuthenticatedEncryptorTests.cs │ │ ├── CngAuthenticatedEncryptorBaseTests.cs │ │ └── GcmAuthenticatedEncryptorTests.cs │ ├── DataProtectionUtilityExtensionsTests.cs │ ├── DockerUtilsTests.cs │ ├── EphemeralDataProtectionProviderTests.cs │ ├── HostingTests.cs │ ├── Internal │ │ └── KeyManagementOptionsSetupTest.cs │ ├── KeyManagement │ │ ├── CacheableKeyRingTests.cs │ │ ├── DefaultKeyResolverTests.cs │ │ ├── DeferredKeyTests.cs │ │ ├── KeyEscrowServiceProviderExtensionsTests.cs │ │ ├── KeyRingBasedDataProtectorTests.cs │ │ ├── KeyRingProviderTests.cs │ │ ├── KeyRingTests.cs │ │ ├── KeyTests.cs │ │ └── XmlKeyManagerTests.cs │ ├── Managed │ │ └── ManagedAuthenticatedEncryptorTests.cs │ ├── Microsoft.AspNetCore.DataProtection.Test.csproj │ ├── MockExtensions.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RegistryPolicyResolverTests.cs │ ├── Repositories │ │ ├── EphemeralXmlRepositoryTests.cs │ │ ├── FileSystemXmlRepositoryTests.cs │ │ └── RegistryXmlRepositoryTests.cs │ ├── SP800_108 │ │ └── SP800_108Tests.cs │ ├── SecretAssert.cs │ ├── SecretTests.cs │ ├── SequentialGenRandom.cs │ ├── ServiceCollectionTests.cs │ ├── StringLoggerFactory.cs │ ├── TestFiles │ │ ├── TestCert1.PublicKeyOnly.cer │ │ ├── TestCert1.pfx │ │ └── TestCert2.pfx │ ├── TypeForwardingActivatorTests.cs │ ├── XmlAssert.cs │ └── XmlEncryption │ │ ├── CertificateXmlEncryptionTests.cs │ │ ├── DpapiNGXmlEncryptionTests.cs │ │ ├── DpapiXmlEncryptionTests.cs │ │ ├── EncryptedXmlDecryptorTests.cs │ │ ├── NullXmlEncryptionTests.cs │ │ └── XmlEncryptionExtensionsTests.cs └── shared │ ├── ConditionalRunTestOnlyWindows8OrLaterAttribute.cs │ ├── ConditionalRunTestOnlyWindowsAttribute.cs │ └── ExceptionAssert2.cs └── version.props /.appveyor.yml: -------------------------------------------------------------------------------- 1 | init: 2 | - git config --global core.autocrlf true 3 | branches: 4 | only: 5 | - master 6 | - /^release\/.*$/ 7 | - /^(.*\/)?ci-.*$/ 8 | build_script: 9 | - ps: .\run.ps1 default-build 10 | clone_depth: 1 11 | environment: 12 | global: 13 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true 14 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 15 | test: 'off' 16 | deploy: 'off' 17 | os: Visual Studio 2017 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.doc diff=astextplain 2 | *.DOC diff=astextplain 3 | *.docx diff=astextplain 4 | *.DOCX diff=astextplain 5 | *.dot diff=astextplain 6 | *.DOT diff=astextplain 7 | *.pdf diff=astextplain 8 | *.PDF diff=astextplain 9 | *.rtf diff=astextplain 10 | *.RTF diff=astextplain 11 | 12 | *.jpg binary 13 | *.png binary 14 | *.gif binary 15 | 16 | *.cs text=auto diff=csharp 17 | *.vb text=auto 18 | *.resx text=auto 19 | *.c text=auto 20 | *.cpp text=auto 21 | *.cxx text=auto 22 | *.h text=auto 23 | *.hxx text=auto 24 | *.py text=auto 25 | *.rb text=auto 26 | *.java text=auto 27 | *.html text=auto 28 | *.htm text=auto 29 | *.css text=auto 30 | *.scss text=auto 31 | *.sass text=auto 32 | *.less text=auto 33 | *.js text=auto 34 | *.lisp text=auto 35 | *.clj text=auto 36 | *.sql text=auto 37 | *.php text=auto 38 | *.lua text=auto 39 | *.m text=auto 40 | *.asm text=auto 41 | *.erl text=auto 42 | *.fs text=auto 43 | *.fsx text=auto 44 | *.hs text=auto 45 | 46 | *.csproj text=auto 47 | *.vbproj text=auto 48 | *.fsproj text=auto 49 | *.dbproj text=auto 50 | *.sln text=auto eol=crlf 51 | 52 | *.sh eol=lf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | THIS ISSUE TRACKER IS CLOSED - please log new issues here: https://github.com/aspnet/Home/issues 2 | 3 | For information about this change, see https://github.com/aspnet/Announcements/issues/283 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Oo]bj/ 2 | [Bb]in/ 3 | TestResults/ 4 | .nuget/ 5 | _ReSharper.*/ 6 | packages/ 7 | artifacts/ 8 | PublishProfiles/ 9 | *.user 10 | *.suo 11 | *.cache 12 | *.docstates 13 | _ReSharper.* 14 | nuget.exe 15 | *net45.csproj 16 | *net451.csproj 17 | *k10.csproj 18 | *.psess 19 | *.vsp 20 | *.pidb 21 | *.userprefs 22 | *DS_Store 23 | *.ncrunchsolution 24 | *.*sdf 25 | *.ipch 26 | *.sln.ide 27 | project.lock.json 28 | .vs 29 | .build/ 30 | .testPublish/ 31 | samples/**/temp-keys/ 32 | global.json 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | sudo: false 3 | dist: trusty 4 | env: 5 | global: 6 | - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true 7 | - DOTNET_CLI_TELEMETRY_OPTOUT: 1 8 | mono: none 9 | os: 10 | - linux 11 | - osx 12 | osx_image: xcode8.2 13 | addons: 14 | apt: 15 | packages: 16 | - libunwind8 17 | branches: 18 | only: 19 | - master 20 | - /^release\/.*$/ 21 | - /^(.*\/)?ci-.*$/ 22 | before_install: 23 | - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s 24 | /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib 25 | /usr/local/lib/; fi 26 | script: 27 | - ./build.sh 28 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": ".NET Core Attach", 5 | "type": "coreclr", 6 | "request": "attach", 7 | "processId": "${command:pickProcess}" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.vsts-pipelines/builds/ci-public.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | - release/* 4 | 5 | # See https://github.com/aspnet/BuildTools 6 | resources: 7 | repositories: 8 | - repository: buildtools 9 | type: github 10 | endpoint: DotNet-Bot GitHub Connection 11 | name: aspnet/BuildTools 12 | ref: refs/heads/master 13 | 14 | phases: 15 | - template: .vsts-pipelines/templates/project-ci.yml@buildtools 16 | - template: .vsts-pipelines/templates/phases/default-build.yml@buildtools 17 | parameters: 18 | phaseName: Linux_RedisTests 19 | queueName: DotNetCore-Docker 20 | agentOs: Linux 21 | demands: 22 | - docker 23 | variables: 24 | Test__Redis__Server: localhost:6379,127.0.0.1:6379 25 | beforeBuild: 26 | - script: docker run --rm -d --name test-redis-server -p 6379:6379 redis 27 | displayName: Start Redis in Docker 28 | afterBuild: 29 | - script: docker stop test-redis-server 30 | displayName: Stop Redis in Docker 31 | condition: always() 32 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ====== 3 | 4 | Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. 5 | -------------------------------------------------------------------------------- /DataProtection.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | False -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Microsoft ASP.NET Core 12 | https://github.com/aspnet/DataProtection 13 | git 14 | $(MSBuildThisFileDirectory) 15 | $(MSBuildThisFileDirectory)build\Key.snk 16 | true 17 | true 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(MicrosoftNETCoreApp30PackageVersion) 4 | $(NETStandardLibrary20PackageVersion) 5 | 6 | 99.9 7 | 8 | 9 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NuGetPackageVerifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "Default": { 3 | "rules": [ 4 | "DefaultCompositeRule" 5 | ] 6 | } 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DataProtection [Archived] 2 | ========================= 3 | 4 | **This GitHub project has been archived.** Ongoing development on this project can be found in . 5 | 6 | Data Protection APIs for protecting and unprotecting data. 7 | 8 | This project is part of ASP.NET Core. You can find documentation for Data Protection in the [ASP.NET Core Documentation](http://docs.asp.net/en/latest/security/data-protection/index.html). You can find samples, documentation and getting started instructions for ASP.NET Core at the [AspNetCore](https://github.com/aspnet/AspNetCore) repo. 9 | 10 | ## Community Maintained Data Protection Providers & Projects 11 | 12 | - [ASP.NET Core DataProtection Provider for Service Fabric](https://github.com/MedAnd/AspNetCore.DataProtection.ServiceFabric) 13 | - [ASP.NET Core DataProtection Provider for Google Cloud Storage](https://github.com/ocinbat/GoogleCloudStorage.AspNetCore.DataProtection) 14 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE" 3 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | # Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) 7 | chmod +x "$DIR/run.sh"; sync 8 | "$DIR/run.sh" default-build "$@" 9 | -------------------------------------------------------------------------------- /build/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/build/Key.snk -------------------------------------------------------------------------------- /build/repo.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Internal.AspNetCore.Universe.Lineup 7 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /build/sources.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(DotNetRestoreSources) 6 | 7 | $(RestoreSources); 8 | https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; 9 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; 10 | https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; 11 | 12 | 13 | $(RestoreSources); 14 | https://api.nuget.org/v3/index.json; 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /korebuild-lock.txt: -------------------------------------------------------------------------------- 1 | version:3.0.0-alpha1-20181004.7 2 | commithash:27fabdaf2b1d4753c3d2749581694ca65d78f7f2 3 | -------------------------------------------------------------------------------- /korebuild.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", 3 | "channel": "master" 4 | } 5 | -------------------------------------------------------------------------------- /run.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" 3 | -------------------------------------------------------------------------------- /samples/AzureBlob/AzureBlob.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/AzureBlob/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Logging; 8 | using Microsoft.WindowsAzure.Storage; 9 | using LogLevel = Microsoft.Extensions.Logging.LogLevel; 10 | 11 | namespace AzureBlob 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | var storageAccount = CloudStorageAccount.DevelopmentStorageAccount; 18 | var client = storageAccount.CreateCloudBlobClient(); 19 | var container = client.GetContainerReference("key-container"); 20 | 21 | // The container must exist before calling the DataProtection APIs. 22 | // The specific file within the container does not have to exist, 23 | // as it will be created on-demand. 24 | 25 | container.CreateIfNotExistsAsync().GetAwaiter().GetResult(); 26 | 27 | // Configure 28 | using (var services = new ServiceCollection() 29 | .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) 30 | .AddDataProtection() 31 | .PersistKeysToAzureBlobStorage(container, "keys.xml") 32 | .Services 33 | .BuildServiceProvider()) 34 | { 35 | // Run a sample payload 36 | 37 | var protector = services.GetDataProtector("sample-purpose"); 38 | var protectedData = protector.Protect("Hello world!"); 39 | Console.WriteLine(protectedData); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /samples/AzureKeyVault/AzureKeyVault.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /samples/AzureKeyVault/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Security.Cryptography.X509Certificates; 8 | using Microsoft.AspNetCore.DataProtection; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace ConsoleApplication 14 | { 15 | public class Program 16 | { 17 | public static void Main(string[] args) 18 | { 19 | var builder = new ConfigurationBuilder(); 20 | builder.SetBasePath(Directory.GetCurrentDirectory()); 21 | builder.AddJsonFile("settings.json"); 22 | var config = builder.Build(); 23 | 24 | var store = new X509Store(StoreLocation.CurrentUser); 25 | store.Open(OpenFlags.ReadOnly); 26 | var cert = store.Certificates.Find(X509FindType.FindByThumbprint, config["CertificateThumbprint"], false); 27 | 28 | var serviceCollection = new ServiceCollection(); 29 | serviceCollection.AddLogging(); 30 | serviceCollection.AddDataProtection() 31 | .PersistKeysToFileSystem(new DirectoryInfo(".")) 32 | .ProtectKeysWithAzureKeyVault(config["KeyId"], config["ClientId"], cert.OfType().Single()); 33 | 34 | var serviceProvider = serviceCollection.BuildServiceProvider(); 35 | 36 | var loggerFactory = serviceProvider.GetService(); 37 | loggerFactory.AddConsole(); 38 | 39 | var protector = serviceProvider.GetDataProtector("Test"); 40 | 41 | Console.WriteLine(protector.Protect("Hello world")); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/AzureKeyVault/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CertificateThumbprint": "", 3 | "KeyId": "", 4 | "ClientId": "" 5 | } -------------------------------------------------------------------------------- /samples/CustomEncryptorSample/CustomBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection; 6 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 7 | using Microsoft.AspNetCore.DataProtection.XmlEncryption; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Options; 10 | 11 | namespace CustomEncryptorSample 12 | { 13 | public static class CustomBuilderExtensions 14 | { 15 | public static IDataProtectionBuilder UseXmlEncryptor( 16 | this IDataProtectionBuilder builder, 17 | Func factory) 18 | { 19 | builder.Services.AddSingleton>(serviceProvider => 20 | { 21 | var instance = factory(serviceProvider); 22 | return new ConfigureOptions(options => 23 | { 24 | options.XmlEncryptor = instance; 25 | }); 26 | }); 27 | 28 | return builder; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/CustomEncryptorSample/CustomEncryptorSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netcoreapp3.0 5 | exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /samples/CustomEncryptorSample/CustomXmlDecryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Xml.Linq; 7 | using Microsoft.AspNetCore.DataProtection.XmlEncryption; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace CustomEncryptorSample 12 | { 13 | public class CustomXmlDecryptor : IXmlDecryptor 14 | { 15 | private readonly ILogger _logger; 16 | 17 | public CustomXmlDecryptor(IServiceProvider services) 18 | { 19 | _logger = services.GetRequiredService().CreateLogger(); 20 | } 21 | 22 | public XElement Decrypt(XElement encryptedElement) 23 | { 24 | if (encryptedElement == null) 25 | { 26 | throw new ArgumentNullException(nameof(encryptedElement)); 27 | } 28 | 29 | return new XElement(encryptedElement.Elements().Single()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/CustomEncryptorSample/CustomXmlEncryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | using Microsoft.AspNetCore.DataProtection.XmlEncryption; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace CustomEncryptorSample 11 | { 12 | public class CustomXmlEncryptor : IXmlEncryptor 13 | { 14 | private readonly ILogger _logger; 15 | 16 | public CustomXmlEncryptor(IServiceProvider services) 17 | { 18 | _logger = services.GetRequiredService().CreateLogger(); 19 | } 20 | 21 | public EncryptedXmlInfo Encrypt(XElement plaintextElement) 22 | { 23 | if (plaintextElement == null) 24 | { 25 | throw new ArgumentNullException(nameof(plaintextElement)); 26 | } 27 | 28 | _logger.LogInformation("Not encrypting key"); 29 | 30 | var newElement = new XElement("unencryptedKey", 31 | new XComment(" This key is not encrypted. "), 32 | new XElement(plaintextElement)); 33 | var encryptedTextElement = new EncryptedXmlInfo(newElement, typeof(CustomXmlDecryptor)); 34 | 35 | return encryptedTextElement; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/CustomEncryptorSample/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.AspNetCore.DataProtection; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace CustomEncryptorSample 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | var keysFolder = Path.Combine(Directory.GetCurrentDirectory(), "temp-keys"); 17 | using (var services = new ServiceCollection() 18 | .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) 19 | .AddDataProtection() 20 | .PersistKeysToFileSystem(new DirectoryInfo(keysFolder)) 21 | .UseXmlEncryptor(s => new CustomXmlEncryptor(s)) 22 | .Services.BuildServiceProvider()) 23 | { 24 | var protector = services.GetDataProtector("SamplePurpose"); 25 | 26 | // protect the payload 27 | var protectedPayload = protector.Protect("Hello World!"); 28 | Console.WriteLine($"Protect returned: {protectedPayload}"); 29 | 30 | // unprotect the payload 31 | var unprotectedPayload = protector.Unprotect(protectedPayload); 32 | Console.WriteLine($"Unprotect returned: {unprotectedPayload}"); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/EntityFrameworkCoreSample/EntityFrameworkCoreSample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | exe 5 | net461;netcoreapp3.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /samples/EntityFrameworkCoreSample/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection; 6 | using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; 7 | using Microsoft.EntityFrameworkCore; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace EntityFrameworkCoreSample 12 | { 13 | class Program 14 | { 15 | static void Main(string[] args) 16 | { 17 | // Configure 18 | var services = new ServiceCollection() 19 | .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) 20 | .AddDbContext(o => 21 | { 22 | o.UseInMemoryDatabase("DataProtection_EntityFrameworkCore"); 23 | o.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); 24 | o.EnableSensitiveDataLogging(); 25 | }) 26 | .AddDataProtection() 27 | .PersistKeysToDbContext() 28 | .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) 29 | .Services 30 | .BuildServiceProvider(validateScopes: true); 31 | 32 | using(services) 33 | { 34 | // Run a sample payload 35 | var protector = services.GetDataProtector("sample-purpose"); 36 | var protectedData = protector.Protect("Hello world!"); 37 | Console.WriteLine(protectedData); 38 | } 39 | } 40 | } 41 | 42 | class DataProtectionKeyContext : DbContext, IDataProtectionKeyContext 43 | { 44 | public DataProtectionKeyContext(DbContextOptions options) : base(options) { } 45 | 46 | public DbSet DataProtectionKeys { get; set; } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples/KeyManagementSample/KeyManagementSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netcoreapp3.0 5 | exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /samples/NonDISample/NonDISample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netcoreapp3.0 5 | exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples/NonDISample/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | using Microsoft.AspNetCore.DataProtection; 8 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 9 | 10 | namespace NonDISample 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | var keysFolder = Path.Combine(Directory.GetCurrentDirectory(), "temp-keys"); 17 | 18 | // instantiate the data protection system at this folder 19 | var dataProtectionProvider = DataProtectionProvider.Create( 20 | new DirectoryInfo(keysFolder), 21 | configuration => 22 | { 23 | configuration.SetApplicationName("my app name"); 24 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 25 | { 26 | configuration.ProtectKeysWithDpapi(); 27 | } 28 | }); 29 | 30 | var protector = dataProtectionProvider.CreateProtector("Program.No-DI"); 31 | 32 | // protect the payload 33 | var protectedPayload = protector.Protect("Hello World!"); 34 | Console.WriteLine($"Protect returned: {protectedPayload}"); 35 | 36 | // unprotect the payload 37 | var unprotectedPayload = protector.Unprotect(protectedPayload); 38 | Console.WriteLine($"Unprotect returned: {unprotectedPayload}"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /samples/Redis/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection; 6 | using Microsoft.AspNetCore.DataProtection.StackExchangeRedis; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Logging; 9 | using StackExchange.Redis; 10 | 11 | namespace RedisSample 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | // Connect 18 | var redis = ConnectionMultiplexer.Connect("localhost:6379"); 19 | 20 | // Configure 21 | using (var services = new ServiceCollection() 22 | .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) 23 | .AddDataProtection() 24 | .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys") 25 | .Services 26 | .BuildServiceProvider()) 27 | { 28 | // Run a sample payload 29 | var protector = services.GetDataProtector("sample-purpose"); 30 | var protectedData = protector.Protect("Hello world!"); 31 | Console.WriteLine(protectedData); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/Redis/Redis.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461;netcoreapp3.0 5 | exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /shared/EncodingUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Text; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | internal static class EncodingUtil 10 | { 11 | // UTF8 encoding that fails on invalid chars 12 | public static readonly UTF8Encoding SecureUtf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /shared/ExceptionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | internal static class ExceptionExtensions 10 | { 11 | /// 12 | /// Determines whether an exception must be homogenized by being wrapped inside a 13 | /// CryptographicException before being rethrown. 14 | /// 15 | public static bool RequiresHomogenization(this Exception ex) 16 | { 17 | return !(ex is CryptographicException); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.Cng 8 | { 9 | // http://msdn.microsoft.com/en-us/library/windows/desktop/cc562981(v=vs.85).aspx 10 | [StructLayout(LayoutKind.Sequential)] 11 | internal unsafe struct BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO 12 | { 13 | public uint cbSize; 14 | public uint dwInfoVersion; 15 | public byte* pbNonce; 16 | public uint cbNonce; 17 | public byte* pbAuthData; 18 | public uint cbAuthData; 19 | public byte* pbTag; 20 | public uint cbTag; 21 | public byte* pbMacContext; 22 | public uint cbMacContext; 23 | public uint cbAAD; 24 | public ulong cbData; 25 | public uint dwFlags; 26 | 27 | // corresponds to the BCRYPT_INIT_AUTH_MODE_INFO macro in bcrypt.h 28 | public static void Init(out BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO info) 29 | { 30 | const uint BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION = 1; 31 | info = new BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO 32 | { 33 | cbSize = (uint)sizeof(BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO), 34 | dwInfoVersion = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION 35 | }; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCRYPT_KEY_LENGTHS_STRUCT.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using Microsoft.AspNetCore.Cryptography.Internal; 7 | 8 | namespace Microsoft.AspNetCore.Cryptography.Cng 9 | { 10 | // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375525(v=vs.85).aspx 11 | [StructLayout(LayoutKind.Sequential)] 12 | internal struct BCRYPT_KEY_LENGTHS_STRUCT 13 | { 14 | // MSDN says these fields represent the key length in bytes. 15 | // It's wrong: these key lengths are all actually in bits. 16 | internal uint dwMinLength; 17 | internal uint dwMaxLength; 18 | internal uint dwIncrement; 19 | 20 | public void EnsureValidKeyLength(uint keyLengthInBits) 21 | { 22 | if (!IsValidKeyLength(keyLengthInBits)) 23 | { 24 | string message = Resources.FormatBCRYPT_KEY_LENGTHS_STRUCT_InvalidKeyLength(keyLengthInBits, dwMinLength, dwMaxLength, dwIncrement); 25 | throw new ArgumentOutOfRangeException(nameof(keyLengthInBits), message); 26 | } 27 | CryptoUtil.Assert(keyLengthInBits % 8 == 0, "keyLengthInBits % 8 == 0"); 28 | } 29 | 30 | private bool IsValidKeyLength(uint keyLengthInBits) 31 | { 32 | // If the step size is zero, then the key length must be exactly the min or the max. Otherwise, 33 | // key length must be between min and max (inclusive) and a whole number of increments away from min. 34 | if (dwIncrement == 0) 35 | { 36 | return (keyLengthInBits == dwMinLength || keyLengthInBits == dwMaxLength); 37 | } 38 | else 39 | { 40 | return (dwMinLength <= keyLengthInBits) 41 | && (keyLengthInBits <= dwMaxLength) 42 | && ((keyLengthInBits - dwMinLength) % dwIncrement == 0); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCryptBuffer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.Cng 8 | { 9 | // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375368(v=vs.85).aspx 10 | [StructLayout(LayoutKind.Sequential)] 11 | internal struct BCryptBuffer 12 | { 13 | public uint cbBuffer; // Length of buffer, in bytes 14 | public BCryptKeyDerivationBufferType BufferType; // Buffer type 15 | public IntPtr pvBuffer; // Pointer to buffer 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCryptBufferDesc.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace Microsoft.AspNetCore.Cryptography.Cng 9 | { 10 | // http://msdn.microsoft.com/en-us/library/windows/desktop/aa375370(v=vs.85).aspx 11 | [StructLayout(LayoutKind.Sequential)] 12 | internal unsafe struct BCryptBufferDesc 13 | { 14 | private const int BCRYPTBUFFER_VERSION = 0; 15 | 16 | public uint ulVersion; // Version number 17 | public uint cBuffers; // Number of buffers 18 | public BCryptBuffer* pBuffers; // Pointer to array of buffers 19 | 20 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 21 | public static void Initialize(ref BCryptBufferDesc bufferDesc) 22 | { 23 | bufferDesc.ulVersion = BCRYPTBUFFER_VERSION; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCryptEncryptFlags.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.Cng 7 | { 8 | [Flags] 9 | internal enum BCryptEncryptFlags 10 | { 11 | BCRYPT_BLOCK_PADDING = 0x00000001, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCryptGenRandomFlags.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.Cng 7 | { 8 | // from bcrypt.h 9 | [Flags] 10 | internal enum BCryptGenRandomFlags 11 | { 12 | BCRYPT_RNG_USE_ENTROPY_IN_BUFFER = 0x00000001, 13 | BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCryptKeyDerivationBufferType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.Cng 7 | { 8 | // from bcrypt.h 9 | internal enum BCryptKeyDerivationBufferType 10 | { 11 | KDF_HASH_ALGORITHM = 0x0, 12 | KDF_SECRET_PREPEND = 0x1, 13 | KDF_SECRET_APPEND = 0x2, 14 | KDF_HMAC_KEY = 0x3, 15 | KDF_TLS_PRF_LABEL = 0x4, 16 | KDF_TLS_PRF_SEED = 0x5, 17 | KDF_SECRET_HANDLE = 0x6, 18 | KDF_TLS_PRF_PROTOCOL = 0x7, 19 | KDF_ALGORITHMID = 0x8, 20 | KDF_PARTYUINFO = 0x9, 21 | KDF_PARTYVINFO = 0xA, 22 | KDF_SUPPPUBINFO = 0xB, 23 | KDF_SUPPPRIVINFO = 0xC, 24 | KDF_LABEL = 0xD, 25 | KDF_CONTEXT = 0xE, 26 | KDF_SALT = 0xF, 27 | KDF_ITERATION_COUNT = 0x10, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/BCryptUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.Cng 7 | { 8 | /// 9 | /// Wraps utility BCRYPT APIs that don't work directly with handles. 10 | /// 11 | internal unsafe static class BCryptUtil 12 | { 13 | /// 14 | /// Fills a buffer with cryptographically secure random data. 15 | /// 16 | public static void GenRandom(byte* pbBuffer, uint cbBuffer) 17 | { 18 | if (cbBuffer != 0) 19 | { 20 | int ntstatus = UnsafeNativeMethods.BCryptGenRandom( 21 | hAlgorithm: IntPtr.Zero, 22 | pbBuffer: pbBuffer, 23 | cbBuffer: cbBuffer, 24 | dwFlags: BCryptGenRandomFlags.BCRYPT_USE_SYSTEM_PREFERRED_RNG); 25 | UnsafeNativeMethods.ThrowExceptionForBCryptStatus(ntstatus); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/NCryptEncryptFlags.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.Cng 7 | { 8 | [Flags] 9 | internal enum NCryptEncryptFlags 10 | { 11 | NCRYPT_NO_PADDING_FLAG = 0x00000001, 12 | NCRYPT_PAD_PKCS1_FLAG = 0x00000002, 13 | NCRYPT_PAD_OAEP_FLAG = 0x00000004, 14 | NCRYPT_PAD_PSS_FLAG = 0x00000008, 15 | NCRYPT_SILENT_FLAG = 0x00000040, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Cng/OSVersionUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Cryptography.SafeHandles; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.Cng 8 | { 9 | internal static class OSVersionUtil 10 | { 11 | private static readonly OSVersion _osVersion = GetOSVersion(); 12 | 13 | private static OSVersion GetOSVersion() 14 | { 15 | const string BCRYPT_LIB = "bcrypt.dll"; 16 | SafeLibraryHandle bcryptLibHandle = null; 17 | try 18 | { 19 | bcryptLibHandle = SafeLibraryHandle.Open(BCRYPT_LIB); 20 | } 21 | catch 22 | { 23 | // we'll handle the exceptional case later 24 | } 25 | 26 | if (bcryptLibHandle != null) 27 | { 28 | using (bcryptLibHandle) 29 | { 30 | if (bcryptLibHandle.DoesProcExist("BCryptKeyDerivation")) 31 | { 32 | // We're running on Win8+. 33 | return OSVersion.Win8OrLater; 34 | } 35 | else 36 | { 37 | // We're running on Win7+. 38 | return OSVersion.Win7OrLater; 39 | } 40 | } 41 | } 42 | else 43 | { 44 | // Not running on Win7+. 45 | return OSVersion.NotWindows; 46 | } 47 | } 48 | 49 | public static bool IsWindows() 50 | { 51 | return (_osVersion >= OSVersion.Win7OrLater); 52 | } 53 | 54 | public static bool IsWindows8OrLater() 55 | { 56 | return (_osVersion >= OSVersion.Win8OrLater); 57 | } 58 | 59 | private enum OSVersion 60 | { 61 | NotWindows = 0, 62 | Win7OrLater = 1, 63 | Win8OrLater = 2 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/DATA_BLOB.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography 8 | { 9 | // http://msdn.microsoft.com/en-us/library/windows/desktop/aa381414(v=vs.85).aspx 10 | [StructLayout(LayoutKind.Sequential)] 11 | internal unsafe struct DATA_BLOB 12 | { 13 | public uint cbData; 14 | public byte* pbData; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/Microsoft.AspNetCore.Cryptography.Internal.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Infrastructure for ASP.NET Core cryptographic packages. Applications and libraries should not reference this package directly. 5 | netstandard2.0 6 | $(NoWarn);CS1591 7 | true 8 | true 9 | aspnetcore;dataprotection 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/SafeHandles/BCryptHandle.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.Win32.SafeHandles; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.SafeHandles 8 | { 9 | internal unsafe abstract class BCryptHandle : SafeHandleZeroOrMinusOneIsInvalid 10 | { 11 | protected BCryptHandle() 12 | : base(ownsHandle: true) 13 | { 14 | } 15 | 16 | protected uint GetProperty(string pszProperty, void* pbOutput, uint cbOutput) 17 | { 18 | uint retVal; 19 | int ntstatus = UnsafeNativeMethods.BCryptGetProperty(this, pszProperty, pbOutput, cbOutput, out retVal, dwFlags: 0); 20 | UnsafeNativeMethods.ThrowExceptionForBCryptStatus(ntstatus); 21 | return retVal; 22 | } 23 | 24 | protected void SetProperty(string pszProperty, void* pbInput, uint cbInput) 25 | { 26 | int ntstatus = UnsafeNativeMethods.BCryptSetProperty(this, pszProperty, pbInput, cbInput, dwFlags: 0); 27 | UnsafeNativeMethods.ThrowExceptionForBCryptStatus(ntstatus); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/SafeHandles/BCryptKeyHandle.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.SafeHandles 7 | { 8 | internal sealed class BCryptKeyHandle : BCryptHandle 9 | { 10 | private BCryptAlgorithmHandle _algProviderHandle; 11 | 12 | // Called by P/Invoke when returning SafeHandles 13 | private BCryptKeyHandle() { } 14 | 15 | // Do not provide a finalizer - SafeHandle's critical finalizer will call ReleaseHandle for you. 16 | protected override bool ReleaseHandle() 17 | { 18 | _algProviderHandle = null; 19 | return (UnsafeNativeMethods.BCryptDestroyKey(handle) == 0); 20 | } 21 | 22 | // We don't actually need to hold a reference to the algorithm handle, as the native CNG library 23 | // already holds the reference for us. But once we create a key from an algorithm provider, odds 24 | // are good that we'll create another key from the same algorithm provider at some point in the 25 | // future. And since algorithm providers are expensive to create, we'll hold a strong reference 26 | // to all known in-use providers. This way the cached algorithm provider handles utility class 27 | // doesn't keep creating providers over and over. 28 | internal void SetAlgorithmProviderHandle(BCryptAlgorithmHandle algProviderHandle) 29 | { 30 | _algProviderHandle = algProviderHandle; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/SafeHandles/LocalAllocHandle.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using Microsoft.Win32.SafeHandles; 7 | 8 | namespace Microsoft.AspNetCore.Cryptography.SafeHandles 9 | { 10 | /// 11 | /// Represents a handle returned by LocalAlloc. 12 | /// 13 | internal class LocalAllocHandle : SafeHandleZeroOrMinusOneIsInvalid 14 | { 15 | // Called by P/Invoke when returning SafeHandles 16 | protected LocalAllocHandle() 17 | : base(ownsHandle: true) { } 18 | 19 | // Do not provide a finalizer - SafeHandle's critical finalizer will call ReleaseHandle for you. 20 | protected override bool ReleaseHandle() 21 | { 22 | Marshal.FreeHGlobal(handle); // actually calls LocalFree 23 | return true; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/SafeHandles/NCryptDescriptorHandle.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.Win32.SafeHandles; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.SafeHandles 8 | { 9 | internal unsafe sealed class NCryptDescriptorHandle : SafeHandleZeroOrMinusOneIsInvalid 10 | { 11 | private NCryptDescriptorHandle() 12 | : base(ownsHandle: true) 13 | { 14 | } 15 | 16 | public string GetProtectionDescriptorRuleString() 17 | { 18 | // from ncryptprotect.h 19 | const int NCRYPT_PROTECTION_INFO_TYPE_DESCRIPTOR_STRING = 0x00000001; 20 | 21 | LocalAllocHandle ruleStringHandle; 22 | int ntstatus = UnsafeNativeMethods.NCryptGetProtectionDescriptorInfo( 23 | hDescriptor: this, 24 | pMemPara: IntPtr.Zero, 25 | dwInfoType: NCRYPT_PROTECTION_INFO_TYPE_DESCRIPTOR_STRING, 26 | ppvInfo: out ruleStringHandle); 27 | UnsafeNativeMethods.ThrowExceptionForNCryptStatus(ntstatus); 28 | CryptoUtil.AssertSafeHandleIsValid(ruleStringHandle); 29 | 30 | using (ruleStringHandle) 31 | { 32 | return new String((char*)ruleStringHandle.DangerousGetHandle()); 33 | } 34 | } 35 | 36 | // Do not provide a finalizer - SafeHandle's critical finalizer will call ReleaseHandle for you. 37 | protected override bool ReleaseHandle() 38 | { 39 | return (UnsafeNativeMethods.NCryptCloseProtectionDescriptor(handle) == 0); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.Internal/baseline.netcore.json: -------------------------------------------------------------------------------- 1 | { 2 | "AssemblyIdentity": "Microsoft.AspNetCore.Cryptography.Internal, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", 3 | "Types": [] 4 | } -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.KeyDerivation/KeyDerivationPrf.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.Cryptography.KeyDerivation 5 | { 6 | /// 7 | /// Specifies the PRF which should be used for the key derivation algorithm. 8 | /// 9 | public enum KeyDerivationPrf 10 | { 11 | /// 12 | /// The HMAC algorithm (RFC 2104) using the SHA-1 hash function (FIPS 180-4). 13 | /// 14 | HMACSHA1, 15 | 16 | /// 17 | /// The HMAC algorithm (RFC 2104) using the SHA-256 hash function (FIPS 180-4). 18 | /// 19 | HMACSHA256, 20 | 21 | /// 22 | /// The HMAC algorithm (RFC 2104) using the SHA-512 hash function (FIPS 180-4). 23 | /// 24 | HMACSHA512, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.KeyDerivation/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ASP.NET Core utilities for key derivation. 5 | netstandard2.0;netcoreapp3.0 6 | true 7 | true 8 | aspnetcore;dataprotection 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.KeyDerivation/PBKDF2/IPbkdf2Provider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.KeyDerivation.PBKDF2 7 | { 8 | /// 9 | /// Internal interface used for abstracting away the PBKDF2 implementation since the implementation is OS-specific. 10 | /// 11 | internal interface IPbkdf2Provider 12 | { 13 | byte[] DeriveKey(string password, byte[] salt, KeyDerivationPrf prf, int iterationCount, int numBytesRequested); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.KeyDerivation/PBKDF2/Pbkdf2Util.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.Cryptography.Cng; 5 | 6 | namespace Microsoft.AspNetCore.Cryptography.KeyDerivation.PBKDF2 7 | { 8 | /// 9 | /// Internal base class used for abstracting away the PBKDF2 implementation since the implementation is OS-specific. 10 | /// 11 | internal static class Pbkdf2Util 12 | { 13 | public static readonly IPbkdf2Provider Pbkdf2Provider = GetPbkdf2Provider(); 14 | 15 | private static IPbkdf2Provider GetPbkdf2Provider() 16 | { 17 | // In priority order, our three implementations are Win8, Win7, and "other". 18 | if (OSVersionUtil.IsWindows8OrLater()) 19 | { 20 | // fastest implementation 21 | return new Win8Pbkdf2Provider(); 22 | } 23 | else if (OSVersionUtil.IsWindows()) 24 | { 25 | // acceptable implementation 26 | return new Win7Pbkdf2Provider(); 27 | } 28 | #if NETCOREAPP3_0 29 | else 30 | { 31 | // fastest implementation on .NET Core for Linux/macOS. 32 | // Not supported on .NET Framework 33 | return new NetCorePbkdf2Provider(); 34 | } 35 | #elif NETSTANDARD2_0 36 | else 37 | { 38 | // slowest implementation 39 | return new ManagedPbkdf2Provider(); 40 | } 41 | #else 42 | #error Update target frameworks 43 | #endif 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.Cryptography.KeyDerivation/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Cryptography.KeyDerivation.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 7 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/CryptoUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using System.Runtime.CompilerServices; 7 | using System.Security.Cryptography; 8 | 9 | namespace Microsoft.AspNetCore.DataProtection 10 | { 11 | internal static class CryptoUtil 12 | { 13 | // This isn't a typical Debug.Fail; an error always occurs, even in retail builds. 14 | // This method doesn't return, but since the CLR doesn't allow specifying a 'never' 15 | // return type, we mimic it by specifying our return type as Exception. That way 16 | // callers can write 'throw Fail(...);' to make the C# compiler happy, as the 17 | // throw keyword is implicitly of type O. 18 | [MethodImpl(MethodImplOptions.NoInlining)] 19 | public static Exception Fail(string message) 20 | { 21 | Debug.Fail(message); 22 | throw new CryptographicException("Assertion failed: " + message); 23 | } 24 | 25 | // Allows callers to write "var x = Method() ?? Fail(message);" as a convenience to guard 26 | // against a method returning null unexpectedly. 27 | [MethodImpl(MethodImplOptions.NoInlining)] 28 | public static T Fail(string message) where T : class 29 | { 30 | throw Fail(message); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/Error.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | using Microsoft.AspNetCore.DataProtection.Abstractions; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection 9 | { 10 | internal static class Error 11 | { 12 | public static CryptographicException CryptCommon_GenericError(Exception inner = null) 13 | { 14 | return new CryptographicException(Resources.CryptCommon_GenericError, inner); 15 | } 16 | 17 | public static CryptographicException CryptCommon_PayloadInvalid() 18 | { 19 | string message = Resources.CryptCommon_PayloadInvalid; 20 | return new CryptographicException(message); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/IDataProtectionProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection 5 | { 6 | /// 7 | /// An interface that can be used to create instances. 8 | /// 9 | public interface IDataProtectionProvider 10 | { 11 | /// 12 | /// Creates an given a purpose. 13 | /// 14 | /// 15 | /// The purpose to be assigned to the newly-created . 16 | /// 17 | /// An IDataProtector tied to the provided purpose. 18 | /// 19 | /// The parameter must be unique for the intended use case; two 20 | /// different instances created with two different 21 | /// values will not be able to decipher each other's payloads. The parameter 22 | /// value is not intended to be kept secret. 23 | /// 24 | IDataProtector CreateProtector(string purpose); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/IDataProtector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection 5 | { 6 | /// 7 | /// An interface that can provide data protection services. 8 | /// 9 | public interface IDataProtector : IDataProtectionProvider 10 | { 11 | /// 12 | /// Cryptographically protects a piece of plaintext data. 13 | /// 14 | /// The plaintext data to protect. 15 | /// The protected form of the plaintext data. 16 | byte[] Protect(byte[] plaintext); 17 | 18 | /// 19 | /// Cryptographically unprotects a piece of protected data. 20 | /// 21 | /// The protected data to unprotect. 22 | /// The plaintext form of the protected data. 23 | /// 24 | /// Thrown if the protected data is invalid or malformed. 25 | /// 26 | byte[] Unprotect(byte[] protectedData); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/Infrastructure/IApplicationDiscriminator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.Infrastructure 8 | { 9 | /// 10 | /// Provides information used to discriminate applications. 11 | /// 12 | /// 13 | /// This type supports the data protection system and is not intended to be used 14 | /// by consumers. 15 | /// 16 | [EditorBrowsable(EditorBrowsableState.Never)] 17 | public interface IApplicationDiscriminator 18 | { 19 | /// 20 | /// An identifier that uniquely discriminates this application from all other 21 | /// applications on the machine. 22 | /// 23 | string Discriminator { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/Microsoft.AspNetCore.DataProtection.Abstractions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ASP.NET Core data protection abstractions. 5 | Commonly used types: 6 | Microsoft.AspNetCore.DataProtection.IDataProtectionProvider 7 | Microsoft.AspNetCore.DataProtection.IDataProtector 8 | netstandard2.0 9 | true 10 | aspnetcore;dataprotection 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Abstractions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | // for unit testing 7 | [assembly: InternalsVisibleTo("Microsoft.AspNetCore.DataProtection.Abstractions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 8 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.AzureKeyVault/IKeyVaultWrappingClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.KeyVault.Models; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault 8 | { 9 | internal interface IKeyVaultWrappingClient 10 | { 11 | Task UnwrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText); 12 | Task WrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.AzureKeyVault/KeyVaultClientWrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.Azure.KeyVault; 6 | using Microsoft.Azure.KeyVault.Models; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.AzureKeyVault 9 | { 10 | internal class KeyVaultClientWrapper : IKeyVaultWrappingClient 11 | { 12 | private readonly KeyVaultClient _client; 13 | 14 | public KeyVaultClientWrapper(KeyVaultClient client) 15 | { 16 | _client = client; 17 | } 18 | 19 | public Task UnwrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText) 20 | { 21 | return _client.UnwrapKeyAsync(keyIdentifier, algorithm, cipherText); 22 | } 23 | 24 | public Task WrapKeyAsync(string keyIdentifier, string algorithm, byte[] cipherText) 25 | { 26 | return _client.WrapKeyAsync(keyIdentifier, algorithm, cipherText); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.AzureKeyVault/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Microsoft Azure KeyVault key encryption support. 5 | netstandard2.0 6 | true 7 | aspnetcore;dataprotection;azure;keyvault 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.AzureKeyVault/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Reflection; 5 | using System.Resources; 6 | using System.Runtime.CompilerServices; 7 | 8 | [assembly: InternalsVisibleTo("Microsoft.AspNetCore.DataProtection.AzureKeyVault.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 9 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 10 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.AzureStorage/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Microsoft Azure Blob storrage support as key store. 5 | netstandard2.0 6 | true 7 | true 8 | aspnetcore;dataprotection;azure;blob 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore/DataProtectionKey.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection.EntityFrameworkCore 5 | { 6 | /// 7 | /// Code first model used by . 8 | /// 9 | public class DataProtectionKey 10 | { 11 | /// 12 | /// The entity identifier of the . 13 | /// 14 | public int Id { get; set; } 15 | 16 | /// 17 | /// The friendly name of the . 18 | /// 19 | public string FriendlyName { get; set; } 20 | 21 | /// 22 | /// The XML representation of the . 23 | /// 24 | public string Xml { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore/EntityFrameworkCoreDataProtectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; 5 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 6 | using Microsoft.EntityFrameworkCore; 7 | using Microsoft.Extensions.DependencyInjection; 8 | using Microsoft.Extensions.Logging; 9 | using Microsoft.Extensions.Logging.Abstractions; 10 | using Microsoft.Extensions.Options; 11 | 12 | namespace Microsoft.AspNetCore.DataProtection 13 | { 14 | /// 15 | /// Extension method class for configuring instances of 16 | /// 17 | public static class EntityFrameworkCoreDataProtectionExtensions 18 | { 19 | /// 20 | /// Configures the data protection system to persist keys to an EntityFrameworkCore datastore 21 | /// 22 | /// The instance to modify. 23 | /// The value . 24 | public static IDataProtectionBuilder PersistKeysToDbContext(this IDataProtectionBuilder builder) 25 | where TContext : DbContext, IDataProtectionKeyContext 26 | { 27 | builder.Services.AddSingleton>(services => 28 | { 29 | var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; 30 | return new ConfigureOptions(options => 31 | { 32 | options.XmlRepository = new EntityFrameworkCoreXmlRepository(services, loggerFactory); 33 | }); 34 | }); 35 | 36 | return builder; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore/IDataProtectionKeyContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.EntityFrameworkCore 7 | { 8 | /// 9 | /// Interface used to store instances of in a 10 | /// 11 | public interface IDataProtectionKeyContext 12 | { 13 | /// 14 | /// A collection of 15 | /// 16 | DbSet DataProtectionKeys { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore/LoggingExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Extensions.Logging 7 | { 8 | internal static class LoggingExtensions 9 | { 10 | private static readonly Action _anExceptionOccurredWhileParsingKeyXml; 11 | private static readonly Action _savingKeyToDbContext; 12 | 13 | static LoggingExtensions() 14 | { 15 | _anExceptionOccurredWhileParsingKeyXml = LoggerMessage.Define( 16 | eventId: 1, 17 | logLevel: LogLevel.Warning, 18 | formatString: "An exception occurred while parsing the key xml '{Xml}'."); 19 | _savingKeyToDbContext = LoggerMessage.Define( 20 | eventId: 2, 21 | logLevel: LogLevel.Debug, 22 | formatString: "Saving key '{FriendlyName}' to '{DbContext}'."); 23 | } 24 | 25 | public static void LogExceptionWhileParsingKeyXml(this ILogger logger, string keyXml, Exception exception) 26 | => _anExceptionOccurredWhileParsingKeyXml(logger, keyXml, exception); 27 | 28 | public static void LogSavingKeyToDbContext(this ILogger logger, string friendlyName, string contextName) 29 | => _savingKeyToDbContext(logger, friendlyName, contextName, null); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Support for storing keys using Entity Framework Core. 5 | netstandard2.0 6 | true 7 | true 8 | aspnetcore;dataprotection;entityframeworkcore 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Extensions/BitHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection 7 | { 8 | internal static class BitHelpers 9 | { 10 | /// 11 | /// Reads an unsigned 64-bit integer from 12 | /// starting at offset . Data is read big-endian. 13 | /// 14 | public static ulong ReadUInt64(byte[] buffer, int offset) 15 | { 16 | return (((ulong)buffer[offset + 0]) << 56) 17 | | (((ulong)buffer[offset + 1]) << 48) 18 | | (((ulong)buffer[offset + 2]) << 40) 19 | | (((ulong)buffer[offset + 3]) << 32) 20 | | (((ulong)buffer[offset + 4]) << 24) 21 | | (((ulong)buffer[offset + 5]) << 16) 22 | | (((ulong)buffer[offset + 6]) << 8) 23 | | (ulong)buffer[offset + 7]; 24 | } 25 | 26 | /// 27 | /// Writes an unsigned 64-bit integer to starting at 28 | /// offset . Data is written big-endian. 29 | /// 30 | public static void WriteUInt64(byte[] buffer, int offset, ulong value) 31 | { 32 | buffer[offset + 0] = (byte)(value >> 56); 33 | buffer[offset + 1] = (byte)(value >> 48); 34 | buffer[offset + 2] = (byte)(value >> 40); 35 | buffer[offset + 3] = (byte)(value >> 32); 36 | buffer[offset + 4] = (byte)(value >> 24); 37 | buffer[offset + 5] = (byte)(value >> 16); 38 | buffer[offset + 6] = (byte)(value >> 8); 39 | buffer[offset + 7] = (byte)(value); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Extensions/Microsoft.AspNetCore.DataProtection.Extensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Additional APIs for ASP.NET Core data protection. 5 | netstandard2.0 6 | true 7 | aspnetcore;dataprotection 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.Extensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | [assembly: InternalsVisibleTo("Microsoft.AspNetCore.DataProtection.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 7 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Support for storing data protection keys in Redis. 5 | netstandard2.0 6 | true 7 | true 8 | aspnetcore;dataprotection;redis 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.SystemWeb/Microsoft.AspNetCore.DataProtection.SystemWeb.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | A component to allow the ASP.NET Core data protection stack to work with the ASP.NET 4.x <machineKey> element. 5 | net461 6 | $(NoWarn);CS1591 7 | true 8 | aspnet;aspnetcore;dataprotection 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection.SystemWeb/web.config.transform: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/ActivatorExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Cryptography; 6 | using Microsoft.AspNetCore.DataProtection.Internal; 7 | using Microsoft.Extensions.DependencyInjection; 8 | 9 | namespace Microsoft.AspNetCore.DataProtection 10 | { 11 | /// 12 | /// Extension methods for working with . 13 | /// 14 | internal static class ActivatorExtensions 15 | { 16 | /// 17 | /// Creates an instance of and ensures 18 | /// that it is assignable to . 19 | /// 20 | public static T CreateInstance(this IActivator activator, string implementationTypeName) 21 | where T : class 22 | { 23 | if (implementationTypeName == null) 24 | { 25 | throw new ArgumentNullException(nameof(implementationTypeName)); 26 | } 27 | 28 | return activator.CreateInstance(typeof(T), implementationTypeName) as T 29 | ?? CryptoUtil.Fail("CreateInstance returned null."); 30 | } 31 | 32 | /// 33 | /// Returns a given an . 34 | /// Guaranteed to return non-null, even if is null. 35 | /// 36 | public static IActivator GetActivator(this IServiceProvider serviceProvider) 37 | { 38 | return (serviceProvider != null) 39 | ? (serviceProvider.GetService() ?? new SimpleActivator(serviceProvider)) 40 | : SimpleActivator.DefaultWithoutServices; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/ApplyPolicyAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection 7 | { 8 | /// 9 | /// Signifies that the should bind this property from the registry. 10 | /// 11 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] 12 | internal sealed class ApplyPolicyAttribute : Attribute { } 13 | } 14 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/ArraySegmentExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection 7 | { 8 | internal static class ArraySegmentExtensions 9 | { 10 | public static byte[] AsStandaloneArray(this ArraySegment arraySegment) 11 | { 12 | // Fast-track: Don't need to duplicate the array. 13 | if (arraySegment.Offset == 0 && arraySegment.Count == arraySegment.Array.Length) 14 | { 15 | return arraySegment.Array; 16 | } 17 | 18 | var retVal = new byte[arraySegment.Count]; 19 | Buffer.BlockCopy(arraySegment.Array, arraySegment.Offset, retVal, 0, retVal.Length); 20 | return retVal; 21 | } 22 | 23 | public static void Validate(this ArraySegment arraySegment) 24 | { 25 | // Since ArraySegment is a struct, it can be improperly initialized or torn. 26 | // We call the ctor again to make sure the instance data is valid. 27 | var unused = new ArraySegment(arraySegment.Array, arraySegment.Offset, arraySegment.Count); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AlgorithmConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 7 | { 8 | public abstract class AlgorithmConfiguration 9 | { 10 | internal const int KDK_SIZE_IN_BYTES = 512 / 8; 11 | 12 | /// 13 | /// Creates a new instance based on this 14 | /// configuration. The newly-created instance contains unique key material and is distinct 15 | /// from all other descriptors created by the method. 16 | /// 17 | /// A unique . 18 | public abstract IAuthenticatedEncryptorDescriptor CreateNewDescriptor(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorDescriptorDeserializer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 8 | { 9 | /// 10 | /// A class that can deserialize an that represents the serialized version 11 | /// of an . 12 | /// 13 | public sealed class CngGcmAuthenticatedEncryptorDescriptorDeserializer : IAuthenticatedEncryptorDescriptorDeserializer 14 | { 15 | 16 | /// 17 | /// Imports the from serialized XML. 18 | /// 19 | public IAuthenticatedEncryptorDescriptor ImportFromXml(XElement element) 20 | { 21 | if (element == null) 22 | { 23 | throw new ArgumentNullException(nameof(element)); 24 | } 25 | 26 | // 27 | // 28 | // 29 | // ... 30 | // 31 | 32 | var configuration = new CngGcmAuthenticatedEncryptorConfiguration(); 33 | 34 | var encryptionElement = element.Element("encryption"); 35 | configuration.EncryptionAlgorithm = (string)encryptionElement.Attribute("algorithm"); 36 | configuration.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength"); 37 | configuration.EncryptionAlgorithmProvider = (string)encryptionElement.Attribute("provider"); // could be null 38 | 39 | Secret masterKey = ((string)element.Element("masterKey")).ToSecret(); 40 | 41 | return new CngGcmAuthenticatedEncryptorDescriptor(configuration, masterKey); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/IAuthenticatedEncryptorDescriptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 8 | { 9 | /// 10 | /// A self-contained descriptor that wraps all information (including secret key 11 | /// material) necessary to create an instance of an . 12 | /// 13 | public interface IAuthenticatedEncryptorDescriptor 14 | { 15 | /// 16 | /// Exports the current descriptor to XML. 17 | /// 18 | /// 19 | /// An wrapping the which represents the serialized 20 | /// current descriptor object. The deserializer type must be assignable to . 21 | /// 22 | /// 23 | /// If an element contains sensitive information (such as key material), the 24 | /// element should be marked via the 25 | /// extension method, and the caller should encrypt the element before persisting 26 | /// the XML to storage. 27 | /// 28 | XmlSerializedDescriptorInfo ExportToXml(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/IAuthenticatedEncryptorDescriptorDeserializer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Xml.Linq; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 7 | { 8 | /// 9 | /// The basic interface for deserializing an XML element into an . 10 | /// 11 | public interface IAuthenticatedEncryptorDescriptorDeserializer 12 | { 13 | /// 14 | /// Deserializes the specified XML element. 15 | /// 16 | /// The element to deserialize. 17 | /// The represented by . 18 | IAuthenticatedEncryptorDescriptor ImportFromXml(XElement element); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/IInternalAlgorithmConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 5 | { 6 | /// 7 | /// A type that knows how to create instances of an 8 | /// given specific secret key material. 9 | /// 10 | /// 11 | /// This type is not public because we don't want to lock ourselves into a contract stating 12 | /// that a descriptor is simply a configuration plus a single serializable, reproducible secret. 13 | /// 14 | internal interface IInternalAlgorithmConfiguration 15 | { 16 | /// 17 | /// Creates a new instance from this configuration 18 | /// given specific secret key material. 19 | /// 20 | IAuthenticatedEncryptorDescriptor CreateDescriptorFromSecret(ISecret secret); 21 | 22 | /// 23 | /// Performs a self-test of the algorithm specified by the configuration object. 24 | /// 25 | void Validate(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/XmlExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 8 | { 9 | public static class XmlExtensions 10 | { 11 | internal static bool IsMarkedAsRequiringEncryption(this XElement element) 12 | { 13 | return ((bool?)element.Attribute(XmlConstants.RequiresEncryptionAttributeName)).GetValueOrDefault(); 14 | } 15 | 16 | /// 17 | /// Marks the provided as requiring encryption before being persisted 18 | /// to storage. Use when implementing . 19 | /// 20 | public static void MarkAsRequiresEncryption(this XElement element) 21 | { 22 | if (element == null) 23 | { 24 | throw new ArgumentNullException(nameof(element)); 25 | } 26 | 27 | element.SetAttributeValue(XmlConstants.RequiresEncryptionAttributeName, true); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/EncryptionAlgorithm.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption 5 | { 6 | /// 7 | /// Specifies a symmetric encryption algorithm to use for providing confidentiality 8 | /// to protected payloads. 9 | /// 10 | public enum EncryptionAlgorithm 11 | { 12 | /// 13 | /// The AES algorithm (FIPS 197) with a 128-bit key running in Cipher Block Chaining mode. 14 | /// 15 | AES_128_CBC, 16 | 17 | /// 18 | /// The AES algorithm (FIPS 197) with a 192-bit key running in Cipher Block Chaining mode. 19 | /// 20 | AES_192_CBC, 21 | 22 | /// 23 | /// The AES algorithm (FIPS 197) with a 256-bit key running in Cipher Block Chaining mode. 24 | /// 25 | AES_256_CBC, 26 | 27 | /// 28 | /// The AES algorithm (FIPS 197) with a 128-bit key running in Galois/Counter Mode (FIPS SP 800-38D). 29 | /// 30 | /// 31 | /// This cipher mode produces a 128-bit authentication tag. This algorithm is currently only 32 | /// supported on Windows. 33 | /// 34 | AES_128_GCM, 35 | 36 | /// 37 | /// The AES algorithm (FIPS 197) with a 192-bit key running in Galois/Counter Mode (FIPS SP 800-38D). 38 | /// 39 | /// 40 | /// This cipher mode produces a 128-bit authentication tag. 41 | /// 42 | AES_192_GCM, 43 | 44 | /// 45 | /// The AES algorithm (FIPS 197) with a 256-bit key running in Galois/Counter Mode (FIPS SP 800-38D). 46 | /// 47 | /// 48 | /// This cipher mode produces a 128-bit authentication tag. 49 | /// 50 | AES_256_GCM, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/IAuthenticatedEncryptorFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption 8 | { 9 | public interface IAuthenticatedEncryptorFactory 10 | { 11 | /// 12 | /// Creates an instance based on the given . 13 | /// 14 | /// An instance. 15 | /// 16 | /// For a given , any two instances returned by this method should 17 | /// be considered equivalent, e.g., the payload returned by one's 18 | /// method should be consumable by the other's method. 19 | /// 20 | IAuthenticatedEncryptor CreateEncryptorInstance(IKey key); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ValidationAlgorithm.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption 7 | { 8 | /// 9 | /// Specifies a message authentication algorithm to use for providing tamper-proofing 10 | /// to protected payloads. 11 | /// 12 | public enum ValidationAlgorithm 13 | { 14 | /// 15 | /// The HMAC algorithm (RFC 2104) using the SHA-256 hash function (FIPS 180-4). 16 | /// 17 | HMACSHA256, 18 | 19 | /// 20 | /// The HMAC algorithm (RFC 2104) using the SHA-512 hash function (FIPS 180-4). 21 | /// 22 | HMACSHA512, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Cng/BCryptGenRandomImpl.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Cryptography.Cng; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.Cng 8 | { 9 | internal unsafe sealed class BCryptGenRandomImpl : IBCryptGenRandom 10 | { 11 | public static readonly BCryptGenRandomImpl Instance = new BCryptGenRandomImpl(); 12 | 13 | private BCryptGenRandomImpl() 14 | { 15 | } 16 | 17 | public void GenRandom(byte* pbBuffer, uint cbBuffer) 18 | { 19 | BCryptUtil.GenRandom(pbBuffer, cbBuffer); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Cng/IBCryptGenRandom.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.Cng 7 | { 8 | internal unsafe interface IBCryptGenRandom 9 | { 10 | void GenRandom(byte* pbBuffer, uint cbBuffer); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/DataProtectionOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection 7 | { 8 | /// 9 | /// Provides global options for the Data Protection system. 10 | /// 11 | public class DataProtectionOptions 12 | { 13 | /// 14 | /// An identifier that uniquely discriminates this application from all other 15 | /// applications on the machine. The discriminator value is implicitly included 16 | /// in all protected payloads generated by the data protection system to isolate 17 | /// multiple logical applications that all happen to be using the same key material. 18 | /// 19 | /// 20 | /// If two different applications need to share protected payloads, they should 21 | /// ensure that this property is set to the same value across both applications. 22 | /// 23 | public string ApplicationDiscriminator { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/IPersistedDataProtector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection 7 | { 8 | /// 9 | /// An interface that can provide data protection services for data which has been persisted 10 | /// to long-term storage. 11 | /// 12 | public interface IPersistedDataProtector : IDataProtector 13 | { 14 | /// 15 | /// Cryptographically unprotects a piece of data, optionally ignoring failures due to 16 | /// revocation of the cryptographic keys used to protect the payload. 17 | /// 18 | /// The protected data to unprotect. 19 | /// 'true' if the payload should be unprotected even 20 | /// if the cryptographic key used to protect it has been revoked (due to potential compromise), 21 | /// 'false' if revocation should fail the unprotect operation. 22 | /// 'true' if the data should be reprotected before being 23 | /// persisted back to long-term storage, 'false' otherwise. Migration might be requested 24 | /// when the default protection key has changed, for instance. 25 | /// 'true' if the cryptographic key used to protect this payload 26 | /// has been revoked, 'false' otherwise. Payloads whose keys have been revoked should be 27 | /// treated as suspect unless the application has separate assurance that the payload 28 | /// has not been tampered with. 29 | /// The plaintext form of the protected data. 30 | /// 31 | /// Implementations should throw CryptographicException if the protected data is 32 | /// invalid or malformed. 33 | /// 34 | byte[] DangerousUnprotect(byte[] protectedData, bool ignoreRevocationErrors, out bool requiresMigration, out bool wasRevoked); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/IRegistryPolicyResolver.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection 5 | { 6 | // Single implementation of this interface is conditionally added to DI on Windows 7 | // We have to use interface because some DI implementations would try to activate class 8 | // even if it was not registered causing problems crossplat 9 | internal interface IRegistryPolicyResolver 10 | { 11 | RegistryPolicy ResolvePolicy(); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/ISecret.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection 7 | { 8 | /// 9 | /// Represents a secret value. 10 | /// 11 | public interface ISecret : IDisposable 12 | { 13 | /// 14 | /// The length (in bytes) of the secret value. 15 | /// 16 | int Length { get; } 17 | 18 | /// 19 | /// Writes the secret value to the specified buffer. 20 | /// 21 | /// The buffer which should receive the secret value. 22 | /// 23 | /// The buffer size must exactly match the length of the secret value. 24 | /// 25 | void WriteSecretIntoBuffer(ArraySegment buffer); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.Internal 8 | { 9 | /// 10 | /// Default implementation of . 11 | /// 12 | public class DataProtectionBuilder : IDataProtectionBuilder 13 | { 14 | /// 15 | /// Creates a new configuration object linked to a . 16 | /// 17 | public DataProtectionBuilder(IServiceCollection services) 18 | { 19 | if (services == null) 20 | { 21 | throw new ArgumentNullException(nameof(services)); 22 | } 23 | 24 | Services = services; 25 | } 26 | 27 | /// 28 | public IServiceCollection Services { get; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionOptionsSetup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.Extensions.Options; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.Internal 8 | { 9 | internal class DataProtectionOptionsSetup : IConfigureOptions 10 | { 11 | private readonly IServiceProvider _services; 12 | 13 | public DataProtectionOptionsSetup(IServiceProvider provider) 14 | { 15 | _services = provider; 16 | } 17 | 18 | public void Configure(DataProtectionOptions options) 19 | { 20 | options.ApplicationDiscriminator = _services.GetApplicationUniqueIdentifier(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionStartupFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using Microsoft.Extensions.Logging.Abstractions; 10 | 11 | namespace Microsoft.AspNetCore.DataProtection.Internal 12 | { 13 | internal class DataProtectionStartupFilter : IStartupFilter 14 | { 15 | private readonly IKeyRingProvider _keyRingProvider; 16 | private readonly ILogger _logger; 17 | 18 | public DataProtectionStartupFilter(IKeyRingProvider keyRingProvider) 19 | : this(keyRingProvider, NullLoggerFactory.Instance) 20 | { } 21 | 22 | public DataProtectionStartupFilter(IKeyRingProvider keyRingProvider, ILoggerFactory loggerFactory) 23 | { 24 | _keyRingProvider = keyRingProvider; 25 | _logger = loggerFactory.CreateLogger(); 26 | } 27 | 28 | public Action Configure(Action next) 29 | { 30 | try 31 | { 32 | // It doesn't look like much, but this preloads the key ring, 33 | // which in turn may load data from remote stores like Redis or Azure. 34 | var keyRing = _keyRingProvider.GetCurrentKeyRing(); 35 | 36 | _logger.KeyRingWasLoadedOnStartup(keyRing.DefaultKeyId); 37 | } 38 | catch (Exception ex) 39 | { 40 | // This should be non-fatal, so swallow, log, and allow server startup to continue. 41 | // The KeyRingProvider may be able to try again on the first request. 42 | _logger.KeyRingFailedToLoadOnStartup(ex); 43 | } 44 | 45 | return next; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Internal/HostingApplicationDiscriminator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.Infrastructure; 5 | using Microsoft.AspNetCore.Hosting; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.Internal 8 | { 9 | internal class HostingApplicationDiscriminator : IApplicationDiscriminator 10 | { 11 | private readonly IHostingEnvironment _hosting; 12 | 13 | // the optional constructor for when IHostingEnvironment is not available from DI 14 | public HostingApplicationDiscriminator() 15 | { 16 | } 17 | 18 | public HostingApplicationDiscriminator(IHostingEnvironment hosting) 19 | { 20 | _hosting = hosting; 21 | } 22 | 23 | public string Discriminator => _hosting?.ContentRootPath; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Internal/IActivator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.Internal 7 | { 8 | /// 9 | /// An interface into that also supports 10 | /// limited dependency injection (of ). 11 | /// 12 | public interface IActivator 13 | { 14 | /// 15 | /// Creates an instance of and ensures 16 | /// that it is assignable to . 17 | /// 18 | object CreateInstance(Type expectedBaseType, string implementationTypeName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/IKeyEscrowSink.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | using Microsoft.AspNetCore.DataProtection.Repositories; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement 9 | { 10 | /// 11 | /// The basic interface for implementing a key escrow sink. 12 | /// 13 | /// 14 | /// is distinct from in that 15 | /// provides a write-only interface and instances handle unencrypted key material, 16 | /// while provides a read+write interface and instances handle encrypted key material. 17 | /// 18 | public interface IKeyEscrowSink 19 | { 20 | /// 21 | /// Stores the given key material to the escrow service. 22 | /// 23 | /// The id of the key being persisted to escrow. 24 | /// The unencrypted XML element that comprises the key material. 25 | void Store(Guid keyId, XElement element); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Internal/DefaultKeyResolution.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal 7 | { 8 | public struct DefaultKeyResolution 9 | { 10 | /// 11 | /// The default key, may be null if no key is a good default candidate. 12 | /// 13 | /// 14 | /// If this property is non-null, its method will succeed 15 | /// so is appropriate for use with deferred keys. 16 | /// 17 | public IKey DefaultKey; 18 | 19 | /// 20 | /// The fallback key, which should be used only if the caller is configured not to 21 | /// honor the property. This property may 22 | /// be null if there is no viable fallback key. 23 | /// 24 | /// 25 | /// If this property is non-null, its method will succeed 26 | /// so is appropriate for use with deferred keys. 27 | /// 28 | public IKey FallbackKey; 29 | 30 | /// 31 | /// 'true' if a new key should be persisted to the keyring, 'false' otherwise. 32 | /// This value may be 'true' even if a valid default key was found. 33 | /// 34 | public bool ShouldGenerateNewKey; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Internal/ICacheableKeyRingProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal 7 | { 8 | public interface ICacheableKeyRingProvider 9 | { 10 | CacheableKeyRing GetCacheableKeyRing(DateTimeOffset now); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Internal/IDefaultKeyResolver.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal 8 | { 9 | /// 10 | /// Implements policy for resolving the default key from a candidate keyring. 11 | /// 12 | public interface IDefaultKeyResolver 13 | { 14 | /// 15 | /// Locates the default key from the keyring. 16 | /// 17 | DefaultKeyResolution ResolveDefaultKeyPolicy(DateTimeOffset now, IEnumerable allKeys); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Internal/IInternalXmlKeyManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal 9 | { 10 | public interface IInternalXmlKeyManager 11 | { 12 | IKey CreateNewKey(Guid keyId, DateTimeOffset creationDate, DateTimeOffset activationDate, DateTimeOffset expirationDate); 13 | 14 | IAuthenticatedEncryptorDescriptor DeserializeDescriptorFromKeyElement(XElement keyElement); 15 | 16 | void RevokeSingleKey(Guid keyId, DateTimeOffset revocationDate, string reason); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Internal/IKeyRing.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal 8 | { 9 | /// 10 | /// The basic interface for accessing a read-only keyring. 11 | /// 12 | public interface IKeyRing 13 | { 14 | /// 15 | /// The authenticated encryptor that shall be used for new encryption operations. 16 | /// 17 | /// 18 | /// Activation of the encryptor instance is deferred until first access. 19 | /// 20 | IAuthenticatedEncryptor DefaultAuthenticatedEncryptor { get; } 21 | 22 | /// 23 | /// The id of the key associated with . 24 | /// 25 | Guid DefaultKeyId { get; } 26 | 27 | /// 28 | /// Returns an encryptor instance for the given key, or 'null' if the key with the 29 | /// specified id cannot be found in the keyring. 30 | /// 31 | /// 32 | /// Activation of the encryptor instance is deferred until first access. 33 | /// 34 | IAuthenticatedEncryptor GetAuthenticatedEncryptorByKeyId(Guid keyId, out bool isRevoked); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Internal/IKeyRingProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement.Internal 5 | { 6 | public interface IKeyRingProvider 7 | { 8 | IKeyRing GetCurrentKeyRing(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/Key.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; 7 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 8 | 9 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement 10 | { 11 | /// 12 | /// The basic implementation of , where the 13 | /// has already been created. 14 | /// 15 | internal sealed class Key : KeyBase 16 | { 17 | public Key( 18 | Guid keyId, 19 | DateTimeOffset creationDate, 20 | DateTimeOffset activationDate, 21 | DateTimeOffset expirationDate, 22 | IAuthenticatedEncryptorDescriptor descriptor, 23 | IEnumerable encryptorFactories) 24 | : base(keyId, 25 | creationDate, 26 | activationDate, 27 | expirationDate, 28 | new Lazy(() => descriptor), 29 | encryptorFactories) 30 | { 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyEscrowServiceProviderExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Xml.Linq; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement 11 | { 12 | internal static class KeyEscrowServiceProviderExtensions 13 | { 14 | /// 15 | /// Gets an aggregate from the underlying . 16 | /// This method may return null if no sinks are registered. 17 | /// 18 | public static IKeyEscrowSink GetKeyEscrowSink(this IServiceProvider services) 19 | { 20 | var escrowSinks = services?.GetService>()?.ToList(); 21 | return (escrowSinks != null && escrowSinks.Count > 0) ? new AggregateKeyEscrowSink(escrowSinks) : null; 22 | } 23 | 24 | private sealed class AggregateKeyEscrowSink : IKeyEscrowSink 25 | { 26 | private readonly List _sinks; 27 | 28 | public AggregateKeyEscrowSink(List sinks) 29 | { 30 | _sinks = sinks; 31 | } 32 | 33 | public void Store(Guid keyId, XElement element) 34 | { 35 | foreach (var sink in _sinks) 36 | { 37 | sink.Store(keyId, element); 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement 7 | { 8 | internal static class KeyExtensions 9 | { 10 | public static bool IsExpired(this IKey key, DateTimeOffset now) 11 | { 12 | return (key.ExpirationDate <= now); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyRingBasedDataProtectionProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement 9 | { 10 | internal unsafe sealed class KeyRingBasedDataProtectionProvider : IDataProtectionProvider 11 | { 12 | private readonly IKeyRingProvider _keyRingProvider; 13 | private readonly ILogger _logger; 14 | 15 | public KeyRingBasedDataProtectionProvider(IKeyRingProvider keyRingProvider, ILoggerFactory loggerFactory) 16 | { 17 | _keyRingProvider = keyRingProvider; 18 | _logger = loggerFactory.CreateLogger(); // note: for protector (not provider!) type 19 | } 20 | 21 | public IDataProtector CreateProtector(string purpose) 22 | { 23 | if (purpose == null) 24 | { 25 | throw new ArgumentNullException(nameof(purpose)); 26 | } 27 | 28 | return new KeyRingBasedDataProtector( 29 | logger: _logger, 30 | keyRingProvider: _keyRingProvider, 31 | originalPurposes: null, 32 | newPurpose: purpose); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/LoggingServiceProviderExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace System 9 | { 10 | /// 11 | /// Helpful logging-related extension methods on . 12 | /// 13 | internal static class LoggingServiceProviderExtensions 14 | { 15 | /// 16 | /// Retrieves an instance of given the type name . 17 | /// This is equivalent to . 18 | /// 19 | /// 20 | /// An instance, or null if is null or the 21 | /// cannot produce an . 22 | /// 23 | public static ILogger GetLogger(this IServiceProvider services) 24 | { 25 | return GetLogger(services, typeof(T)); 26 | } 27 | 28 | /// 29 | /// Retrieves an instance of given the type name . 30 | /// This is equivalent to . 31 | /// 32 | /// 33 | /// An instance, or null if is null or the 34 | /// cannot produce an . 35 | /// 36 | public static ILogger GetLogger(this IServiceProvider services, Type type) 37 | { 38 | // Compiler won't allow us to use static types as the type parameter 39 | // for the call to CreateLogger, so we'll duplicate its logic here. 40 | return services?.GetService()?.CreateLogger(type.FullName); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Managed/HashAlgorithmExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | using Microsoft.AspNetCore.Cryptography; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.Managed 9 | { 10 | internal static class HashAlgorithmExtensions 11 | { 12 | public static int GetDigestSizeInBytes(this HashAlgorithm hashAlgorithm) 13 | { 14 | var hashSizeInBits = hashAlgorithm.HashSize; 15 | CryptoUtil.Assert(hashSizeInBits >= 0 && hashSizeInBits % 8 == 0, "hashSizeInBits >= 0 && hashSizeInBits % 8 == 0"); 16 | return hashSizeInBits / 8; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Managed/IManagedGenRandom.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.Managed 7 | { 8 | internal interface IManagedGenRandom 9 | { 10 | byte[] GenRandom(int numBytes); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Managed/ManagedGenRandomImpl.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.Managed 8 | { 9 | internal unsafe sealed class ManagedGenRandomImpl : IManagedGenRandom 10 | { 11 | private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); 12 | public static readonly ManagedGenRandomImpl Instance = new ManagedGenRandomImpl(); 13 | 14 | private ManagedGenRandomImpl() 15 | { 16 | } 17 | 18 | public byte[] GenRandom(int numBytes) 19 | { 20 | var bytes = new byte[numBytes]; 21 | _rng.GetBytes(bytes); 22 | return bytes; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Managed/SymmetricAlgorithmExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | using Microsoft.AspNetCore.Cryptography; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.Managed 9 | { 10 | internal static class SymmetricAlgorithmExtensions 11 | { 12 | public static int GetBlockSizeInBytes(this SymmetricAlgorithm symmetricAlgorithm) 13 | { 14 | var blockSizeInBits = symmetricAlgorithm.BlockSize; 15 | CryptoUtil.Assert(blockSizeInBits >= 0 && blockSizeInBits % 8 == 0, "blockSizeInBits >= 0 && blockSizeInBits % 8 == 0"); 16 | return blockSizeInBits / 8; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/MemoryProtection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using Microsoft.AspNetCore.Cryptography; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection 9 | { 10 | /// 11 | /// Wrappers around CryptProtectMemory / CryptUnprotectMemory. 12 | /// 13 | internal unsafe static class MemoryProtection 14 | { 15 | // from dpapi.h 16 | private const uint CRYPTPROTECTMEMORY_SAME_PROCESS = 0x00; 17 | 18 | public static void CryptProtectMemory(SafeHandle pBuffer, uint byteCount) 19 | { 20 | if (!UnsafeNativeMethods.CryptProtectMemory(pBuffer, byteCount, CRYPTPROTECTMEMORY_SAME_PROCESS)) 21 | { 22 | UnsafeNativeMethods.ThrowExceptionForLastCrypt32Error(); 23 | } 24 | } 25 | 26 | public static void CryptUnprotectMemory(byte* pBuffer, uint byteCount) 27 | { 28 | if (!UnsafeNativeMethods.CryptUnprotectMemory(pBuffer, byteCount, CRYPTPROTECTMEMORY_SAME_PROCESS)) 29 | { 30 | UnsafeNativeMethods.ThrowExceptionForLastCrypt32Error(); 31 | } 32 | } 33 | 34 | public static void CryptUnprotectMemory(SafeHandle pBuffer, uint byteCount) 35 | { 36 | if (!UnsafeNativeMethods.CryptUnprotectMemory(pBuffer, byteCount, CRYPTPROTECTMEMORY_SAME_PROCESS)) 37 | { 38 | UnsafeNativeMethods.ThrowExceptionForLastCrypt32Error(); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Microsoft.AspNetCore.DataProtection.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ASP.NET Core logic to protect and unprotect data, similar to DPAPI. 5 | netstandard2.0 6 | $(NoWarn);CS1591 7 | true 8 | true 9 | aspnetcore;dataprotection 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | // for unit testing 7 | [assembly: InternalsVisibleTo("Microsoft.AspNetCore.DataProtection.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 8 | [assembly: InternalsVisibleTo("Microsoft.AspNetCore.DataProtection.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] 9 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 10 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/RegistryPolicy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 6 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection 9 | { 10 | internal class RegistryPolicy 11 | { 12 | public RegistryPolicy( 13 | AlgorithmConfiguration configuration, 14 | IEnumerable keyEscrowSinks, 15 | int? defaultKeyLifetime) 16 | { 17 | EncryptorConfiguration = configuration; 18 | KeyEscrowSinks = keyEscrowSinks; 19 | DefaultKeyLifetime = defaultKeyLifetime; 20 | } 21 | 22 | public AlgorithmConfiguration EncryptorConfiguration { get; } 23 | 24 | public IEnumerable KeyEscrowSinks { get; } 25 | 26 | public int? DefaultKeyLifetime { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Repositories/IDefaultKeyStorageDirectory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.IO; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.Repositories 7 | { 8 | /// 9 | /// This interface enables overridding the default storage location of keys on disk 10 | /// 11 | internal interface IDefaultKeyStorageDirectories 12 | { 13 | DirectoryInfo GetKeyStorageDirectory(); 14 | 15 | DirectoryInfo GetKeyStorageDirectoryForAzureWebSites(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/Repositories/IXmlRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Xml.Linq; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.Repositories 9 | { 10 | /// 11 | /// The basic interface for storing and retrieving XML elements. 12 | /// 13 | public interface IXmlRepository 14 | { 15 | /// 16 | /// Gets all top-level XML elements in the repository. 17 | /// 18 | /// 19 | /// All top-level elements in the repository. 20 | /// 21 | IReadOnlyCollection GetAllElements(); 22 | 23 | /// 24 | /// Adds a top-level XML element to the repository. 25 | /// 26 | /// The element to add. 27 | /// An optional name to be associated with the XML element. 28 | /// For instance, if this repository stores XML files on disk, the friendly name may 29 | /// be used as part of the file name. Repository implementations are not required to 30 | /// observe this parameter even if it has been provided by the caller. 31 | /// 32 | /// The 'friendlyName' parameter must be unique if specified. For instance, it could 33 | /// be the id of the key being stored. 34 | /// 35 | void StoreElement(XElement element, string friendlyName); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/SP800_108/ISP800_108_CTR_HMACSHA512Provider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.SP800_108 7 | { 8 | internal unsafe interface ISP800_108_CTR_HMACSHA512Provider : IDisposable 9 | { 10 | void DeriveKey(byte* pbLabel, uint cbLabel, byte* pbContext, uint cbContext, byte* pbDerivedKey, uint cbDerivedKey); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/SP800_108/SP800_108_CTR_HMACSHA512Extensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Cryptography; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.SP800_108 8 | { 9 | internal unsafe static class SP800_108_CTR_HMACSHA512Extensions 10 | { 11 | public static void DeriveKeyWithContextHeader(this ISP800_108_CTR_HMACSHA512Provider provider, byte* pbLabel, uint cbLabel, byte[] contextHeader, byte* pbContext, uint cbContext, byte* pbDerivedKey, uint cbDerivedKey) 12 | { 13 | var cbCombinedContext = checked((uint)contextHeader.Length + cbContext); 14 | 15 | // Try allocating the combined context on the stack to avoid temporary managed objects; only fall back to heap if buffers are too large. 16 | byte[] heapAllocatedCombinedContext = (cbCombinedContext > Constants.MAX_STACKALLOC_BYTES) ? new byte[cbCombinedContext] : null; 17 | fixed (byte* pbHeapAllocatedCombinedContext = heapAllocatedCombinedContext) 18 | { 19 | byte* pbCombinedContext = pbHeapAllocatedCombinedContext; 20 | if (pbCombinedContext == null) 21 | { 22 | byte* pbStackAllocatedCombinedContext = stackalloc byte[(int)cbCombinedContext]; // will be released when frame pops 23 | pbCombinedContext = pbStackAllocatedCombinedContext; 24 | } 25 | 26 | fixed (byte* pbContextHeader = contextHeader) 27 | { 28 | UnsafeBufferUtil.BlockCopy(from: pbContextHeader, to: pbCombinedContext, byteCount: contextHeader.Length); 29 | } 30 | UnsafeBufferUtil.BlockCopy(from: pbContext, to: &pbCombinedContext[contextHeader.Length], byteCount: cbContext); 31 | 32 | // At this point, combinedContext := { contextHeader || context } 33 | provider.DeriveKey(pbLabel, cbLabel, pbCombinedContext, cbCombinedContext, pbDerivedKey, cbDerivedKey); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | /// 10 | /// Helpful extension methods on . 11 | /// 12 | internal static class TypeExtensions 13 | { 14 | /// 15 | /// Throws if 16 | /// is not assignable to . 17 | /// 18 | public static void AssertIsAssignableFrom(this Type expectedBaseType, Type implementationType) 19 | { 20 | if (!expectedBaseType.IsAssignableFrom(implementationType)) 21 | { 22 | // It might seem a bit weird to throw an InvalidCastException explicitly rather than 23 | // to let the CLR generate one, but searching through NetFX there is indeed precedent 24 | // for this pattern when the caller knows ahead of time the operation will fail. 25 | throw new InvalidCastException(Resources.FormatTypeExtensions_BadCast( 26 | expectedBaseType.AssemblyQualifiedName, implementationType.AssemblyQualifiedName)); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | /// 10 | /// Contains XLinq constants. 11 | /// 12 | internal static class XmlConstants 13 | { 14 | /// 15 | /// The root namespace used for all DataProtection-specific XML elements and attributes. 16 | /// 17 | private static readonly XNamespace RootNamespace = XNamespace.Get("http://schemas.asp.net/2015/03/dataProtection"); 18 | 19 | /// 20 | /// Represents the type of decryptor that can be used when reading 'encryptedSecret' elements. 21 | /// 22 | internal static readonly XName DecryptorTypeAttributeName = "decryptorType"; 23 | 24 | /// 25 | /// Elements with this attribute will be read with the specified deserializer type. 26 | /// 27 | internal static readonly XName DeserializerTypeAttributeName = "deserializerType"; 28 | 29 | /// 30 | /// Elements with this name will be automatically decrypted when read by the XML key manager. 31 | /// 32 | internal static readonly XName EncryptedSecretElementName = RootNamespace.GetName("encryptedSecret"); 33 | 34 | /// 35 | /// Elements where this attribute has a value of 'true' should be encrypted before storage. 36 | /// 37 | internal static readonly XName RequiresEncryptionAttributeName = RootNamespace.GetName("requiresEncryption"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/DpapiNGProtectionDescriptorFlags.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 7 | { 8 | /// 9 | /// Flags used to control the creation of protection descriptors. 10 | /// 11 | /// 12 | /// These values correspond to the 'dwFlags' parameter on NCryptCreateProtectionDescriptor. 13 | /// See https://msdn.microsoft.com/en-us/library/windows/desktop/hh706800(v=vs.85).aspx for more information. 14 | /// 15 | [Flags] 16 | public enum DpapiNGProtectionDescriptorFlags 17 | { 18 | /// 19 | /// No special handling is necessary. 20 | /// 21 | None = 0, 22 | 23 | /// 24 | /// The provided descriptor is a reference to a full descriptor stored 25 | /// in the system registry. 26 | /// 27 | NamedDescriptor = 0x00000001, 28 | 29 | /// 30 | /// When combined with , uses the HKLM registry 31 | /// instead of the HKCU registry when locating the full descriptor. 32 | /// 33 | MachineKey = 0x00000020, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/ICertificateResolver.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Security.Cryptography.X509Certificates; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 7 | { 8 | /// 9 | /// Provides services for locating instances. 10 | /// 11 | public interface ICertificateResolver 12 | { 13 | /// 14 | /// Locates an given its thumbprint. 15 | /// 16 | /// The thumbprint (as a hex string) of the certificate to resolve. 17 | /// The resolved , or null if the certificate cannot be found. 18 | X509Certificate2 ResolveCertificate(string thumbprint); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/IInternalCertificateXmlEncryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml; 6 | using System.Security.Cryptography.Xml; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 9 | { 10 | /// 11 | /// Internal implementation details of for unit testing. 12 | /// 13 | internal interface IInternalCertificateXmlEncryptor 14 | { 15 | EncryptedData PerformEncryption(EncryptedXml encryptedXml, XmlElement elementToEncrypt); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/IInternalEncryptedXmlDecryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography.Xml; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 8 | { 9 | /// 10 | /// Internal implementation details of for unit testing. 11 | /// 12 | internal interface IInternalEncryptedXmlDecryptor 13 | { 14 | void PerformPreDecryptionSetup(EncryptedXml encryptedXml); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/IXmlDecryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Xml.Linq; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 7 | { 8 | /// 9 | /// The basic interface for decrypting an XML element. 10 | /// 11 | public interface IXmlDecryptor 12 | { 13 | /// 14 | /// Decrypts the specified XML element. 15 | /// 16 | /// An encrypted XML element. 17 | /// The decrypted form of . 18 | /// 19 | /// Implementations of this method must not mutate the 20 | /// instance provided by . 21 | /// 22 | XElement Decrypt(XElement encryptedElement); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/IXmlEncryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Xml.Linq; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 7 | { 8 | /// 9 | /// The basic interface for encrypting XML elements. 10 | /// 11 | public interface IXmlEncryptor 12 | { 13 | /// 14 | /// Encrypts the specified . 15 | /// 16 | /// The plaintext to encrypt. 17 | /// 18 | /// An that contains the encrypted value of 19 | /// along with information about how to 20 | /// decrypt it. 21 | /// 22 | /// 23 | /// Implementations of this method must not mutate the 24 | /// instance provided by . 25 | /// 26 | EncryptedXmlInfo Encrypt(XElement plaintextElement); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/NullXmlDecryptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Xml.Linq; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 9 | { 10 | /// 11 | /// An that decrypts XML elements with a null decryptor. 12 | /// 13 | public sealed class NullXmlDecryptor : IXmlDecryptor 14 | { 15 | /// 16 | /// Decrypts the specified XML element. 17 | /// 18 | /// An encrypted XML element. 19 | /// The decrypted form of . 20 | public XElement Decrypt(XElement encryptedElement) 21 | { 22 | if (encryptedElement == null) 23 | { 24 | throw new ArgumentNullException(nameof(encryptedElement)); 25 | } 26 | 27 | // 28 | // 29 | // 30 | // 31 | 32 | // Return a clone of the single child node. 33 | return new XElement(encryptedElement.Elements().Single()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlEncryption/XmlKeyDecryptionOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Security.Cryptography.X509Certificates; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 9 | { 10 | /// 11 | /// Specifies settings for how to decrypt XML keys. 12 | /// 13 | internal class XmlKeyDecryptionOptions 14 | { 15 | private readonly Dictionary> _certs = new Dictionary>(StringComparer.Ordinal); 16 | 17 | public int KeyDecryptionCertificateCount => _certs.Count; 18 | 19 | public bool TryGetKeyDecryptionCertificates(X509Certificate2 certInfo, out IReadOnlyList keyDecryptionCerts) 20 | { 21 | var key = GetKey(certInfo); 22 | var retVal = _certs.TryGetValue(key, out var keyDecryptionCertsRetVal); 23 | keyDecryptionCerts = keyDecryptionCertsRetVal; 24 | return retVal; 25 | } 26 | 27 | public void AddKeyDecryptionCertificate(X509Certificate2 certificate) 28 | { 29 | var key = GetKey(certificate); 30 | if (!_certs.TryGetValue(key, out var certificates)) 31 | { 32 | certificates = _certs[key] = new List(); 33 | } 34 | certificates.Add(certificate); 35 | } 36 | 37 | private string GetKey(X509Certificate2 cert) => cert.Thumbprint; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Microsoft.AspNetCore.DataProtection/XmlExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | /// 10 | /// Contains helpers to work with XElement objects. 11 | /// 12 | internal static class XmlExtensions 13 | { 14 | /// 15 | /// Returns a new XElement which is a carbon copy of the provided element, 16 | /// but with no child nodes. Useful for writing exception messages without 17 | /// inadvertently disclosing secret key material. It is assumed that the 18 | /// element name itself and its attribute values are not secret. 19 | /// 20 | public static XElement WithoutChildNodes(this XElement element) 21 | { 22 | var newElement = new XElement(element.Name); 23 | foreach (var attr in element.Attributes()) 24 | { 25 | newElement.SetAttributeValue(attr.Name, attr.Value); 26 | } 27 | return newElement; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/CreateTestCert.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Generates a new test cert in a .pfx file 3 | # Obviously, don't actually use this to produce production certs 4 | # 5 | 6 | param( 7 | [Parameter(Mandatory = $true)] 8 | $OutFile 9 | ) 10 | 11 | $password = ConvertTo-SecureString -Force -AsPlainText -String "password" 12 | $cert = New-SelfSignedCertificate -DnsName "localhost" -CertStoreLocation Cert:\CurrentUser\My\ 13 | Export-PfxCertificate -Cert $cert -Password $password -FilePath $OutFile 14 | Remove-Item "Cert:\CurrentUser\My\$($cert.Thumbprint)" 15 | -------------------------------------------------------------------------------- /test/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | netcoreapp3.0 6 | $(DeveloperBuildTestTfms) 7 | 8 | $(StandardTestTfms);net461 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.Internal.Test/Cng/BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_Tests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.Cng 8 | { 9 | public unsafe class BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_Tests 10 | { 11 | [Fact] 12 | public void Init_SetsProperties() 13 | { 14 | // Act 15 | BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.Init(out var cipherModeInfo); 16 | 17 | // Assert 18 | Assert.Equal((uint)sizeof(BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO), cipherModeInfo.cbSize); 19 | Assert.Equal(1U, cipherModeInfo.dwInfoVersion); 20 | Assert.Equal(IntPtr.Zero, (IntPtr)cipherModeInfo.pbNonce); 21 | Assert.Equal(0U, cipherModeInfo.cbNonce); 22 | Assert.Equal(IntPtr.Zero, (IntPtr)cipherModeInfo.pbAuthData); 23 | Assert.Equal(0U, cipherModeInfo.cbAuthData); 24 | Assert.Equal(IntPtr.Zero, (IntPtr)cipherModeInfo.pbTag); 25 | Assert.Equal(0U, cipherModeInfo.cbTag); 26 | Assert.Equal(IntPtr.Zero, (IntPtr)cipherModeInfo.pbMacContext); 27 | Assert.Equal(0U, cipherModeInfo.cbMacContext); 28 | Assert.Equal(0U, cipherModeInfo.cbAAD); 29 | Assert.Equal(0UL, cipherModeInfo.cbData); 30 | Assert.Equal(0U, cipherModeInfo.dwFlags); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.Internal.Test/CryptoUtilTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography 8 | { 9 | public unsafe class CryptoUtilTests 10 | { 11 | [Fact] 12 | public void TimeConstantBuffersAreEqual_Array_Equal() 13 | { 14 | // Arrange 15 | byte[] a = new byte[] { 0x01, 0x23, 0x45, 0x67 }; 16 | byte[] b = new byte[] { 0xAB, 0xCD, 0x23, 0x45, 0x67, 0xEF }; 17 | 18 | // Act & assert 19 | Assert.True(CryptoUtil.TimeConstantBuffersAreEqual(a, 1, 3, b, 2, 3)); 20 | } 21 | 22 | [Fact] 23 | public void TimeConstantBuffersAreEqual_Array_Unequal() 24 | { 25 | byte[] a = new byte[] { 0x01, 0x23, 0x45, 0x67 }; 26 | byte[] b = new byte[] { 0xAB, 0xCD, 0x23, 0xFF, 0x67, 0xEF }; 27 | 28 | // Act & assert 29 | Assert.False(CryptoUtil.TimeConstantBuffersAreEqual(a, 1, 3, b, 2, 3)); 30 | } 31 | 32 | [Fact] 33 | public void TimeConstantBuffersAreEqual_Pointers_Equal() 34 | { 35 | // Arrange 36 | uint a = 0x01234567; 37 | uint b = 0x01234567; 38 | 39 | // Act & assert 40 | Assert.True(CryptoUtil.TimeConstantBuffersAreEqual((byte*)&a, (byte*)&b, sizeof(uint))); 41 | } 42 | 43 | [Fact] 44 | public void TimeConstantBuffersAreEqual_Pointers_Unequal() 45 | { 46 | // Arrange 47 | uint a = 0x01234567; 48 | uint b = 0x89ABCDEF; 49 | 50 | // Act & assert 51 | Assert.False(CryptoUtil.TimeConstantBuffersAreEqual((byte*)&a, (byte*)&b, sizeof(uint))); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.Internal.Test/Microsoft.AspNetCore.Cryptography.Internal.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.Internal.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | // for unit testing 7 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 8 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.Internal.Test/SafeHandles/SecureLocalAllocHandleTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.Cryptography.SafeHandles 8 | { 9 | public unsafe class SecureLocalAllocHandleTests 10 | { 11 | [Fact] 12 | public void Duplicate_Copies_Data() 13 | { 14 | // Arrange 15 | const string expected = "xyz"; 16 | int cbExpected = expected.Length * sizeof(char); 17 | var controlHandle = SecureLocalAllocHandle.Allocate((IntPtr)cbExpected); 18 | for (int i = 0; i < expected.Length; i++) 19 | { 20 | ((char*)controlHandle.DangerousGetHandle())[i] = expected[i]; 21 | } 22 | 23 | // Act 24 | var duplicateHandle = controlHandle.Duplicate(); 25 | 26 | // Assert 27 | Assert.Equal(expected, new string((char*)duplicateHandle.DangerousGetHandle(), 0, expected.Length)); // contents the same data 28 | Assert.NotEqual(controlHandle.DangerousGetHandle(), duplicateHandle.DangerousGetHandle()); // shouldn't just point to the same memory location 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.Cryptography.KeyDerivation.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | // for unit testing 7 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 8 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Abstractions.Test/Microsoft.AspNetCore.DataProtection.Abstractions.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.AzureKeyVault.Test/Microsoft.AspNetCore.DataProtection.AzureKeyVault.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.AzureStorage.Test/AzureDataProtectionBuilderExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Options; 8 | using Microsoft.WindowsAzure.Storage.Blob; 9 | using Xunit; 10 | 11 | namespace Microsoft.AspNetCore.DataProtection.AzureStorage 12 | { 13 | public class AzureDataProtectionBuilderExtensionsTest 14 | { 15 | [Fact] 16 | public void PersistKeysToAzureBlobStorage_UsesAzureBlobXmlRepository() 17 | { 18 | // Arrange 19 | var container = new CloudBlobContainer(new Uri("http://www.example.com")); 20 | var serviceCollection = new ServiceCollection(); 21 | var builder = serviceCollection.AddDataProtection(); 22 | 23 | // Act 24 | builder.PersistKeysToAzureBlobStorage(container, "keys.xml"); 25 | var services = serviceCollection.BuildServiceProvider(); 26 | 27 | // Assert 28 | var options = services.GetRequiredService>(); 29 | Assert.IsType(options.Value.XmlRepository); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.AzureStorage.Test/Microsoft.AspNetCore.DataProtection.AzureStorage.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test/DataProtectionKeyContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.EntityFrameworkCore; 5 | 6 | namespace Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test 7 | { 8 | class DataProtectionKeyContext : DbContext, IDataProtectionKeyContext 9 | { 10 | public DataProtectionKeyContext(DbContextOptions options) : base(options) { } 11 | 12 | public DbSet DataProtectionKeys { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test/EntityFrameworkCoreDataProtectionBuilderExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.Extensions.Options; 7 | using Xunit; 8 | 9 | namespace Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test 10 | { 11 | public class EntityFrameworkCoreDataProtectionBuilderExtensionsTests 12 | { 13 | [Fact] 14 | public void PersistKeysToEntityFrameworkCore_UsesEntityFrameworkCoreXmlRepository() 15 | { 16 | var serviceCollection = new ServiceCollection(); 17 | serviceCollection 18 | .AddDbContext() 19 | .AddDataProtection() 20 | .PersistKeysToDbContext(); 21 | var serviceProvider = serviceCollection.BuildServiceProvider(validateScopes: true); 22 | var keyManagementOptions = serviceProvider.GetRequiredService>(); 23 | Assert.IsType>(keyManagementOptions.Value.XmlRepository); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/Microsoft.AspNetCore.DataProtection.Extensions.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Xunit; 5 | 6 | // Workaround for DataProtectionProviderTests.System_UsesProvidedDirectoryAndCertificate 7 | // https://github.com/aspnet/DataProtection/issues/160 8 | [assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert2.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert2.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert3.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert3.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert3WithoutPrivateKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCert3WithoutPrivateKey.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCertWithoutPrivateKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/TestFiles/TestCertWithoutPrivateKey.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Extensions.Test/X509StoreIsAvailableAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography.X509Certificates; 6 | using Microsoft.AspNetCore.Testing.xunit; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection 9 | { 10 | [AttributeUsage(AttributeTargets.Method)] 11 | public class X509StoreIsAvailableAttribute : Attribute, ITestCondition 12 | { 13 | public X509StoreIsAvailableAttribute(StoreName name, StoreLocation location) 14 | { 15 | Name = name; 16 | Location = location; 17 | } 18 | 19 | public bool IsMet 20 | { 21 | get 22 | { 23 | try 24 | { 25 | using (var store = new X509Store(Name, Location)) 26 | { 27 | store.Open(OpenFlags.ReadWrite); 28 | return true; 29 | } 30 | } 31 | catch 32 | { 33 | return false; 34 | } 35 | } 36 | } 37 | 38 | public string SkipReason => $"Skipping because the X509Store({Name}/{Location}) is not available on this machine."; 39 | 40 | public StoreName Name { get; } 41 | public StoreLocation Location { get; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | PreserveNewest 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test/RedisDataProtectionBuilderExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using Microsoft.Extensions.Options; 7 | using Moq; 8 | using StackExchange.Redis; 9 | using Xunit; 10 | 11 | namespace Microsoft.AspNetCore.DataProtection.StackExchangeRedis 12 | { 13 | public class RedisDataProtectionBuilderExtensionsTest 14 | { 15 | [Fact] 16 | public void PersistKeysToRedis_UsesRedisXmlRepository() 17 | { 18 | // Arrange 19 | var connection = Mock.Of(); 20 | var serviceCollection = new ServiceCollection(); 21 | var builder = serviceCollection.AddDataProtection(); 22 | 23 | // Act 24 | builder.PersistKeysToStackExchangeRedis(connection); 25 | var services = serviceCollection.BuildServiceProvider(); 26 | 27 | // Assert 28 | var options = services.GetRequiredService>(); 29 | Assert.IsType(options.Value.XmlRepository); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test/TestRedisServer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.Extensions.Configuration; 5 | using System; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | internal class TestRedisServer 10 | { 11 | public const string ConnectionStringKeyName = "Test:Redis:Server"; 12 | private static readonly IConfigurationRoot _config; 13 | 14 | static TestRedisServer() 15 | { 16 | _config = new ConfigurationBuilder() 17 | .SetBasePath(AppContext.BaseDirectory) 18 | .AddJsonFile("testconfig.json") 19 | .AddEnvironmentVariables() 20 | .Build(); 21 | } 22 | 23 | internal static string GetConnectionString() 24 | { 25 | return _config[ConnectionStringKeyName]; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test/TestRedisServerIsAvailableAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.Testing.xunit; 5 | using System; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | internal class TestRedisServerIsAvailableAttribute : Attribute, ITestCondition 10 | { 11 | public bool IsMet => !string.IsNullOrEmpty(TestRedisServer.GetConnectionString()); 12 | 13 | public string SkipReason => $"A test redis server must be configured to run. Set the connection string as an environment variable as {TestRedisServer.ConnectionStringKeyName.Replace(":", "__")} or in testconfig.json"; 14 | } 15 | } -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Test/testconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": { 3 | "Redis": { 4 | // You can setup a local Redis server easily with Docker by running 5 | // docker run --rm -it -p 6379:6379 redis 6 | // Then uncomment this config below 7 | // "Server": "localhost:6379,127.0.0.1:6379" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/CngCbcAuthenticatedEncryptorFactoryTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 5 | using Microsoft.AspNetCore.DataProtection.Cng; 6 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 7 | using Microsoft.AspNetCore.DataProtection.Test.Shared; 8 | using Microsoft.AspNetCore.Testing.xunit; 9 | using Microsoft.Extensions.Logging.Abstractions; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption 14 | { 15 | public class CngCbcAuthenticatedEncryptorFactoryTest 16 | { 17 | [Fact] 18 | public void CreateEncrptorInstance_UnknownDescriptorType_ReturnsNull() 19 | { 20 | // Arrange 21 | var key = new Mock(); 22 | key.Setup(k => k.Descriptor).Returns(new Mock().Object); 23 | 24 | var factory = new CngCbcAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); 25 | 26 | // Act 27 | var encryptor = factory.CreateEncryptorInstance(key.Object); 28 | 29 | // Assert 30 | Assert.Null(encryptor); 31 | } 32 | 33 | [ConditionalFact] 34 | [ConditionalRunTestOnlyOnWindows] 35 | public void CreateEncrptorInstance_ExpectedDescriptorType_ReturnsEncryptor() 36 | { 37 | // Arrange 38 | var descriptor = new CngCbcAuthenticatedEncryptorConfiguration().CreateNewDescriptor(); 39 | var key = new Mock(); 40 | key.Setup(k => k.Descriptor).Returns(descriptor); 41 | 42 | var factory = new CngCbcAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); 43 | 44 | // Act 45 | var encryptor = factory.CreateEncryptorInstance(key.Object); 46 | 47 | // Assert 48 | Assert.NotNull(encryptor); 49 | Assert.IsType(encryptor); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/CngGcmAuthenticatedEncryptorFactoryTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 5 | using Microsoft.AspNetCore.DataProtection.Cng; 6 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 7 | using Microsoft.AspNetCore.DataProtection.Test.Shared; 8 | using Microsoft.AspNetCore.Testing.xunit; 9 | using Microsoft.Extensions.Logging.Abstractions; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption 14 | { 15 | public class CngGcmAuthenticatedEncryptorFactoryTest 16 | { 17 | [Fact] 18 | public void CreateEncrptorInstance_UnknownDescriptorType_ReturnsNull() 19 | { 20 | // Arrange 21 | var key = new Mock(); 22 | key.Setup(k => k.Descriptor).Returns(new Mock().Object); 23 | 24 | var factory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); 25 | 26 | // Act 27 | var encryptor = factory.CreateEncryptorInstance(key.Object); 28 | 29 | // Assert 30 | Assert.Null(encryptor); 31 | } 32 | 33 | [ConditionalFact] 34 | [ConditionalRunTestOnlyOnWindows] 35 | public void CreateEncrptorInstance_ExpectedDescriptorType_ReturnsEncryptor() 36 | { 37 | // Arrange 38 | var descriptor = new CngGcmAuthenticatedEncryptorConfiguration().CreateNewDescriptor(); 39 | var key = new Mock(); 40 | key.Setup(k => k.Descriptor).Returns(descriptor); 41 | 42 | var factory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); 43 | 44 | // Act 45 | var encryptor = factory.CreateEncryptorInstance(key.Object); 46 | 47 | // Assert 48 | Assert.NotNull(encryptor); 49 | Assert.IsType(encryptor); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 8 | { 9 | public class CngCbcAuthenticatedEncryptorConfigurationTests 10 | { 11 | [Fact] 12 | public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey() 13 | { 14 | // Arrange 15 | var configuration = new CngCbcAuthenticatedEncryptorConfiguration(); 16 | 17 | // Act 18 | var masterKey1 = ((CngCbcAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; 19 | var masterKey2 = ((CngCbcAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; 20 | 21 | // Assert 22 | SecretAssert.NotEqual(masterKey1, masterKey2); 23 | SecretAssert.LengthIs(512 /* bits */, masterKey1); 24 | SecretAssert.LengthIs(512 /* bits */, masterKey2); 25 | } 26 | 27 | [Fact] 28 | public void CreateNewDescriptor_PropagatesOptions() 29 | { 30 | // Arrange 31 | var configuration = new CngCbcAuthenticatedEncryptorConfiguration(); 32 | 33 | // Act 34 | var descriptor = (CngCbcAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor(); 35 | 36 | // Assert 37 | Assert.Equal(configuration, descriptor.Configuration); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 8 | { 9 | public class CngGcmAuthenticatedEncryptorConfigurationTests 10 | { 11 | [Fact] 12 | public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey() 13 | { 14 | // Arrange 15 | var configuration = new CngGcmAuthenticatedEncryptorConfiguration(); 16 | 17 | // Act 18 | var masterKey1 = ((CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; 19 | var masterKey2 = ((CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; 20 | 21 | // Assert 22 | SecretAssert.NotEqual(masterKey1, masterKey2); 23 | SecretAssert.LengthIs(512 /* bits */, masterKey1); 24 | SecretAssert.LengthIs(512 /* bits */, masterKey2); 25 | } 26 | 27 | [Fact] 28 | public void CreateNewDescriptor_PropagatesOptions() 29 | { 30 | // Arrange 31 | var configuration = new CngGcmAuthenticatedEncryptorConfiguration(); 32 | 33 | // Act 34 | var descriptor = (CngGcmAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor(); 35 | 36 | // Assert 37 | Assert.Equal(configuration, descriptor.Configuration); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfigurationTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel 8 | { 9 | public class ManagedAuthenticatedEncryptorConfigurationTests 10 | { 11 | [Fact] 12 | public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey() 13 | { 14 | // Arrange 15 | var configuration = new ManagedAuthenticatedEncryptorConfiguration(); 16 | 17 | // Act 18 | var masterKey1 = ((ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; 19 | var masterKey2 = ((ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey; 20 | 21 | // Assert 22 | SecretAssert.NotEqual(masterKey1, masterKey2); 23 | SecretAssert.LengthIs(512 /* bits */, masterKey1); 24 | SecretAssert.LengthIs(512 /* bits */, masterKey2); 25 | } 26 | 27 | [Fact] 28 | public void CreateNewDescriptor_PropagatesOptions() 29 | { 30 | // Arrange 31 | var configuration = new ManagedAuthenticatedEncryptorConfiguration(); 32 | 33 | // Act 34 | var descriptor = (ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor(); 35 | 36 | // Assert 37 | Assert.Equal(configuration, descriptor.Configuration); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/AuthenticatedEncryption/ManagedAuthenticatedEncryptorFactoryTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 5 | using Microsoft.AspNetCore.DataProtection.Cng; 6 | using Microsoft.AspNetCore.DataProtection.KeyManagement; 7 | using Microsoft.AspNetCore.DataProtection.Managed; 8 | using Microsoft.Extensions.Logging.Abstractions; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption 13 | { 14 | public class ManagedAuthenticatedEncryptorFactoryTest 15 | { 16 | [Fact] 17 | public void CreateEncrptorInstance_UnknownDescriptorType_ReturnsNull() 18 | { 19 | // Arrange 20 | var key = new Mock(); 21 | key.Setup(k => k.Descriptor).Returns(new Mock().Object); 22 | 23 | var factory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); 24 | 25 | // Act 26 | var encryptor = factory.CreateEncryptorInstance(key.Object); 27 | 28 | // Assert 29 | Assert.Null(encryptor); 30 | } 31 | 32 | [Fact] 33 | public void CreateEncrptorInstance_ExpectedDescriptorType_ReturnsEncryptor() 34 | { 35 | // Arrange 36 | var descriptor = new ManagedAuthenticatedEncryptorConfiguration().CreateNewDescriptor(); 37 | var key = new Mock(); 38 | key.Setup(k => k.Descriptor).Returns(descriptor); 39 | 40 | var factory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); 41 | 42 | // Act 43 | var encryptor = factory.CreateEncryptorInstance(key.Object); 44 | 45 | // Assert 46 | Assert.NotNull(encryptor); 47 | Assert.IsType(encryptor); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; 6 | using Moq; 7 | using Xunit; 8 | using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; 9 | 10 | namespace Microsoft.AspNetCore.DataProtection.KeyManagement 11 | { 12 | public class KeyTests 13 | { 14 | [Fact] 15 | public void Ctor_Properties() 16 | { 17 | // Arrange 18 | var keyId = Guid.NewGuid(); 19 | var creationDate = DateTimeOffset.Now; 20 | var activationDate = creationDate.AddDays(2); 21 | var expirationDate = creationDate.AddDays(90); 22 | var descriptor = Mock.Of(); 23 | var encryptorFactory = Mock.Of(); 24 | 25 | // Act 26 | var key = new Key(keyId, creationDate, activationDate, expirationDate, descriptor, new[] { encryptorFactory }); 27 | 28 | // Assert 29 | Assert.Equal(keyId, key.KeyId); 30 | Assert.Equal(creationDate, key.CreationDate); 31 | Assert.Equal(activationDate, key.ActivationDate); 32 | Assert.Equal(expirationDate, key.ExpirationDate); 33 | Assert.Same(descriptor, key.Descriptor); 34 | } 35 | 36 | [Fact] 37 | public void SetRevoked_Respected() 38 | { 39 | // Arrange 40 | var now = DateTimeOffset.UtcNow; 41 | var encryptorFactory = Mock.Of(); 42 | var key = new Key(Guid.Empty, now, now, now, new Mock().Object, new[] { encryptorFactory }); 43 | 44 | // Act & assert 45 | Assert.False(key.IsRevoked); 46 | key.SetRevoked(); 47 | Assert.True(key.IsRevoked); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/Microsoft.AspNetCore.DataProtection.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(StandardTestTfms) 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System.Runtime.CompilerServices; 5 | 6 | // for unit testing 7 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 8 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/Repositories/EphemeralXmlRepositoryTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | using Microsoft.Extensions.Logging.Abstractions; 7 | using Xunit; 8 | 9 | namespace Microsoft.AspNetCore.DataProtection.Repositories 10 | { 11 | public class EphemeralXmlRepositoryTests 12 | { 13 | [Fact] 14 | public void GetAllElements_Empty() 15 | { 16 | // Arrange 17 | var repository = new EphemeralXmlRepository(NullLoggerFactory.Instance); 18 | 19 | // Act & assert 20 | Assert.Empty(repository.GetAllElements()); 21 | } 22 | 23 | [Fact] 24 | public void Store_Then_Get() 25 | { 26 | // Arrange 27 | var element1 = XElement.Parse(@""); 28 | var element2 = XElement.Parse(@""); 29 | var element3 = XElement.Parse(@""); 30 | var repository = new EphemeralXmlRepository(NullLoggerFactory.Instance); 31 | 32 | // Act & assert 33 | repository.StoreElement(element1, "Invalid friendly name."); // nobody should care about the friendly name 34 | repository.StoreElement(element2, "abcdefg"); 35 | Assert.Equal(new[] { element1, element2 }, repository.GetAllElements(), XmlAssert.EqualityComparer); 36 | repository.StoreElement(element3, null); 37 | Assert.Equal(new[] { element1, element2, element3 }, repository.GetAllElements(), XmlAssert.EqualityComparer); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/SecretAssert.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Xunit; 6 | 7 | namespace Microsoft.AspNetCore.DataProtection 8 | { 9 | /// 10 | /// Helpful ISecret-based assertions. 11 | /// 12 | public static class SecretAssert 13 | { 14 | /// 15 | /// Asserts that two instances contain the same material. 16 | /// 17 | public static void Equal(ISecret secret1, ISecret secret2) 18 | { 19 | Assert.Equal(SecretToBase64String(secret1), SecretToBase64String(secret2)); 20 | } 21 | 22 | /// 23 | /// Asserts that has the length specified by . 24 | /// 25 | public static void LengthIs(int expectedLengthInBits, ISecret secret) 26 | { 27 | Assert.Equal(expectedLengthInBits, checked(secret.Length * 8)); 28 | } 29 | 30 | /// 31 | /// Asserts that two instances do not contain the same material. 32 | /// 33 | public static void NotEqual(ISecret secret1, ISecret secret2) 34 | { 35 | Assert.NotEqual(SecretToBase64String(secret1), SecretToBase64String(secret2)); 36 | } 37 | 38 | private static string SecretToBase64String(ISecret secret) 39 | { 40 | byte[] secretBytes = new byte[secret.Length]; 41 | secret.WriteSecretIntoBuffer(new ArraySegment(secretBytes)); 42 | return Convert.ToBase64String(secretBytes); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/SequentialGenRandom.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.DataProtection.Cng; 6 | using Microsoft.AspNetCore.DataProtection.Managed; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection 9 | { 10 | internal unsafe class SequentialGenRandom : IBCryptGenRandom, IManagedGenRandom 11 | { 12 | private byte _value; 13 | 14 | public byte[] GenRandom(int numBytes) 15 | { 16 | byte[] bytes = new byte[numBytes]; 17 | for (int i = 0; i < bytes.Length; i++) 18 | { 19 | bytes[i] = _value++; 20 | } 21 | return bytes; 22 | } 23 | 24 | public void GenRandom(byte* pbBuffer, uint cbBuffer) 25 | { 26 | for (uint i = 0; i < cbBuffer; i++) 27 | { 28 | pbBuffer[i] = _value++; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/TestFiles/TestCert1.PublicKeyOnly.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Test/TestFiles/TestCert1.PublicKeyOnly.cer -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/TestFiles/TestCert1.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Test/TestFiles/TestCert1.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/TestFiles/TestCert2.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/DataProtection/88a191f0f348a1eae467a906048e6adcac5f9cc3/test/Microsoft.AspNetCore.DataProtection.Test/TestFiles/TestCert2.pfx -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/XmlEncryption/DpapiNGXmlEncryptionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | using Microsoft.AspNetCore.DataProtection.Test.Shared; 7 | using Microsoft.AspNetCore.Testing.xunit; 8 | using Microsoft.Extensions.Logging.Abstractions; 9 | using Xunit; 10 | 11 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 12 | { 13 | public class DpapiNGXmlEncryptionTests 14 | { 15 | [ConditionalFact] 16 | [ConditionalRunTestOnlyOnWindows8OrLater] 17 | public void Encrypt_Decrypt_RoundTrips() 18 | { 19 | // Arrange 20 | var originalXml = XElement.Parse(@""); 21 | var encryptor = new DpapiNGXmlEncryptor("LOCAL=user", DpapiNGProtectionDescriptorFlags.None, NullLoggerFactory.Instance); 22 | var decryptor = new DpapiNGXmlDecryptor(); 23 | 24 | // Act & assert - run through encryptor and make sure we get back an obfuscated element 25 | var encryptedXmlInfo = encryptor.Encrypt(originalXml); 26 | Assert.Equal(typeof(DpapiNGXmlDecryptor), encryptedXmlInfo.DecryptorType); 27 | Assert.DoesNotContain("265ee4ea-ade2-43b1-b706-09b259e58b6b", encryptedXmlInfo.EncryptedElement.ToString(), StringComparison.OrdinalIgnoreCase); 28 | 29 | // Act & assert - run through decryptor and make sure we get back the original value 30 | var roundTrippedElement = decryptor.Decrypt(encryptedXmlInfo.EncryptedElement); 31 | XmlAssert.Equal(originalXml, roundTrippedElement); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/Microsoft.AspNetCore.DataProtection.Test/XmlEncryption/NullXmlEncryptionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Xml.Linq; 6 | using Xunit; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.XmlEncryption 9 | { 10 | public class NullXmlEncryptionTests 11 | { 12 | [Fact] 13 | public void NullDecryptor_ReturnsOriginalElement() 14 | { 15 | // Arrange 16 | var decryptor = new NullXmlDecryptor(); 17 | 18 | // Act 19 | var retVal = decryptor.Decrypt(XElement.Parse("")); 20 | 21 | // Assert 22 | XmlAssert.Equal("", retVal); 23 | } 24 | 25 | [Fact] 26 | public void NullEncryptor_ReturnsOriginalElement() 27 | { 28 | // Arrange 29 | var encryptor = new NullXmlEncryptor(); 30 | 31 | // Act 32 | var retVal = encryptor.Encrypt(XElement.Parse("")); 33 | 34 | // Assert 35 | Assert.Equal(typeof(NullXmlDecryptor), retVal.DecryptorType); 36 | XmlAssert.Equal("", retVal.EncryptedElement); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/shared/ConditionalRunTestOnlyWindows8OrLaterAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Cryptography.Cng; 6 | using Microsoft.AspNetCore.Testing.xunit; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.Test.Shared 9 | { 10 | public class ConditionalRunTestOnlyOnWindows8OrLaterAttribute : Attribute, ITestCondition 11 | { 12 | public bool IsMet => OSVersionUtil.IsWindows8OrLater(); 13 | 14 | public string SkipReason { get; } = "Test requires Windows 8 / Windows Server 2012 or higher."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/shared/ConditionalRunTestOnlyWindowsAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using Microsoft.AspNetCore.Cryptography.Cng; 6 | using Microsoft.AspNetCore.Testing.xunit; 7 | 8 | namespace Microsoft.AspNetCore.DataProtection.Test.Shared 9 | { 10 | public class ConditionalRunTestOnlyOnWindowsAttribute : Attribute, ITestCondition 11 | { 12 | public bool IsMet => OSVersionUtil.IsWindows(); 13 | 14 | public string SkipReason { get; } = "Test requires Windows 7 / Windows Server 2008 R2 or higher."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/shared/ExceptionAssert2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | using Xunit; 7 | 8 | namespace Microsoft.AspNetCore.Testing 9 | { 10 | internal static class ExceptionAssert2 11 | { 12 | /// 13 | /// Verifies that the code throws a . 14 | /// 15 | /// A delegate to the code to be tested 16 | /// The that was thrown, when successful 17 | /// Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown 18 | public static CryptographicException ThrowsCryptographicException(Action testCode) 19 | { 20 | return Assert.Throws(testCode); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /version.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 3.0.0 4 | alpha1 5 | $(VersionPrefix) 6 | $(VersionPrefix)-$(VersionSuffix)-final 7 | t000 8 | a- 9 | $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) 10 | $(VersionSuffix)-$(BuildNumber) 11 | 12 | 13 | --------------------------------------------------------------------------------