I used IIS 7 on Windows Server Enterprise 2008 to generate a self-signed cert for use with IIS (basically one-click button).
However, even when I export and add this cert to a windows client's curl-ca-bundle.crt, neither it nor openssl.exe will not verify the cert correctly:
openssl s_client -CAfile curl-ca-bundle.crt -showcerts -connect myserver.ad.pri:443
CONNECTED(00000003)
depth=0 /CN=myserver.ad.pri
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /CN=myserver.ad.pri
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=myserver.ad.pri
i:/CN=myserver.ad.pri
-----BEGIN CERTIFICATE-----
MIIDADCCAeigAwIBAgIQTi9gdBLdo6pJ1h4Zljr/wzANBgkqhkiG9w0BAQUFADAp
....
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=myserver.ad.pri
issuer=/CN=myserver.ad.pri
---
No client certificate CA names sent
---
SSL handshake has read 924 bytes and written 444 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Start Time: 1377728216
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
read:errno=104
I used IE to export the cert to Base-64 Encoded, which is openssl-readable as PEM: openssl x509 -inform PEM -in myserver.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
4e:2f:60:74:12:dd:a3:aa:49:d6:1e:19:96:3a:ff:c3
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=myserver.ad.pri
Validity
Not Before: Aug 26 15:38:46 2013 GMT
Not After : Aug 26 00:00:00 2014 GMT
Subject: CN=myserver.ad.pri
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
....
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage:
Key Encipherment, Data Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha1WithRSAEncryption
...
-----BEGIN CERTIFICATE-----
....
openssl/curl with the same curl-ca-bundle.crt will verify certs from google.com:443 etc. just fine.
I also ran into this (and I'm very surprised more people haven't.) when I couldn't get a NodeJS HTTP(s) client to connect to an IIS instance with a self-signed-certificate on it (one created through IIS manager) Just got the dreaded' unable to verify the first certificate error!
It seems that this is because the certificates that IISManager creates for this purpose specify some 'Key Usage' extensions; 'Key Encipherment' and 'Data Encipherment'.
It turns out that when openssl encounters a certificate that specifies 'Key Usage' but fails to specify the 'certSign' usage then the openssl code will discount that certificate as a possible CA certificate even if it has been correctly provided to the openssl code (meaning it is unable to verify the certificate against said absent CA!).
(See the logic here https://github.com/openssl/openssl/blob/6f0ac0e2f27d9240516edb9a23b7863e7ad02898/crypto/x509v3/v3_purp.c#L503 )
The solution is as the one already above, which is to create your own certificates with the correct key usages (or no key usage extensions!)
I also thought I should include an alternative way of creating the Self Signed certificate that openssl clients would be happy with if you're in windows land.
First download the powershell script from here
In a powershell console (Administrative) execute the following commands from within a folder that contains the downloaded scripts
New-SelfsignedCertificateEx -StoreLocation "LocalMachine" -KeyUsage "DigitalSignature,KeyEncipherment,KeyCertSign" -Subject "CN=<HOST_NAME_TO_USE>" -FriendlyName "<HOST_NAME_TO_USE>" -SignatureAlgorithm sha256 -SubjectAlternativeName "<HOST_NAME_TO_USE>","anotherhost.org","someotherdomain.com"
Once you've executed the above command your LocalMachine\Personal Certificates store will contain a self-signed certificate that can be used by IIS for its SSL communications. (Please note you may also need to copy this certificate into one of the Trusted Root stores as well to guarantee that the certificate is trusted on that machine)