public void UrlCheckTest() { /* * The protocol is equal to https (case insensitive). * The hostname is equal to s3.amazonaws.com (case insensitive). * The path starts with /echo.api/ (case sensitive). * If a port is defined in the URL, the port is equal to 443. */ string[] correctUrls = { "https://s3.amazonaws.com/echo.api/echo-api-cert.pem", "https://s3.amazonaws.com:443/echo.api/echo-api-cert.pem", "https://s3.amazonaws.com/echo.api/../echo.api/echo-api-cert.pem" }; var validator = new DotNetCertValidator() { Header = new RequestHeader() }; foreach (var item in correctUrls) { validator.Header.CertChainUrl = item; Assert.IsTrue(validator.VerifyCertificateUrl()); } string[] invalidUrls = { null, string.Empty, "http://s3.amazonaws.com/echo.api/echo-api-cert.pem", // invalid protocol "https://notamazon.com/echo.api/echo-api-cert.pem", // invalid hostname "https://s3.amazonaws.com/EcHo.aPi/echo-api-cert.pem", //invalid path "https://s3.amazonaws.com/invalid.path/echo-api-cert.pem", //invalid path "https://s3.amazonaws.com:563/echo.api/echo-api-cert.pem", //invalid port }; foreach (var item in invalidUrls) { validator.Header.CertChainUrl = item; Assert.IsFalse(validator.VerifyCertificateUrl()); } }
public void TestChain() { var signature = "MY SIGNATURE"; var data = Convert.FromBase64String("REQUEST AS BASE64"); var validator = new DotNetCertValidator(); var header = new RequestHeader() { CertChainUrl = "https://s3.amazonaws.com/echo.api/echo-api-cert-3.pem", RequestRawData = data, Signature = signature }; //Assert.AreEqual(validator.Verify(header), SpeechletRequestValidationResult.InvalidSignature); header.CertChainUrl = "https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem"; Assert.AreEqual(validator.Verify(header), SpeechletRequestValidationResult.OK); }
/// <summary> /// Processes Alexa request AND validates request signature /// </summary> /// <param name="httpRequest"></param> /// <returns></returns> public virtual async Task <HttpResponseMessage> GetResponseAsync(HttpRequestMessage httpRequest) { DateTime now = DateTime.UtcNow; // reference time for this request RequestHeader requestHeader = new RequestHeader(); requestHeader.Read(httpRequest); await OnRequestIncomeAsync(requestHeader); #if HasBouncyCastle var cerValidator = new BouncyCastleCertValidator(); #else var cerValidator = new DotNetCertValidator(); #endif var validationResult = await cerValidator.VerifyAsync(requestHeader); if (!await OnRequestValidationAsync(requestHeader, validationResult)) { return(new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = validationResult.ToString() }); } try { RequestEnvelope = SpeechletRequestEnvelope.FromJson(requestHeader.RequestAsString); if (!SpeechletRequestTimestampVerifier.VerifyRequestTimestamp(RequestEnvelope, now)) { validationResult = validationResult | SpeechletRequestValidationResult.InvalidTimestamp; } } catch (Exception e1) { await OnParsingErrorAsync(e1); validationResult = SpeechletRequestValidationResult.InvalidJson; } try { string alexaResponsejson = await DoProcessRequestAsync(RequestEnvelope); if (alexaResponsejson == null) { await OnResponseOutgoingAsync("->alexaResponsejson == null"); return(null); } await OnResponseOutgoingAsync(alexaResponsejson); return(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(alexaResponsejson, Encoding.UTF8, "application/json") });; } catch (NotImplementedException) { return(null); } catch (Exception e2) { await OnParsingErrorAsync(e2); return(new HttpResponseMessage(HttpStatusCode.InternalServerError)); } }