127 lines
5.3 KiB
C#
127 lines
5.3 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
|
|
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
|
|
using Moq;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.DataProtection.KeyManagement
|
|
{
|
|
public class KeyRingTests
|
|
{
|
|
[Fact]
|
|
public void DefaultAuthenticatedEncryptor_Prop_InstantiationIsDeferred()
|
|
{
|
|
// Arrange
|
|
var expectedEncryptorInstance = new Mock<IAuthenticatedEncryptor>().Object;
|
|
|
|
var key1 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance);
|
|
var key2 = new MyKey();
|
|
|
|
// Act
|
|
var keyRing = new KeyRing(key1, new[] { key1, key2 });
|
|
|
|
// Assert
|
|
Assert.Equal(0, key1.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
|
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance, keyRing.DefaultAuthenticatedEncryptor);
|
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled); // should've been cached
|
|
}
|
|
|
|
[Fact]
|
|
public void DefaultKeyId_Prop()
|
|
{
|
|
// Arrange
|
|
var key1 = new MyKey();
|
|
var key2 = new MyKey();
|
|
|
|
// Act
|
|
var keyRing = new KeyRing(key2, new[] { key1, key2 });
|
|
|
|
// Assert
|
|
Assert.Equal(key2.KeyId, keyRing.DefaultKeyId);
|
|
}
|
|
|
|
[Fact]
|
|
public void DefaultKeyIdAndEncryptor_IfDefaultKeyNotPresentInAllKeys()
|
|
{
|
|
// Arrange
|
|
var key1 = new MyKey();
|
|
var key2 = new MyKey();
|
|
var key3 = new MyKey(expectedEncryptorInstance: new Mock<IAuthenticatedEncryptor>().Object);
|
|
|
|
// Act
|
|
var keyRing = new KeyRing(key3, new[] { key1, key2 });
|
|
|
|
// Assert
|
|
Assert.Equal(key3.KeyId, keyRing.DefaultKeyId);
|
|
Assert.Equal(key3.CreateEncryptor(), keyRing.GetAuthenticatedEncryptorByKeyId(key3.KeyId, out var _));
|
|
}
|
|
|
|
[Fact]
|
|
public void GetAuthenticatedEncryptorByKeyId_DefersInstantiation_AndReturnsRevocationInfo()
|
|
{
|
|
// Arrange
|
|
var expectedEncryptorInstance1 = new Mock<IAuthenticatedEncryptor>().Object;
|
|
var expectedEncryptorInstance2 = new Mock<IAuthenticatedEncryptor>().Object;
|
|
|
|
var key1 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance1, isRevoked: true);
|
|
var key2 = new MyKey(expectedEncryptorInstance: expectedEncryptorInstance2);
|
|
|
|
|
|
// Act
|
|
var keyRing = new KeyRing(key2, new[] { key1, key2 });
|
|
|
|
// Assert
|
|
Assert.Equal(0, key1.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out var isRevoked));
|
|
Assert.True(isRevoked);
|
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance1, keyRing.GetAuthenticatedEncryptorByKeyId(key1.KeyId, out isRevoked));
|
|
Assert.True(isRevoked);
|
|
Assert.Equal(1, key1.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Equal(0, key2.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
|
|
Assert.False(isRevoked);
|
|
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance2, keyRing.GetAuthenticatedEncryptorByKeyId(key2.KeyId, out isRevoked));
|
|
Assert.False(isRevoked);
|
|
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
|
|
Assert.Same(expectedEncryptorInstance2, keyRing.DefaultAuthenticatedEncryptor);
|
|
Assert.Equal(1, key2.NumTimesCreateEncryptorInstanceCalled);
|
|
}
|
|
|
|
private sealed class MyKey : IKey
|
|
{
|
|
public int NumTimesCreateEncryptorInstanceCalled;
|
|
private readonly Func<IAuthenticatedEncryptor> _encryptorFactory;
|
|
|
|
public MyKey(bool isRevoked = false, IAuthenticatedEncryptor expectedEncryptorInstance = null)
|
|
{
|
|
CreationDate = DateTimeOffset.Now;
|
|
ActivationDate = CreationDate + TimeSpan.FromHours(1);
|
|
ExpirationDate = CreationDate + TimeSpan.FromDays(30);
|
|
IsRevoked = isRevoked;
|
|
KeyId = Guid.NewGuid();
|
|
_encryptorFactory = () => expectedEncryptorInstance ?? new Mock<IAuthenticatedEncryptor>().Object;
|
|
}
|
|
|
|
public DateTimeOffset ActivationDate { get; }
|
|
public DateTimeOffset CreationDate { get; }
|
|
public DateTimeOffset ExpirationDate { get; }
|
|
public bool IsRevoked { get; }
|
|
public Guid KeyId { get; }
|
|
public IAuthenticatedEncryptorDescriptor Descriptor => throw new NotImplementedException();
|
|
|
|
public IAuthenticatedEncryptor CreateEncryptor()
|
|
{
|
|
NumTimesCreateEncryptorInstanceCalled++;
|
|
return _encryptorFactory();
|
|
}
|
|
}
|
|
}
|
|
}
|