/// <inheritdoc/> public async Task <bool> VerifyAsync(KeyHandle handle, byte[] hash, SignatureType algorithm, byte[] signature, CancellationToken ct) { var document = await _keys.GetAsync <KeyDocument>(KeyId.GetId(handle), ct); if (document.Value.IsDisabled) { throw new InvalidOperationException("Key is disabled"); } var key = document.Value.KeyJson.ToKey(); if (key == null) { throw new ResourceNotFoundException("Key not found"); } switch (key.Type) { case KeyType.RSA: using (var rsa = key.ToRSA()) { return(rsa.VerifyHash(hash, signature, algorithm.ToHashAlgorithmName(), algorithm.ToRSASignaturePadding())); } case KeyType.ECC: using (var ecc = key.ToECDsa()) { return(ecc.VerifyHash(hash, signature)); } default: throw new ArgumentException("Bad key type passed for signing"); } }
/// <summary> /// Create self signed cert /// </summary> /// <param name="signature"></param> /// <param name="subject"></param> /// <returns></returns> internal static AsymmetricAlgorithm CreateCsr(this SignatureType signature, string subject, out CertificateRequest csr) { AsymmetricAlgorithm alg = null; try { if (signature.IsRSA()) { var rsa = RSA.Create(); alg = rsa; csr = new CertificateRequest(X500DistinguishedNameEx.Create(subject), rsa, signature.ToHashAlgorithmName(), signature.ToRSASignaturePadding()); return(alg); } if (signature.IsECC()) { var ecdsa = ECDsa.Create(); alg = ecdsa; csr = new CertificateRequest(X500DistinguishedNameEx.Create(subject), ecdsa, signature.ToHashAlgorithmName()); return(alg); } throw new ArgumentException("Bad signature"); } catch { alg?.Dispose(); throw; } }
/// <summary> /// To DER algorithm identifier /// </summary> /// <param name="signature"></param> /// <returns></returns> public static byte[] ToAlgorithmIdentifier(this SignatureType signature) { var hashAlgorithm = signature.ToHashAlgorithmName(); string oid; if (signature.IsRSA()) { var padding = signature.ToRSASignaturePadding(); if (padding == RSASignaturePadding.Pkcs1) { if (hashAlgorithm == HashAlgorithmName.SHA256) { oid = Oids.RsaPkcs1Sha256; } else if (hashAlgorithm == HashAlgorithmName.SHA384) { oid = Oids.RsaPkcs1Sha384; } else if (hashAlgorithm == HashAlgorithmName.SHA512) { oid = Oids.RsaPkcs1Sha512; } else { throw new ArgumentOutOfRangeException(nameof(hashAlgorithm), $"The hash algorithm {hashAlgorithm.Name} is not supported."); } using (var writer = new AsnWriter(AsnEncodingRules.DER)) { writer.PushSequence(); writer.WriteObjectIdentifier(oid); writer.WriteNull(); writer.PopSequence(); return(writer.Encode()); } } if (padding == RSASignaturePadding.Pss) { int saltLen; if (hashAlgorithm == HashAlgorithmName.SHA256) { saltLen = 256 / 8; oid = Oids.Sha256; } else if (hashAlgorithm == HashAlgorithmName.SHA384) { saltLen = 384 / 8; oid = Oids.Sha384; } else if (hashAlgorithm == HashAlgorithmName.SHA512) { saltLen = 512 / 8; oid = Oids.Sha512; } else { throw new ArgumentOutOfRangeException(nameof(hashAlgorithm), $"The hash algorithm {hashAlgorithm.Name} is not supported."); } using (var writer = new AsnWriter(AsnEncodingRules.DER)) { writer.WritePssSignatureAlgorithmIdentifier(saltLen, oid); return(writer.Encode()); } } throw new ArgumentOutOfRangeException(nameof(signature), "Specified Padding is not supported."); } if (hashAlgorithm == HashAlgorithmName.SHA256) { oid = Oids.ECDsaWithSha256; } else if (hashAlgorithm == HashAlgorithmName.SHA384) { oid = Oids.ECDsaWithSha384; } else if (hashAlgorithm == HashAlgorithmName.SHA512) { oid = Oids.ECDsaWithSha512; } else { throw new ArgumentOutOfRangeException(nameof(hashAlgorithm), $"The hash algorithm {hashAlgorithm.Name} is not supported."); } using (var writer = new AsnWriter(AsnEncodingRules.DER)) { writer.PushSequence(); writer.WriteObjectIdentifier(oid); writer.PopSequence(); return(writer.Encode()); } }