This was discovered after assisting a person in #perl at Freenode, who was using the following URL for testing:
HTTPS://WWW.SPS-SERVICE.EU/6AV2124-0GC01-0AX0
Attempts to connect to this URL were resulting in a Can't connect to WWW.SPS-SERVICE.EU:443 (certificate verify failed) error. It was then discovered that the lower case form of this URL worked and, after further testing, that specifying anything other than www. as the first component of the hostname was enough to trigger the error. All of which should not happen, of course.
Eventually, I realised that the host in question requires SNI to be active, otherwise it reports an entirely different CN, against which verification is, indeed, impossible. For instance:
Sure enough, after setting the $DEBUG level to 2, I was able to confirm that IO::Socket::SSL was not attempting to use SNI in the failing case (the first name component being anything other than lower-case www):
DEBUG: .../IO/Socket/SSL.pm:720: not using SNI because hostname is unknown
This is where the issue lies:
# grep -n 'host = undef' /usr/lib64/perl5/vendor_perl/5.24.3/IO/Socket/SSL.pm
712: $host = undef if $host !~m{[a-z_]} or $host =~m{:};
Specifically, the above regular expression does not tolerate any names that contain upper-case characters, in which case SNI becomes impossible. Adjusting the regular expression to tolerate upper-case alphabetical characters, or adding the /i flag is enough for SNI to be correctly employed for all case-oriented permutations of this particular URL.
This was discovered after assisting a person in #perl at Freenode, who was using the following URL for testing:
Attempts to connect to this URL were resulting in a
Can't connect to WWW.SPS-SERVICE.EU:443 (certificate verify failed)
error. It was then discovered that the lower case form of this URL worked and, after further testing, that specifying anything other thanwww.
as the first component of the hostname was enough to trigger the error. All of which should not happen, of course.Eventually, I realised that the host in question requires SNI to be active, otherwise it reports an entirely different CN, against which verification is, indeed, impossible. For instance:
Sure enough, after setting the $DEBUG level to 2, I was able to confirm that IO::Socket::SSL was not attempting to use SNI in the failing case (the first name component being anything other than lower-case
www
):This is where the issue lies:
Specifically, the above regular expression does not tolerate any names that contain upper-case characters, in which case SNI becomes impossible. Adjusting the regular expression to tolerate upper-case alphabetical characters, or adding the
/i
flag is enough for SNI to be correctly employed for all case-oriented permutations of this particular URL.