Is it possible that the lines are ^M-terminated? This is a potential issue when moving files from Windows to UNIX systems. One easy way to check is to use vi
in "show me the binary" mode, with vi -b /etc/apache2/domain.ssl/domain.ssl.crt/domain.com.crt
.
If each line ends with a control-M, like this
-----BEGIN CERTIFICATE-----^M
MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM^M
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg^M
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x^M
you've got a file in Windows line-terminated format, and apache doesn't love those.
Your options include moving the file over again, taking more care; or using the dos2unix
command to strip those out; you can also remove them inside vi, if you're careful.
Edit: thanks to @dave_thompson_085, who points out that this answer no longer applies in 2019. That is, Apache/OpenSSL are now tolerant of ^M-terminated lines, so they don't cause problems. That said, other formatting errors, several different examples of which appear in the comments, can still cause problems; check carefully for these if the certificate has been moved across systems.
The structure of this IIS7 renewal request is actually quite elegant. It seems to start from the premise that because this is a request to renew a current certificate, it needs to prove that the request is coming from the correct host -- i.e. the host that is actually using the current certificate & ∴ owns the associated private key. In the Internet world, you prove that you are allowed to request renewals for a certificate by authenticating to your CA as the original user, rather than creating a signed CSR.
To prove the right to issue a renewal request, IIS7 creates a normal CSR (PKCS#10 object), and then signs it, and provides the cert of the key that signed it.
- IIS7 renewal CSR
- PKCS#7 Data
- PKCS#10 Data (the ordinary CSR)
- Normal server certificate
- Issuing CA data
- RSA signature (I assume)
Use openssl asn1parse -in iis7rcsr -i
to see the structure of the file, and compare this to normal CSRs. You should see an OCTET STRING near the beginning, in an object labelled ":pkcs7-data", which is what you need to extract to get the CSR.
$ openssl asn1parse -in iis7rcsr -i
0:d=0 hl=4 l=4273 cons: SEQUENCE
4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData
15:d=1 hl=4 l=4258 cons: cont [ 0 ]
19:d=2 hl=4 l=4254 cons: SEQUENCE
23:d=3 hl=2 l= 1 prim: INTEGER :01
26:d=3 hl=2 l= 11 cons: SET
28:d=4 hl=2 l= 9 cons: SEQUENCE
30:d=5 hl=2 l= 5 prim: OBJECT :sha1
37:d=5 hl=2 l= 0 prim: NULL
39:d=3 hl=4 l=2426 cons: SEQUENCE
43:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
54:d=4 hl=4 l=2411 cons: cont [ 0 ]
58:d=5 hl=4 l=2407 prim: OCTET STRING [HEX DUMP]:3082096330820...
In order to get the actual PKCS#10 CSR out of here, we need that offset number, "58" in this example. Then we can use that offset to extract the binary version of that object :-
$ openssl asn1parse -in iis7rcsr -strparse 58 -out thecsr -noout
Next we can read that output file 'thecsr' with openssl req
, remembering to specify the input format DER.
$ openssl req -in thecsr -inform DER -text -noout
Certificate Request:
Data:
Version: 0 (0x0)
Subject: (normal CSR Subject: line, censored)
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
...
I can wrap all this up into one command-line with no temporary files (but sadly 2 reads of the original cert), as long as I can use Linux's /proc/self/fd/
to fool openssl (it will do native tricks with file descriptors for password handling, but not normal output).
$ openssl asn1parse -in iis7rcsr -strparse $(openssl asn1parse -in iis7rcsr | grep -A2 ':pkcs7-data'|tail -1|cut -d: -f1) -out /dev/stdout -noout | openssl req -inform DER -noout -text
Certificate Request:
Data:
Version: 0 (0x0)
Subject: (Subject: line censored again)
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
...
This long command line is directly equivalent to the simple openssl req -in non-iis7rcsr -noout -text
that I normally use :-)
Best Answer
You can, but you shouldn't as you are obviously discussing DV-certificates here.
A certificate identify "something". That something can be an organization, an individual, a website, an email address, an IP address, a piece of code, etc.
If you are creating certificates to be used in the HTTPS world you need to have a DNS name in the certificate, in the SAN section. You should not use HTTPS URLs with IP addresses in the hostname part because, even if can technically work, and you can have certificates with IP addresses instead of names, they have to be generated differently and you will have far more troubles finding a CA to sign them.
You should register a domain name, anyone, and then use that as a suffix to name all your hosts, and you solve your problem they way it should be done: all hosts now have a name, and hence you can create a proper certificate for that name.