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)); }
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(); } }
/// <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); }
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); }