public KeyBase?Find(KeyRequirement req, DateTime bestBefore)
 {
     foreach (var k in this)
     {
         if (req.Match(k) && k.BestBefore < bestBefore)
         {
             return(k);
         }
     }
     return(null);
 }
Example #2
0
 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());
        }
Example #7
0
        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));
 }
Example #10
0
        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);
        }