public KeyBase?Find(KeyRequirement req, DateTime bestBefore) { foreach (var k in this) { if (req.Match(k) && k.BestBefore < bestBefore) { return(k); } } return(null); }
public DiffieHellmanAlgorithm(int generatedKeySize) { _hash = generatedKeySize switch { 128 => HashAlgorithmName.MD5, 160 => HashAlgorithmName.SHA1, 256 => HashAlgorithmName.SHA256, 384 => HashAlgorithmName.SHA384, 512 => HashAlgorithmName.SHA512, _ => throw new ArgumentException($"Must be 128 (MD5), 160 (SHA1), 256 (SHA256), 384 (SHA384) or 512 (SHA512). Got {generatedKeySize}.", nameof(generatedKeySize)) }; GeneratedKeySize = generatedKeySize; _keyRequirement = new KeyRequirement(KeyOperations.DeriveKey, ECCurve.NamedCurves.nistP256.Oid, "DiffieHellman"); }
public HmacUsingSha(SignatureAlgorithmId id) { switch (id) { case SignatureAlgorithmId.HS256: _keySize = 32; break; case SignatureAlgorithmId.HS384: _keySize = 48; break; case SignatureAlgorithmId.HS512: _keySize = 64; break; default: throw new ArgumentException($"Invalid identifier: {id}."); } _id = id; _keyRequirement = new KeyRequirement(KeyType.Oct, KeyOperations.SignAndVerify, _keySize * 8, id.GetKeyName().ToString()); }
/// <summary> /// Creates a key based on the configuration and the provided properties. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="kid">The <see cref="KeyBase.Kid"/>.</param> /// <param name="party">The target audience. Creation behavior may differ per party or it's key realm.</param> /// <param name="keyRequirement">The key requirement.</param> /// <param name="bestBefore">The <see cref="KeyBase.BestBefore"/>.</param> /// <param name="maxUseCount">The <see cref="KeyBase.MaxUseCount"/>. When 0, <see cref="KeyConfiguration.DefaultUseCount"/> is used.</param> /// <returns>The new key.</returns> public KeyBase CreateKey(IActivityMonitor monitor, string kid, ITrustedParty party, KeyRequirement keyRequirement, DateTime bestBefore, uint maxUseCount) { KeyBase?result = TryCreateKey(monitor, kid, party, keyRequirement, bestBefore, maxUseCount); if (result == null) { throw new CKException($"Unable to create key for '{keyRequirement}'."); } monitor.Info($"Key created: {result.GetType().Name} '{result.Kid}', best before '{result.BestBefore:O}'."); return(result); }
KeyBase?TryCreateKey(IActivityMonitor monitor, string kid, ITrustedParty party, KeyRequirement keyRequirement, DateTime bestBefore, uint maxUseCount) { if (bestBefore.Kind != DateTimeKind.Utc) { throw new ArgumentException("Must be UTC kind.", nameof(bestBefore)); } var now = Clock.UtcNow; var delta = bestBefore - now; if (delta <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException($"Best before is {bestBefore:O} in the past (now is {now:O}).", nameof(bestBefore)); } KeyBase?result; if (keyRequirement.KeyType == KeyType.Ec) { KeyConfig.ECKeys.Apply(now, delta, ref bestBefore, ref maxUseCount); result = ECKey.Create(monitor, Clock, kid, keyRequirement, bestBefore, maxUseCount); } else if (keyRequirement.KeyType == KeyType.Rsa) { Debug.Assert(keyRequirement.KeySizeInBits != null); KeyConfig.RSAKeys.Apply(now, delta, ref bestBefore, ref maxUseCount); result = RSAKey.Create(monitor, Clock, kid, keyRequirement.Operations, keyRequirement.KeySizeInBits.Value, bestBefore, maxUseCount); } else { Debug.Assert(keyRequirement.KeySizeInBits != null); KeyConfig.SecretKeys.Apply(now, delta, ref bestBefore, ref maxUseCount); result = new SymmetricKey(Clock, kid, keyRequirement.Operations, keyRequirement.KeySizeInBits.Value, bestBefore, maxUseCount); } return(result); }
public RsaUsingSha(SignatureAlgorithmId id, int rsaKeySize) { switch (id) { case SignatureAlgorithmId.RS256: _hash = HashAlgorithmName.SHA256; _padding = RSASignaturePadding.Pkcs1; break; case SignatureAlgorithmId.RS384: _hash = HashAlgorithmName.SHA384; _padding = RSASignaturePadding.Pkcs1; break; case SignatureAlgorithmId.RS512: _hash = HashAlgorithmName.SHA512; _padding = RSASignaturePadding.Pkcs1; break; case SignatureAlgorithmId.PS256: _hash = HashAlgorithmName.SHA256; _padding = RSASignaturePadding.Pss; break; case SignatureAlgorithmId.PS384: _hash = HashAlgorithmName.SHA384; _padding = RSASignaturePadding.Pss; break; case SignatureAlgorithmId.PS512: _hash = HashAlgorithmName.SHA512; _padding = RSASignaturePadding.Pss; break; default: throw new ArgumentException($"Invalid identifier: {id}."); } _id = id; _keyRequirement = new KeyRequirement(KeyType.Rsa, KeyOperations.SignAndVerify, rsaKeySize, id.GetKeyName().ToString()); }
async ValueTask <KeyBase> ResolveOutgoingKeyAsync(IActivityMonitor monitor, TrustedParty p, KeyRequirement keyRequirement, DateTime bestBefore, uint maxUseCount) { Debug.Assert(monitor != null && p != null && keyRequirement != null); if (keyRequirement.KeyType != KeyType.Oct) { Throw.NotSupportedException("Only symmetric keys are currently supported."); } Debug.Assert(keyRequirement.KeyType == KeyType.Oct && keyRequirement.KeySizeInBits != null); var remote = p as RemoteParty; var key = await p.SymmetricKeys.FindOrCreateKeyAsync(monitor, keyRequirement, bestBefore, maxUseCount, remote == null); if (key != null) { return(key); } Debug.Assert(remote != null, "If remote was null, a local symmetric key has been created."); return(CreateSymmetricKeyFromExchangeAsync(monitor, remote, keyRequirement.Operations, keyRequirement.KeySizeInBits.Value, bestBefore, maxUseCount, null)); }
public EcdsaUsingSha(SignatureAlgorithmId id) { ECCurve curveName; switch (id) { case SignatureAlgorithmId.ES256: curveName = ECCurve.NamedCurves.nistP256; _hash = HashAlgorithmName.SHA256; _signatureSize = 64; break; case SignatureAlgorithmId.ES256K: // See http://oid-info.com/get/1.3.132.0.10 (secp256k1 curve). curveName = ECCurve.CreateFromValue("1.3.132.0.10"); _hash = HashAlgorithmName.SHA256; _signatureSize = 64; break; case SignatureAlgorithmId.ES384: curveName = ECCurve.NamedCurves.nistP384; _hash = HashAlgorithmName.SHA384; _signatureSize = 96; break; case SignatureAlgorithmId.ES512: curveName = ECCurve.NamedCurves.nistP521; _hash = HashAlgorithmName.SHA512; _signatureSize = 132; break; default: throw new ArgumentException($"SignatureAlgorithm '{id}' is not an EC algorithm.", nameof(id)); } _id = id; _keyRequirement = new KeyRequirement(KeyOperations.SignAndVerify, curveName.Oid, id.GetKeyName().ToString()); }
public KeyBase?FindWithUseCount(KeyRequirement req, DateTime bestBefore) { return(req.KeyType == KeyType.Ec ? FindWithUseCount(req.Operations, req.CurveName !, bestBefore) : FindWithUseCount(req.KeyType, req.Operations, req.KeySizeInBits !.Value, bestBefore)); }
internal async ValueTask <KeyBase?> FindOrCreateKeyAsync(IActivityMonitor monitor, KeyRequirement keyRequirement, DateTime bestBefore, uint maxUseCount, bool createLocal) { var local = _party.LocalParty; if (local == null) { return(null); } KeyBase?result = null; Debug.Assert(keyRequirement.KeyType == KeyType.Oct && keyRequirement.KeySizeInBits != null); _lock.EnterReadLock(); try { result = _keys.FindWithUseCount(KeyType.Oct, keyRequirement.Operations, keyRequirement.KeySizeInBits.Value, bestBefore); if (result != null) { return(result); } } finally { _lock.ExitReadLock(); } if (!createLocal) { return(null); } _lock.EnterUpgradeableReadLock(); try { // Only one thread (except readers but they don't read it) at a time can enter the Upgradeable lock: we can safely // double lock check and use the _keyCounter (nobody reads it). result = _keys.FindWithUseCount(KeyType.Oct, keyRequirement.Operations, keyRequirement.KeySizeInBits.Value, bestBefore); if (result != null) { return(result); } result = local.KeyFactory.CreateKey(monitor, HelperAndExtensions.ComputeKid(_keyCounter), _party, keyRequirement, bestBefore, maxUseCount); _lock.EnterWriteLock(); try { unchecked { ++_keyCounter; } _keys.Add(result); if (result != null && local.KeyStore != null) { await local.KeyStore.AddKeyAsync(monitor, _storeName, result.Kid.ToString(), (m, s) => KeyBase.Write(s, result, null)); } } finally { _lock.ExitWriteLock(); } } finally { _lock.ExitUpgradeableReadLock(); } return(result); }