3

I have been trying to access an API which is secured using SSL using python requests library as given below

requests.get('https://path/to/url',cert=('cert.pem','key.pem'),verify='ca.pem')

but am getting an error

File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 385, in send
raise SSLError(e)
requests.exceptions.SSLError: hostname '10.10.10.10' doesn't match u'*' # IP address is not real.

If my understanding is right this certificates can be used with any server since they are signed with '*' as domain.

I guess the requests library is making a strict match of hostname verification instead of regular expression matching.

so my question is whether it is a bug with requests library or is this the way it is indented to work?

It is working perfectly fine when I use curl command as given below.

curl https://path/to/url  --cert cert.pem  --key key.pem --cacert ca.pem

So i have two possibilities, either curl library is not performing hostname verification or they are doing it with regular expression.

Where am i going wrong here? Expecting a detailed answer

midhun
  • 157
  • 2
  • 2
  • 10

2 Answers2

3

How wildcards are matched is described in RFC 2818, more precisely stated in RFC 6125 and there are also information in the CAB baseline requirements. At the end the browsers implement the following:

  • Only the leftmost label can have a wildcard and a wildcard matches only a single label. That is no wildcards like *, *.*.example.com etc are possible. Also *.example.com matches www.example.com but not sub.www.example.com or example.com.
  • Additionally there are restrictions depending on the public key suffix, i.e no browsers allow wildcards for *.com, some don't allow wildcards for *.co.uk to.
  • And there are restriction where the wildcard can be in the certificate. All support wildcards in the subject alternative name section, but not all allow wildcards in the common name.
  • Apart from that wildcards are only for hostnames. This means IP addresses are not allowed to be matched against a wildcard entry. To have an IP address included into a certificate you must use an iPAdress as subject alternative name (all browsers except IE) or a dNSName (no browsers except IE) or the IP address must be in the CN (all browsers except Safari).

Several languages like python did not do any checks against the hostname at all in the past but with 2.7.9 python also checks the hostname by default and has an implementation which is mostly compatible to what the browsers do.

As for curl: it depends on the version of curl you use. 7.36 should be ok but older versions have flaws in the validation.

Community
  • 1
  • 1
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
0

There are no real, approved standards about how the wildcards are interpreted in certificates. Whether they match one label, or multiple, whether they match ips or not (the ones in SAN extension definitely don't), whether you can match part of a label (prefix-*.example.com), etc. are not well defined.

I'd suggest not using * on it's own, but only as one full label (*.example.com). And don't use it for IPs, just names.

viraptor
  • 33,322
  • 10
  • 107
  • 191
  • These certificates are not generated by me. It is a third party service which i don't have control. My concern is on the different behavior of two libraries with the same functionality. – midhun Oct 30 '15 at 06:21
  • The most common cases are actually well defined in several places. Less well defined are only the edge cases. – Steffen Ullrich Oct 30 '15 at 06:26
  • @Steffen Ullrich So you are saying that the implementations in requests, and curl may differ and hence i can't use these certificates with requests ? – midhun Oct 30 '15 at 06:34
  • @midhun: see my answer for more details. – Steffen Ullrich Oct 30 '15 at 06:38
  • @SteffenUllrich It's messy. Yes, they're defined but not everything interprets them the same way. Even the rfc you linked states: "The client MAY match a presented identifier in which the wildcard character is not the only character of the label (...). However, the client SHOULD NOT attempt to match a presented identifier where the wildcard character is embedded within an A-label or U-label [IDNA-DEFS] of an internationalized domain name [IDNA-PROTO]." So in practice it's "do this, unless you don't want to". Ok, it's an approved standard, but it's meaningless in practice. – viraptor Nov 01 '15 at 23:51
  • The way it is implemented in the browsers conforms mostly to the standard (except for edge cases) and the programming languages and command line tools slowly catch up. Insofar I would not consider the standard meaningless. – Steffen Ullrich Nov 02 '15 at 05:40