C# remote web request certificate error
- by Ben
Hi.
I am currently integrating a payment gateway into an application. Following a successful transaction the remote payment gateway posts details of the transaction back to my application (ITN). It posts to a HttpHandler that is used to read and validate the data.
Part of the validation performed is a POST made by the handler to a validation service provided by the payment gateway. This effectively posts some of the original form values received back to the payment gateway to ensure they are valid.
The url that I am posting back to is: "https://sandbox.payfast.co.za/eng/query/validate"
and the code I am using:
/// <summary>
/// Posts the data back to the payment processor to validate the data received
/// </summary>
public static bool ValidateITNRequestData(NameValueCollection formVariables) {
bool isValid = true;
try {
using (WebClient client = new WebClient()) {
string validateUrl = (UseSandBox) ? SandboxValidateUrl : LiveValidateUrl;
byte[] responseArray = client.UploadValues(validateUrl, "POST", formVariables);
// get the resposne and replace the line breaks with spaces
string result = Encoding.ASCII.GetString(responseArray);
result = result.Replace("\r\n", " ").Replace("\r", "").Replace("\n", " ");
if (result == null || !result.StartsWith("VALID")) {
isValid = false;
LogManager.InsertLog(LogTypeEnum.OrderError, "PayFast ITN validation failed",
"The validation response was not valid.");
}
}
} catch (Exception ex) {
LogManager.InsertLog(LogTypeEnum.Unknown, "Unable to validate ITN data. Unknown exception", ex);
isValid = false;
}
return isValid;
}
However, on calling WebClient.UploadValues the following exception is raised:
System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure. at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception) at
For the sake of brevity I haven't listed the full call stack (I can do if anyone thinks it will help).
The remote certificate does appear to be valid. To get around the problem I did try adding a new RemoteCertificateValidationCallback that always returned true but just ended up getting the following exception:
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) at System.Security.CodeAccessPermission.Demand() at System.Net.ServicePointManager.set_ServerCertificateValidationCallback(RemoteCertificateValidationCallback value) at NopSolutions.NopCommerce.Payment.Methods.PayFast.PayFastPaymentProcessor.ValidateITNRequestData(NameValueCollection formVariables) The action that failed was: Demand The type of the first permission that failed was: System.Security.Permissions.SecurityPermission The Zone of the assembly that failed was: MyComputer
So I am not sure this will work in medium trust?
Any help would be much appreciated.
Thanks
Ben