43

I have generated a CSR that includes the field subject alt names:

openssl req -out mycsr.pem -new -key mykey.pem -days 365

When I inspect this it looks as expected with a new field present:

X509v3 Subject Alternative Name:
    DNS: my.alt.dns

However when I use this to sign a certificate that field is omitted for some reason.

I generate it with the following command:

openssl ca -out mycert.pem -infiles mycsr.pem

Can it be that my CA cert have to include the same Alt name for it to be included?

jimmy
  • 1,981
  • 3
  • 19
  • 28
  • Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. Also see [Where do I post questions about Dev Ops?](http://meta.stackexchange.com/q/134306). – jww Jun 22 '15 at 16:00
  • Also see [How do you sign Certificate Signing Request with your Certification Authority?](http://stackoverflow.com/a/21340898/608639) – jww Jun 22 '15 at 16:03
  • 1
    @jww I can see why you say the question is off-topic but that seems to be the case for most SSL related questions on stack-overflow including the one you are linking :) – jimmy Jun 22 '15 at 16:10
  • Yeah, we (the community) do a poor job of keeping the site tidy at times. I do my best to tag all the new ones so folks citing them see they questions should be taken elsewhere. We ***really*** need that DevOps site for questions like this, questions about configuring Apache and Nginx, etc ... – jww Jun 22 '15 at 17:21

3 Answers3

57

For everybody, who doesn´t like to edit the system-wide openssl.conf, there´s a native openssl CLI option for adding the SANs to the .crt from a .csr. All you have to use is openssl´s -extfile and -extensions CLI parameters.

Here´s an example:

openssl x509 -req -days 3650 -in alice.csr -signkey aliceprivate.key -out alice.crt -extfile alice-csr.conf -extensions v3_req

This requires a alice-csr.conf file, which looks like this (fill in your appropriate data) and which was used to generate the .csr with the command openssl req -new -key aliceprivate.key -out alice.csr -config alice-csr.conf:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
C = DE
ST = Thuringia
L = Erfurt
O = Alice Corp
OU = Team Foo
CN = server-alice

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = server-alice
DNS.2 = localhost

Keep in mind, that the -extensions v3_req option corresponds to the [v3_req] section in the file alice-csr.conf, where you define you Subject Alternative Names aka the domains, which you want to issue your certificate to.

As I always appreciate fully comprehensible examples, where one could reproduce every step, I created an example project featuring Spring Boot microservices: https://github.com/jonashackt/spring-boot-rest-clientcertificates-docker-compose

jonashackt
  • 12,022
  • 5
  • 67
  • 124
  • 4
    i don't understand why this worked vs the other 20 things i tried but it did.. thanks. – Flo Woo Mar 22 '19 at 05:56
  • 4
    thank you very much... this should be the accepted answer b/c it doesnt require systemwide changes (thus could be scripted) – Chad May 31 '19 at 00:30
  • 2
    This was the only thing I could get to work for me. Even changing the system .cnf file, as suggested in the accepted answer did not work. I made one small change to make this highly portable. I got rid of the ```[alt_names]``` section entirely and replaced ```subjectAltName = @alt_names``` with ```subjectAltName = $ENV::SAN```. Using this you can specify any subject alternative name by assigning the SAN environ variable. – Robert Kearns Dec 01 '19 at 13:16
  • 1
    This got me a little further along. You still have to use -config with the req command when building a CA it looks like. – John Ernest Aug 22 '20 at 23:34
  • The provided link to github in this answer has an example, but it does not use a CA to sign the csr (unless I overlooked something). – barrypicker Jul 15 '21 at 22:45
  • The repo's [README contains a section](https://github.com/jonashackt/spring-boot-rest-clientcertificates-docker-compose#3-self-signed-certificate-alicecrt), where the steps to self-sign / self-issue the certificate signing request (csr) is shown: `openssl x509 -req -days 3650 -in alice.csr -signkey aliceprivate.key -out alice.crt -extfile alice-csr.conf -extensions v3_req`. Using a CA instead would be also possible, but was ommitted here to reduce complexity. And in the end, the CA issues a certificate for the `.csr` in the same way - just acting as another authority of trust. – jonashackt Jul 16 '21 at 06:06
  • Don't forget to have the same name `[alt_names]` and `subjectAltName=@alt_names`. – Roland Jun 20 '23 at 18:29
  • Using the -extfile and -extensions parameters was the only way to keep the SANs in the certificate, as the openssl x509 removed them. It also helped me to create a CSR file and to generate the x509 based on it, and not to create the certificate directly (without CSR). – Cristian Chereji Jul 06 '23 at 07:20
28

You can use:

copy_extensions = copy 

under your CA_default section in your openssl.cnf.

but only when you're sure that you can trust the extensions in the CSR as pointed out in this thread: http://openssl.6102.n7.nabble.com/subjectAltName-removed-from-CSR-when-signing-td26928.html

See also: How can I generate a self-signed certificate with SubjectAltName using OpenSSL?

Community
  • 1
  • 1
Hans Z.
  • 50,496
  • 12
  • 102
  • 115
  • @jimmy - be careful of `copy_extensions = copy`. You need to validate each signing request. A bad guy can set `CA = TRUE` and you will mint him a subordinate CA. – jww Jun 22 '15 at 16:01
  • @jww Good advice. I will have to consider this. – jimmy Jun 22 '15 at 16:12
  • 10
    Then why isn't there a feature where you can whitelist which extensions to copy? :( – Steen Schütt Nov 29 '18 at 12:14
10

Signing a CSR with alt names is described here well: https://www.feistyduck.com/library/openssl-cookbook/online/ch-openssl.html#creating-certificates-valid-for-multiple-hostnames

In short words, you create a something.ext file containing just the alt names:

subjectAltName = DNS:*.my.alt.dns, DNS:my.alt.dns

and then refer to this file in openssl x509 -req ... command: -extfile something.ext. Note that it happens when signing the CSR, not when preparing it.

Paul Lysak
  • 1,284
  • 1
  • 14
  • 18