Beispiel #1
0
        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));
        }
Beispiel #2
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #11
0
        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;
		}
Beispiel #16
0
        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);
        }
Beispiel #18
0
        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;
		}
Beispiel #21
0
        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);
        }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        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 );
		}
Beispiel #25
0
        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));
        }
Beispiel #30
0
        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);
        }
Beispiel #31
0
        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;
		}
Beispiel #37
0
 private bool NeedFreshPrivateKey(D2LSecurityToken key)
 {
     return(key == null || m_dateTimeProvider.UtcNow >= key.ValidTo - m_keyRotationPeriod);
 }