public async Task <bool> IsValidRequest(HeaderObject headerObject, string body, string webHookId) { bool isValid = false; try { HashAlgorithmName hashAlgorithm = ConvertAuthAlgorithmHeaderToHashAlgorithmName(headerObject.AuthenticationAlogrithm); uint crc32 = Crc32.ComputeChecksum(body); string expectedSignature = $"{headerObject.TransmissionId}|{headerObject.TransmissionTime}|{webHookId}|{crc32}"; byte[] expectedSignatureBytes = Encoding.UTF8.GetBytes(expectedSignature); _logger.LogInformation($"Expected sig: {expectedSignature}"); _logger.LogInformation($"Cert url: {headerObject.CertificateUrl}"); var x509Certificate = await CertificateManager.Instance.GetCertificateFromUrl(headerObject.CertificateUrl); using (var rsa = x509Certificate.GetRSAPublicKey()) { byte[] signatureBytes = Convert.FromBase64String(headerObject.TransmissionSig); //TODO: Implement Verification => || -> && with working verification of sigs isValid = CertificateManager.Instance.ValidatePayPalClientCertificate(x509Certificate) || rsa.VerifyData(expectedSignatureBytes, signatureBytes, hashAlgorithm, RSASignaturePadding.Pss); } } catch (Exception ex) { throw new Exception($"Encountered an error while attepting to validate a webhook event.", ex); } return(isValid); }
protected async override Task <AuthenticateResult> HandleAuthenticateAsync() { HeaderObject headerObject = GetHeaderObject(); string body = await new StreamReader(Request.Body).ReadToEndAsync(); if (headerObject == null || !await _authenticationService.IsValidRequest(headerObject, await new StreamReader(Request.Body).ReadToEndAsync(), Options.WebHookId)) { return(AuthenticateResult.Fail("Invalid transmission signature!")); } Request.Body.Position = 0; IEnumerable <Claim> claims = new List <Claim>() { new Claim(ClaimTypes.Authentication, "true") }; IEnumerable <ClaimsIdentity> identity = new List <ClaimsIdentity>() { new ClaimsIdentity(claims) { } }; return(AuthenticateResult.Success( new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties { ExpiresUtc = DateTime.UtcNow.AddMinutes(15), IsPersistent = false, AllowRefresh = false }, EventRequestAuthenticationDefaults.AuthenticationScheme))); }