Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { var creationParams = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, KeyUsage = CngKeyUsages.Signing }; byte[] privateBlob; using (var cngKey = CngKey.Create(m_algorithm, null, creationParams)) { using (ECDsaCng ecDsa = new ECDsaCng(cngKey)) { privateBlob = ecDsa.Key.Export(CngKeyBlobFormat.EccPrivateBlob); } } D2LSecurityToken result = m_d2lSecurityTokenFactory.Create(() => { using (var cng = CngKey.Import(privateBlob, CngKeyBlobFormat.EccPrivateBlob)) { // ECDsaCng copies the CngKey, hence the using var ecDsa = new ECDsaCng(cng); var key = new EcDsaSecurityKey(ecDsa); return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, ecDsa)); } }); return(Task.FromResult(result)); }
async Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { // Hold a local reference so that we know we are talking about the same key // after even if another thread changed m_privateKey (race condition when we // are using a key very close to the rotation time.) D2LSecurityToken privateKey = m_privateKey; if (NeedFreshPrivateKey(privateKey)) { // This Semaphore is used instead of lock(foo){} // because await cannot be used within a lock await m_privateKeyLock.WaitAsync().SafeAsync(); try { privateKey = m_privateKey; if (NeedFreshPrivateKey(privateKey)) { m_privateKey = (await m_inner.GetSigningCredentialsAsync().SafeAsync()).Ref(); if (privateKey != null) { privateKey.Dispose(); } privateKey = m_privateKey; } } finally { m_privateKeyLock.Release(); } } return(privateKey.Ref()); }
async Task<D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { // Hold a local reference so that we know we are talking about the same key // after even if another thread changed m_privateKey (race condition when we // are using a key very close to the rotation time.) D2LSecurityToken privateKey = m_privateKey; if( NeedFreshPrivateKey( privateKey ) ) { // This Semaphore is used instead of lock(foo){} // because await cannot be used within a lock await m_privateKeyLock.WaitAsync().SafeAsync(); try { privateKey = m_privateKey; if( NeedFreshPrivateKey( privateKey ) ) { m_privateKey = (await m_inner.GetSigningCredentialsAsync().SafeAsync()).Ref(); if( privateKey != null ) { privateKey.Dispose(); } privateKey = m_privateKey; } } finally { m_privateKeyLock.Release(); } } return privateKey.Ref(); }
async Task <string> ITokenSigner.SignAsync(UnsignedToken token) { JwtSecurityToken jwt; using (D2LSecurityToken securityToken = await m_privateKeyProvider .GetSigningCredentialsAsync() .SafeAsync() ) { jwt = new JwtSecurityToken( issuer: token.Issuer, audience: token.Audience, claims: Enumerable.Empty <Claim>(), notBefore: token.NotBefore, expires: token.ExpiresAt, signingCredentials: securityToken.GetSigningCredentials() ); var claims = token.Claims; foreach (var claim in claims) { if (jwt.Payload.ContainsKey(claim.Key)) { throw new ValidationException($"'{claim.Key}' is already part of the payload"); } jwt.Payload.Add(claim.Key, claim.Value); } var jwtHandler = new JwtSecurityTokenHandler(); string signedRawToken = jwtHandler.WriteToken(jwt); return(signedRawToken); } }
private static void AssertSignatureVerifiable( D2LSecurityToken securityToken, string signedToken ) { JwtSecurityTokenHandler validationTokenHandler = new JwtSecurityTokenHandler(); TokenValidationParameters validationParameters = new TokenValidationParameters() { ValidateAudience = false, ValidateIssuer = false, ValidateLifetime = false, RequireSignedTokens = true, IssuerSigningKey = securityToken }; validationTokenHandler.ValidateToken( signedToken, validationParameters, out SecurityToken validatedToken ); JwtSecurityToken validatedJwt = validatedToken as JwtSecurityToken; Assert.AreEqual(TEST_ISSUER, validatedJwt.Issuer); }
public async Task GetSigningCredentialsAsync_FirstCall_CreatesAndReturnsKey() { D2LSecurityToken key = await m_privateKeyProvider.GetSigningCredentialsAsync().ConfigureAwait(false); m_mockPublicKeyDataProvider.Verify(pkdp => pkdp.SaveAsync(It.IsAny <Guid>(), It.IsAny <JsonWebKey>()), Times.Once()); Assert.NotNull(key); }
async public void ItShouldRetrieveJwksAndCacheKeysWhenKeyIsNotInCache() { var seq = new MockSequence(); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, KEY_ID)) .Returns <D2LSecurityToken>(null); var otherKeyId = Guid.NewGuid(); var jwks = new JsonWebKeySet( new JavaScriptSerializer().Serialize( new { keys = new object[] { D2LSecurityTokenUtility .CreateActiveToken(KEY_ID) .ToJsonWebKey() .ToJwkDto(), D2LSecurityTokenUtility .CreateActiveToken(otherKeyId) .ToJsonWebKey() .ToJwkDto() } } ), new Uri("http://localhost/dummy") ); m_jwksProvider .InSequence(seq) .Setup(x => x.RequestJwksAsync()) .ReturnsAsync(jwks); m_keyCache .Setup(x => x.Set(SRC_NAMESPACE, It.Is <D2LSecurityToken>(k => k.KeyId == KEY_ID))); m_keyCache .Setup(x => x.Set(SRC_NAMESPACE, It.Is <D2LSecurityToken>(k => k.KeyId == otherKeyId))); var cachedKey = new D2LSecurityToken( KEY_ID, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1), () => null as Tuple <AsymmetricSecurityKey, IDisposable> ); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, KEY_ID)) .Returns(cachedKey); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync(KEY_ID) .SafeAsync(); m_keyCache.VerifyAll(); Assert.AreEqual(cachedKey, result); }
public async Task ItShouldRetrieveJwksAndIgnoreInvalidKeysWithoutErroring(string keyId) { var seq = new MockSequence(); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, keyId)) .Returns <D2LSecurityToken>(null); var otherKeyId = Guid.NewGuid().ToString(); var jwks = new JsonWebKeySet( JsonSerializer.Serialize( new { keys = new[] { D2LSecurityTokenUtility .CreateActiveToken(keyId) .ToJsonWebKey() .ToJwkDto(), D2LSecurityTokenUtility .CreateTokenWithTimeRemaining(TimeSpan.FromSeconds(-1), otherKeyId) .ToJsonWebKey() .ToJwkDto() } } ), new Uri("http://localhost/dummy") ); m_jwksProvider .InSequence(seq) .Setup(x => x.RequestJwkAsync(keyId)) .ReturnsAsync(jwks); m_keyCache .Setup(x => x.Set(SRC_NAMESPACE, It.Is <D2LSecurityToken>(k => k.KeyId == keyId))); var cachedKey = new D2LSecurityToken( keyId, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1), () => null as Tuple <AsymmetricSecurityKey, IDisposable> ); m_keyCache .InSequence(seq) .Setup(x => x.Get(SRC_NAMESPACE, keyId)) .Returns(cachedKey); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync(keyId) .ConfigureAwait(false); m_keyCache.VerifyAll(); m_keyCache.Verify(x => x.Set(SRC_NAMESPACE, It.IsAny <D2LSecurityToken>()), Times.Once); Assert.AreEqual(cachedKey, result); }
void IInMemoryPublicKeyCache.Set( D2LSecurityToken key ) { m_cache.Set( BuildCacheKey( key.KeyId ), key, new CacheItemPolicy() { AbsoluteExpiration = key.ValidTo } ); }
async Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { D2LSecurityToken result = await m_inner.GetSigningCredentialsAsync().SafeAsync(); JsonWebKey jwk = result.ToJsonWebKey(); await m_publicKeyDataProvider.SaveAsync(jwk).SafeAsync(); return(result); }
async Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { D2LSecurityToken result = await m_inner.GetSigningCredentialsAsync().ConfigureAwait(false); JsonWebKey jwk = result.ToJsonWebKey(); await m_publicKeyDataProvider.SaveAsync(new Guid( jwk.Id ), jwk).ConfigureAwait(false); return(result); }
private static string Sign( D2LSecurityToken securityToken ) { JwtSecurityToken jwt = new JwtSecurityToken( issuer: TEST_ISSUER, signingCredentials: securityToken.GetSigningCredentials() ); JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler(); string signedToken = jwtHandler.WriteToken( jwt ); return signedToken; }
private static string Sign(D2LSecurityToken securityToken) { JwtSecurityToken jwt = new JwtSecurityToken( issuer: TEST_ISSUER, signingCredentials: securityToken.GetSigningCredentials() ); JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler(); string signedToken = jwtHandler.WriteToken(jwt); return(signedToken); }
Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { var ecdsa = ECDsa.Create(m_curve); var parameters = ecdsa.ExportParameters(includePrivateParameters: true); D2LSecurityToken result = m_d2lSecurityTokenFactory.Create(() => { var ecDsa = ECDsa.Create(parameters); var key = new ECDsaSecurityKey(ecDsa); return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, ecDsa)); }); return(Task.FromResult(result)); }
internal static Mock<IPublicKeyProvider> Create( Uri jwksEndpoint, Guid keyId, D2LSecurityToken token ) { var mock = new Mock<IPublicKeyProvider>(); mock.Setup( p => p.GetByIdAsync( keyId )).Returns( Task.FromResult( token ) ); return mock; }
public async Task GetSigningCredentialsAsync_SecondCallShortlyAfter_ReturnsSameKey(long offsetSeconds) { DateTimeOffset now = DateTimeOffset.UtcNow; m_mockDateTimeProvider.Setup(dtp => dtp.UtcNow).Returns(now); D2LSecurityToken key1 = await m_privateKeyProvider.GetSigningCredentialsAsync().ConfigureAwait(false); m_mockDateTimeProvider.Setup(dtp => dtp.UtcNow).Returns(now + TimeSpan.FromSeconds(offsetSeconds)); D2LSecurityToken key2 = await m_privateKeyProvider.GetSigningCredentialsAsync().ConfigureAwait(false); m_mockPublicKeyDataProvider.Verify(pkdp => pkdp.SaveAsync(It.IsAny <Guid>(), It.IsAny <JsonWebKey>()), Times.Once()); Assert.AreEqual(key1.KeyId, key2.KeyId); }
internal override D2LSecurityToken ToSecurityToken() { var token = new D2LSecurityToken( id: Id, validFrom: DateTimeOffset.UtcNow, validTo: ExpiresAt ?? DateTimeOffset.UtcNow + Constants.REMOTE_KEY_MAX_LIFETIME, keyFactory: () => { var ecdsa = ECDsa.Create(m_parameters); var key = new ECDsaSecurityKey(ecdsa); return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, ecdsa)); } ); return(token); }
internal override D2LSecurityToken ToSecurityToken() { var token = new D2LSecurityToken( id: Id, validFrom: DateTime.UtcNow, validTo: ExpiresAt ?? DateTime.UtcNow + Constants.REMOTE_KEY_MAX_LIFETIME, keyFactory: () => { var cng = BuildEcDsaCng(); var key = new EcDsaSecurityKey(cng); return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, cng)); } ); return(token); }
internal override D2LSecurityToken ToSecurityToken() { var token = new D2LSecurityToken( id: Id, validFrom: DateTime.UtcNow, validTo: ExpiresAt ?? DateTime.UtcNow + Constants.REMOTE_KEY_MAX_LIFETIME, keyFactory: () => { var rsa = new RSACryptoServiceProvider() { PersistKeyInCsp = false }; rsa.ImportParameters( m_parameters ); var key = new RsaSecurityKey( rsa ); return new Tuple<AsymmetricSecurityKey, IDisposable>( key, rsa ); } ); return token; }
D2LSecurityToken ID2LSecurityTokenFactory.Create( Func<Tuple<AsymmetricSecurityKey, IDisposable>> keyFactory ) { Guid id = Guid.NewGuid(); DateTime validFrom = m_dateTimeProvider.UtcNow; DateTime validTo = validFrom + m_keyLifetime; var result = new D2LSecurityToken( id: id, validFrom: validFrom, validTo: validTo, keyFactory: keyFactory ); return result; }
D2LSecurityToken ID2LSecurityTokenFactory.Create( Func <Tuple <AsymmetricSecurityKey, IDisposable> > keyFactory ) { Guid id = Guid.NewGuid(); DateTime validFrom = m_dateTimeProvider.UtcNow; DateTime validTo = validFrom + m_keyLifetime; var result = new D2LSecurityToken( id: id, validFrom: validFrom, validTo: validTo, keyFactory: keyFactory ); return(result); }
public async Task GetSigningCredentialsAsync_KeyDuringOrAfterRotationPeriod_ReturnsNewKey(long offsetSeconds) { DateTimeOffset now = DateTimeOffset.UtcNow; m_mockDateTimeProvider.Setup(dtp => dtp.UtcNow).Returns(now); D2LSecurityToken key1 = await m_privateKeyProvider.GetSigningCredentialsAsync().ConfigureAwait(false); m_mockDateTimeProvider .Setup(dtp => dtp.UtcNow) .Returns(now + KEY_LIFETIME - ROTATION_PERIOD + TimeSpan.FromSeconds(offsetSeconds)); D2LSecurityToken key2 = await m_privateKeyProvider.GetSigningCredentialsAsync().ConfigureAwait(false); m_mockPublicKeyDataProvider.Verify(pkdp => pkdp.SaveAsync(It.IsAny <Guid>(), It.IsAny <JsonWebKey>()), Times.Exactly(2)); Assert.AreNotEqual(key1.KeyId, key2.KeyId); }
internal override D2LSecurityToken ToSecurityToken() { var token = new D2LSecurityToken( id: Id, validFrom: DateTime.UtcNow, validTo: ExpiresAt ?? DateTime.UtcNow + Constants.REMOTE_KEY_MAX_LIFETIME, keyFactory: () => { var rsa = new RSACryptoServiceProvider() { PersistKeyInCsp = false }; rsa.ImportParameters(m_parameters); var key = new RsaSecurityKey(rsa); return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, rsa)); } ); return(token); }
async public void ItShouldReturnFromCacheWhenKeyIsInCache() { var cachedKey = new D2LSecurityToken( KEY_ID, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours( 1 ), () => null as Tuple<AsymmetricSecurityKey, IDisposable> ); m_keyCache .Setup( x => x.Get( KEY_ID ) ) .Returns( cachedKey ); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync( KEY_ID ) .SafeAsync(); m_keyCache .Verify( x => x.Get( KEY_ID ) ); Assert.AreEqual( cachedKey, result ); }
async public void ItShouldReturnFromCacheWhenKeyIsInCache() { var cachedKey = new D2LSecurityToken( KEY_ID, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1), () => null as Tuple <AsymmetricSecurityKey, IDisposable> ); m_keyCache .Setup(x => x.Get(SRC_NAMESPACE, KEY_ID)) .Returns(cachedKey); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync(KEY_ID) .SafeAsync(); m_keyCache .Verify(x => x.Get(SRC_NAMESPACE, KEY_ID)); Assert.AreEqual(cachedKey, result); }
async Task <D2LSecurityToken> IPublicKeyProvider.GetByIdAsync(Guid id) { D2LSecurityToken result = m_cache.Get(PUBLIC_KEY_SOURCE, id); if (result != null) { return(result); } JsonWebKey jwk = await m_publicKeyDataProvider .GetByIdAsync(id) .SafeAsync(); if (jwk != null) { result = jwk.ToSecurityToken(); m_cache.Set(PUBLIC_KEY_SOURCE, result); return(result); } throw new PublicKeyNotFoundException(id, PUBLIC_KEY_SOURCE); }
public async Task ItShouldReturnFromCacheWhenKeyIsInCache(string keyId) { var cachedKey = new D2LSecurityToken( keyId, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1), () => null as Tuple <AsymmetricSecurityKey, IDisposable> ); m_keyCache .Setup(x => x.Get(SRC_NAMESPACE, keyId)) .Returns(cachedKey); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync(keyId) .ConfigureAwait(false); m_keyCache .Verify(x => x.Get(SRC_NAMESPACE, keyId)); Assert.AreEqual(cachedKey, result); }
private static void Runner( IPrivateKeyProvider provider, ManualResetEventSlim go, int threadNumber ) { // wait for start signal go.Wait(); for (int i = 0; i < SIGNATURES_PER_THREAD; i++) { using (D2LSecurityToken securityToken = provider.GetSigningCredentialsAsync() .ConfigureAwait(false) .GetAwaiter() .GetResult() ) { string signedToken = Sign(securityToken); Thread.Sleep(TimeSpan.FromMilliseconds(20)); AssertSignatureVerifiable(securityToken, signedToken); } } }
Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { RSAParameters privateKey; using (var csp = new RSACryptoServiceProvider(Constants.GENERATED_RSA_KEY_SIZE) { PersistKeyInCsp = false }) { privateKey = csp.ExportParameters(includePrivateParameters: true); } D2LSecurityToken result = m_d2lSecurityTokenFactory.Create(() => { var csp = new RSACryptoServiceProvider() { PersistKeyInCsp = false }; csp.ImportParameters(privateKey); var key = new RsaSecurityKey(csp); return(new Tuple <AsymmetricSecurityKey, IDisposable>(key, csp)); }); return(Task.FromResult(result)); }
async Task <D2LSecurityToken> IPublicKeyProvider.GetByIdAsync(string id) { D2LSecurityToken result = m_cache.Get(m_jwksProvider.Namespace, id); if (result != null) { return(result); } JsonWebKeySet jwks = await m_jwksProvider .RequestJwkAsync(id) .ConfigureAwait(false); CacheJwks(m_cache, m_jwksProvider.Namespace, jwks); result = m_cache.Get(m_jwksProvider.Namespace, id); if (result != null) { return(result); } throw new PublicKeyNotFoundException(id, jwks.Source.AbsoluteUri); }
async Task <string> ITokenSigner.SignAsync(UnsignedToken token) { JwtSecurityToken jwt; using (D2LSecurityToken securityToken = await m_privateKeyProvider .GetSigningCredentialsAsync() .SafeAsync() ) { jwt = new JwtSecurityToken( issuer: token.Issuer, audience: token.Audience, claims: token.Claims, notBefore: token.NotBefore, expires: token.ExpiresAt, signingCredentials: securityToken.GetSigningCredentials() ); var jwtHandler = new JwtSecurityTokenHandler(); string signedRawToken = jwtHandler.WriteToken(jwt); return(signedRawToken); } }
private static void AssertSignatureVerifiable( D2LSecurityToken securityToken, string signedToken ) { JwtSecurityTokenHandler validationTokenHandler = new JwtSecurityTokenHandler(); TokenValidationParameters validationParameters = new TokenValidationParameters() { ValidateAudience = false, ValidateIssuer = false, ValidateLifetime = false, RequireSignedTokens = true, IssuerSigningToken = securityToken }; SecurityToken validatedToken; validationTokenHandler.ValidateToken( signedToken, validationParameters, out validatedToken ); JwtSecurityToken validatedJwt = validatedToken as JwtSecurityToken; Assert.AreEqual( TEST_ISSUER, validatedJwt.Issuer ); }
async public void ItShouldRetrieveJwksAndIgnoreInvalidKeysWithoutErroring() { var seq = new MockSequence(); m_keyCache .InSequence( seq ) .Setup( x => x.Get( SRC_NAMESPACE, KEY_ID ) ) .Returns<D2LSecurityToken>( null ); var otherKeyId = Guid.NewGuid(); var jwks = new JsonWebKeySet( new JavaScriptSerializer().Serialize( new { keys = new[] { D2LSecurityTokenUtility .CreateActiveToken( KEY_ID ) .ToJsonWebKey() .ToJwkDto(), D2LSecurityTokenUtility .CreateTokenWithTimeRemaining( TimeSpan.FromSeconds( -1 ), otherKeyId ) .ToJsonWebKey() .ToJwkDto() } } ), new Uri( "http://localhost/dummy" ) ); m_jwksProvider .InSequence( seq ) .Setup( x => x.RequestJwksAsync() ) .ReturnsAsync( jwks ); m_keyCache .Setup( x => x.Set( SRC_NAMESPACE, It.Is<D2LSecurityToken>( k => k.KeyId == KEY_ID ) ) ); var cachedKey = new D2LSecurityToken( KEY_ID, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours( 1 ), () => null as Tuple<AsymmetricSecurityKey, IDisposable> ); m_keyCache .InSequence( seq ) .Setup( x => x.Get( SRC_NAMESPACE, KEY_ID ) ) .Returns( cachedKey ); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync( KEY_ID ) .SafeAsync(); m_keyCache.VerifyAll(); m_keyCache.Verify( x => x.Set( SRC_NAMESPACE, It.IsAny<D2LSecurityToken>() ), Times.Once ); Assert.AreEqual( cachedKey, result ); }
async public void ItShouldRetrieveJwksAndCacheKeysWhenKeyIsNotInCache() { var seq = new MockSequence(); m_keyCache .InSequence( seq ) .Setup( x => x.Get( KEY_ID ) ) .Returns<D2LSecurityToken>( null ); var otherKeyId = Guid.NewGuid(); var jwks = new JsonWebKeySet( new JavaScriptSerializer().Serialize( new { keys = new object[] { D2LSecurityTokenUtility .CreateActiveToken( KEY_ID ) .ToJsonWebKey() .ToJwkDto(), D2LSecurityTokenUtility .CreateActiveToken( otherKeyId ) .ToJsonWebKey() .ToJwkDto() } } ) ); m_jwksProvider .InSequence( seq ) .Setup( x => x.RequestJwksAsync() ) .ReturnsAsync( jwks ); m_keyCache .Setup( x => x.Set( It.Is<D2LSecurityToken>( k => k.KeyId == KEY_ID ) ) ); m_keyCache .Setup( x => x.Set( It.Is<D2LSecurityToken>( k => k.KeyId == otherKeyId ) ) ); var cachedKey = new D2LSecurityToken( KEY_ID, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours( 1 ), () => null as Tuple<AsymmetricSecurityKey, IDisposable> ); m_keyCache .InSequence( seq ) .Setup( x => x.Get( KEY_ID ) ) .Returns( cachedKey ); D2LSecurityToken result = await m_publicKeyProvider .GetByIdAsync( KEY_ID ) .SafeAsync(); m_keyCache.VerifyAll(); Assert.AreEqual( cachedKey, result ); }
internal override D2LSecurityToken ToSecurityToken() { var token = new D2LSecurityToken( id: Id, validFrom: DateTime.UtcNow, validTo: ExpiresAt ?? DateTime.UtcNow + Constants.REMOTE_KEY_MAX_LIFETIME, keyFactory: () => { var cng = BuildEcDsaCng(); var key = new EcDsaSecurityKey( cng ); return new Tuple<AsymmetricSecurityKey, IDisposable>( key, cng ); } ); return token; }
private bool NeedFreshPrivateKey( D2LSecurityToken key ) { return key == null || m_dateTimeProvider.UtcNow >= key.ValidTo - m_keyRotationPeriod; }
private bool NeedFreshPrivateKey(D2LSecurityToken key) { return(key == null || m_dateTimeProvider.UtcNow >= key.ValidTo - m_keyRotationPeriod); }