public async Task <int> Run(VerifyOptions options, string httpMessage) { ISignatureAlgorithm signatureAlgorithmForVerification; if (string.IsNullOrEmpty(options.KeyType) || options.KeyType.Equals("RSA", StringComparison.OrdinalIgnoreCase)) { RSAParameters rsaPublicKey; using (var stream = File.OpenRead(options.PublicKey)) { using (var reader = new PemReader(stream)) { rsaPublicKey = reader.ReadRsaKey(); } } signatureAlgorithmForVerification = RSASignatureAlgorithm.CreateForVerification(HashAlgorithmName.SHA512, rsaPublicKey); } else if (options.KeyType.Equals("P256", StringComparison.OrdinalIgnoreCase) || options.KeyType.Equals("ECDSA", StringComparison.OrdinalIgnoreCase)) { ECParameters ecPublicKey; using (var stream = File.OpenRead(options.PublicKey)) { using (var reader = new StreamReader(stream)) { var fileContents = reader.ReadToEnd(); var lines = fileContents.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); lines = lines.Skip(1).Take(lines.Length - 2).ToArray(); var pem = string.Join("", lines); var ecdsa = ECDsa.Create(); var derArray = Convert.FromBase64String(pem); ecdsa.ImportSubjectPublicKeyInfo(derArray, out _); ecPublicKey = ecdsa.ExportParameters(false); } } signatureAlgorithmForVerification = ECDsaSignatureAlgorithm.CreateForVerification(HashAlgorithmName.SHA512, ecPublicKey); } else if (options.KeyType.Equals("HMAC", StringComparison.OrdinalIgnoreCase)) { signatureAlgorithmForVerification = SignatureAlgorithm.CreateForVerification(options.PublicKey, HashAlgorithmName.SHA512); } else { throw new NotSupportedException("The specified key type is not supported."); } var serviceProvider = new ServiceCollection() .AddHttpMessageSignatureVerification(provider => { var clientStore = new InMemoryClientStore(); clientStore.Register(new Client( new KeyId("test"), "ConformanceClient", signatureAlgorithmForVerification, TimeSpan.FromSeconds(30), TimeSpan.FromMinutes(1))); return(clientStore); }) .BuildServiceProvider(); var verifier = serviceProvider.GetRequiredService <IRequestSignatureVerifier>(); var clientRequest = HttpRequestMessageParser.Parse(httpMessage); var requestToVerify = await clientRequest.ToServerSideHttpRequest(); var verificationResult = await verifier.VerifySignature(requestToVerify, new SignedRequestAuthenticationOptions { OnSignatureParsed = (request, signature) => { if (!string.IsNullOrEmpty(options.Algorithm)) { signature.Algorithm = options.Algorithm; } return(Task.CompletedTask); } }); return(verificationResult is RequestSignatureVerificationResultSuccess ? 0 : 1); }
public async Task <int> Run(SignOptions options, string httpMessage) { ISignatureAlgorithm signatureAlgorithm; if (string.IsNullOrEmpty(options.KeyType) || options.KeyType.Equals("RSA", StringComparison.OrdinalIgnoreCase)) { RSAParameters rsaPrivateKey; using (var stream = File.OpenRead(options.PrivateKey)) { using (var reader = new PemReader(stream)) { rsaPrivateKey = reader.ReadRsaKey(); } } signatureAlgorithm = RSASignatureAlgorithm.CreateForSigning(HashAlgorithmName.SHA512, rsaPrivateKey); } else if (options.KeyType.Equals("P256", StringComparison.OrdinalIgnoreCase) || options.KeyType.Equals("ECDSA", StringComparison.OrdinalIgnoreCase)) { ECParameters ecPrivateKey; using (var stream = File.OpenRead(options.PrivateKey)) { using (var reader = new StreamReader(stream)) { var fileContents = reader.ReadToEnd(); var lines = fileContents.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); lines = lines.Skip(1).Take(lines.Length - 2).ToArray(); var pem = string.Join("", lines); var ecdsa = ECDsa.Create(); var derArray = Convert.FromBase64String(pem); ecdsa.ImportPkcs8PrivateKey(derArray, out _); ecPrivateKey = ecdsa.ExportParameters(true); } } signatureAlgorithm = ECDsaSignatureAlgorithm.CreateForSigning(HashAlgorithmName.SHA512, ecPrivateKey); } else if (options.KeyType.Equals("HMAC", StringComparison.OrdinalIgnoreCase)) { signatureAlgorithm = SignatureAlgorithm.CreateForSigning(options.PrivateKey, HashAlgorithmName.SHA512); } else { throw new NotSupportedException("The specified key type is not supported."); } if (!string.IsNullOrEmpty(options.Algorithm) && !options.Algorithm.StartsWith("rsa", StringComparison.OrdinalIgnoreCase) && !options.Algorithm.StartsWith("hmac", StringComparison.OrdinalIgnoreCase) && !options.Algorithm.StartsWith("ecdsa", StringComparison.OrdinalIgnoreCase)) { signatureAlgorithm = new CustomSignatureAlgorithm(options.Algorithm); } var signingSettings = new SigningSettings { SignatureAlgorithm = signatureAlgorithm, EnableNonce = false, DigestHashAlgorithm = HashAlgorithmName.SHA256, AutomaticallyAddRecommendedHeaders = false, Headers = options.Headers ?.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(h => new HeaderName(h)) .ToArray() }; var signer = _requestSignerFactory.Create( new KeyId("test"), signingSettings); var request = HttpRequestMessageParser.Parse(httpMessage); var created = DateTimeOffset.UtcNow; if (!string.IsNullOrEmpty(options.Created)) { var createdUnix = int.Parse(options.Created); created = DateTimeOffset.FromUnixTimeSeconds(createdUnix); } var expires = signingSettings.Expires; if (!string.IsNullOrEmpty(options.Expires)) { var expiresUnix = int.Parse(options.Expires); var expiresAbsolute = DateTimeOffset.FromUnixTimeSeconds(expiresUnix); expires = expiresAbsolute - created; } await signer.Sign(request, created, expires); var httpMessageLines = new List <string>(httpMessage.Split('\n').Select(l => l.Trim())); httpMessageLines.Insert(1, "Authorization: " + request.Headers.Authorization.Scheme + " " + request.Headers.Authorization.Parameter); var fullMessage = string.Join('\n', httpMessageLines); Log.Information(fullMessage); Console.Out.Flush(); return(0); }