예제 #1
0
        internal ECKey(ISystemClock clock, ICKBinaryReader r)
            : base(clock, r)
        {
            r.ReadByte();
            Oid?curveName = HelperAndExtensions.ReadNullableOid(r);

            Debug.Assert(curveName != null);
            _parameters = new ECParameters()
            {
                Curve = ECCurve.CreateFromOid(curveName),
                D     = ReadBytes(r),
                Q     = new ECPoint()
                {
                    X = ReadBytes(r), Y = ReadBytes(r)
                }
            };
            if (r.ReadBoolean())
            {
                _ecdh = ECDiffieHellman.Create(_parameters);
            }
            else
            {
                _ec = ECDsa.Create(_parameters);
            }
            JWKCurveName = GetJWKCurveName(_parameters.Curve.Oid);
        public bool Verify(object?key, ReadOnlySpan <byte> signature, ReadOnlySpan <byte> source)
        {
            var         k    = GetHash(key);
            Span <byte> hash = stackalloc byte[_keySize];

            return(GetHash(key).TryComputeHash(source, hash, out var _) &&
                   HelperAndExtensions.ConstantTimeEquals(signature, hash));
        }
예제 #3
0
 public KeyRequirement(ICKBinaryReader r)
 {
     r.ReadByte(); // Version.
     KeyType       = r.ReadEnum <KeyType>();
     Operations    = r.ReadEnum <KeyOperations>();
     KeySizeInBits = r.ReadNullableInt32(  );
     CurveName     = HelperAndExtensions.ReadNullableOid(r);
     if (r.ReadBoolean())
     {
         InitiatorAlgorithmName = r.ReadString();
     }
 }
예제 #4
0
 /// <summary>
 /// Writes this requirement.
 /// </summary>
 /// <param name="w">The writer.</param>
 /// <param name="withInitiatorAlgorithmName">Optionally writes the <see cref="InitiatorAlgorithmName"/> if any.</param>
 public void Write(ICKBinaryWriter w, bool withInitiatorAlgorithmName = false)
 {
     w.Write((byte)0);
     w.WriteEnum(KeyType);
     w.WriteEnum(Operations);
     w.WriteNullableInt32(KeySizeInBits);
     HelperAndExtensions.WriteNullableOid(w, CurveName);
     if (withInitiatorAlgorithmName && InitiatorAlgorithmName != null)
     {
         w.Write(true);
         w.Write(InitiatorAlgorithmName);
     }
     else
     {
         w.Write(false);
     }
 }
 protected override void Write(Utf8JsonWriter w, KeyOperations?restrictedOperations, WriteUseCountOption useCountOption)
 {
     base.Write(w, restrictedOperations, useCountOption);
     HelperAndExtensions.WriteBase64Url(w, UTF8EncodedNames.K, _key);
 }
예제 #6
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);
        }