0

I'm putting certificates into a repository that will not allow a successive certificate with more limited usage than the previous one. I need an initial dummy cert/key/chain to bootstrap the process whose usages are not more open than Let's Encrypt host certs which allow serverAuth and clientAuth. All I need is a dummy host cert that has these usages or less. However I have been unable to produce this given many iterations of commands, after reading many articles and SO posts yesterday and today.

Here is what I'm working with:

gen.sh

#!/bin/bash -e

rm dummy*

days=100

openssl genrsa -out dummy-root.key 2048

openssl req -new -x509 -days $days -subj '/C=US/ST=TX/O=foo/OU=bar/CN=dummy-root.com' -key dummy-root.key -out dummy-root.crt

openssl genrsa -out dummy-class2.key 2048

openssl req -new -subj '/C=US/ST=TX/O=foo/OU=bar/CN=dummy-class2.com' -key dummy-class2.key -out dummy-class2.csr 

openssl x509 -req -days $days -in dummy-class2.csr -CA dummy-root.crt -CAkey dummy-root.key -CAcreateserial -out dummy-class2.crt

openssl genrsa -out dummy-host.key 2048

openssl req -new -config gen.host.cfg -key dummy-host.key -out dummy-host.csr -extensions my_server_exts

openssl x509 -req -days $days -in dummy-host.csr -CA dummy-class2.crt -CAkey dummy-class2.key -set_serial 1 -out dummy-host.crt -sha256  -ext subjAltName

rm *.srl *.csr
cat dummy-host.crt dummy-class2.crt dummy-root.crt > dummy-chain.crt

# this always fails?
# openssl verify --CAfile dummy-root.crt -untrusted dummy-class2.crt dummy-host.crt

openssl x509 -noout -ext extendedKeyUsage < dummy-host.crt

And for the config file needed for the extensions (referred to above):

gen.host.cfg

[ req ]
prompt             = no
default_bits       = 2048
default_md         = sha256
distinguished_name = my_dn
req_extensions     = my_server_exts


[ my_dn ]
# The bare minimum is probably a commonName
            commonName = dummy-host2.com
           countryName = US
      organizationName = foo
organizationalUnitName = bar

[ my_server_exts ]
basicConstraints = critical,CA:false
keyUsage = keyEncipherment
# extendedKeyUsage = serverAuth
extendedKeyUsage = 1.3.6.1.5.5.7.3.1

The last line of gen.sh tries to read the extensions and always says "No extensions in certificate", which when sent to the certificate repository interprets as having "ANY" usage, and then refuses to reduce the usage when updating with a Lets Encrypt cert.

Why is my specified EKU not making it to the cert? Or how else can I create a cert that has a limited usage?

2
  • Are you saying the dummy host cert can't contain extensions if the CA does not contain extensions? – user1169420 Mar 31 '20 at 21:56
  • Sorry, I read your script too much superficially (didn't notice the x509 -CA invocations). I'll gather my remarks in an answer. – Piotr P. Karwasz Apr 1 '20 at 0:58
1

The only extensions added to your certificates are those of the Root CA, because you use the default config file. In the x509 command invocations you don't provide the -extfile and -extensions command line options.

To have more control on extensions added your should probably explicitly list the extensions for each certificate in your config file, add the keyUsage extension for the CA certificates and the subjectKeyIdentifier and authorityKeyIdentifier to all of them:

[ req ]
default_bits       = 2048
default_md         = sha256
distinguished_name = dn

[ dn ]
# -subj used instead

[ root_exts ]
basicConstraints = critical,CA:true
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = keyCertSign, cRLSign

[ intermediate_exts ]
# Can not sign other CA certificates
basicConstraints = critical,CA:true,pathlen:0
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = keyCertSign, cRLSign

[ server_exts ]
basicConstraints = critical,CA:false
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
keyUsage = keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:dummy-host.com

and call all certificate generating commands with the -extfile or -config option, whichever is appropriate:

#!/bin/bash
set -e
days=100

openssl genrsa -out dummy-root.key 2048
openssl req -x509 -key dummy-root.key -out dummy-root.crt -days $days \
  -subj '/C=US/ST=TX/O=foo/OU=bar/CN=dummy-root.com' \
  -config gen.host.cfg -extensions root_exts

openssl genrsa -out dummy-class2.key 2048
openssl req -new -key dummy-class2.key -out dummy-class2.csr \
  -subj '/C=US/ST=TX/O=foo/OU=bar/CN=dummy-class2.com' 
openssl x509 -req -in dummy-class2.csr -out dummy-class2.crt -days $days \
  -CAkey dummy-root.key -CA dummy-root.crt -CAcreateserial \
  -extfile gen.host.cfg -extensions intermediate_exts

openssl genrsa -out dummy-host.key 2048
openssl req -new -key dummy-host.key -out dummy-host.csr \
  -subj '/C=US/ST=TX/O=foo/OU=bar/CN=dummy-host.com' 
openssl x509 -req -in dummy-host.csr -out dummy-host.crt -days $days \
  -CAkey dummy-class2.key -CA dummy-class2.crt -CAcreateserial \
  -extfile gen.host.cfg -extensions server_exts

rm *.csr
cat dummy-{host,class2,root}.crt > dummy-chain.crt

openssl verify -CAfile dummy-root.crt -untrusted dummy-class2.crt dummy-host.crt
openssl x509 -noout -ext extendedKeyUsage -in dummy-host.crt
1
  • Thank you very much! I like that you used a shell expansion in the chain line too :) – user1169420 Apr 1 '20 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.