Reputation: 1052
When I try to connect to an HTTPS REST service I get the following error during execution (currently within unit testing in VS 2013):
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel. Result StackTrace: at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
Code:
public class CompanyApi
{
private string _username;
private string _password;
private string _url;
public CompanyApi(string username, string password, string url)
{
_username = username;
_password = password;
_url = url;
}
public string MakeUrl(string programHostName)
{
return string.Format("https://{0}/api/v1/program/", programHostName);
}
/// <summary>Creates a basic HTTP authentication token.</summary>
protected AuthenticationHeaderValue CreateBasicCredentials()
{
string token = String.Format("{0}:{1}", _username, _password);
return new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.UTF8.GetBytes(token))
);
}
public void UserGivePoints(add_points newPointsRequest)
{
string url = MakeUrl(_url);
WebRequestHandler handler =
new WebRequestHandler
{
AllowAutoRedirect = false,
UseProxy = false
};
HttpClient client =
new HttpClient(handler)
{
BaseAddress = new Uri(url)
};
client.DefaultRequestHeaders.Authorization = CreateBasicCredentials();
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/x-javascript"));
// Create the JSON formatter.
MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
// Use the JSON formatter to create the content of the request body.
HttpContent content = new ObjectContent<add_points>(newPointsRequest, jsonFormatter);
client.Timeout = new TimeSpan(0, 0, 30);
HttpResponseMessage message = client.PostAsync("user/add_points?outputFormat=JSON", content).Result;
if (message.StatusCode != HttpStatusCode.OK)
throw new Exception("Wrong result code - " + message.StatusCode);
message.EnsureSuccessStatusCode();
}
}
public class add_points
{
public string username { get; set; }
public int amount { get; set; }
public string account_name { get; set; }
public string reason { get; set; }
public add_points(string userId, int pointAmount, string account, string pointDescription)
{
username = userId;
amount = pointAmount;
account_name = account;
reason = pointDescription;
}
public add_points()
{ }
}
As far as I can tell from the error, it doesn't seem to like the certificate on the site itself, this is the warning message that I get from Chrome:
You attempted to reach tribute.site.com.int01.site.com, but instead you actually reached a server identifying itself as *.int01.site.com. This may be caused by a misconfiguration on the server or by something more serious. An attacker on your network could be trying to get you to visit a fake (and potentially harmful) version of tribute.site.com.int01.site.com. You should not proceed, especially if you have never seen this warning before for this site.
I am at a loss to work around this, the vendor assures me that many others connect to the API without issues...
Any ideas?
Update 2014-08-08
I added a
ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }
line within the WebRequestHandler initializing code and still get the same problem.
Upvotes: 0
Views: 2029
Reputation: 1299
There are few options here:
workarounds:
preferable:
Upvotes: 1
Reputation: 16595
A certificate with the hostname *.int01.site.com
will only match com.int01.site.com
but not tribute.site.com.int01.site.com
. Wildcards only match on the same level. To make that certificate valid they would need to have an SSL certificate with the ability to match *.*.*.int01.site.com
.
I would highly recommend avoiding any code that would disable the certificate checks and work with the vendor to get a valid certificate. Disabling or working around the certificate checks just degrades the security. If you really have to disable checks, use certificate pinning to validate the vendor certificate before sending data.
Upvotes: 1