Expecting: CERTIFICATE REQUEST while setting up an intermediate certificate

I’m trying to setup a PKI based on a CA root and CA intermediary.

I have scripts/generateServerCARoot.sh which creates the CA root:

##!/usr/bin/env bash
set -xeuo pipefail

CA_DIR=server/generated/ca-root
REQ_DIR=server/requests

mkdir -p $CA_DIR
touch $CA_DIR/ca.index
openssl rand -hex 16 > $CA_DIR/ca.serial

mkdir "$CA_DIR/certs" "$CA_DIR/newcerts" "$CA_DIR/private"



openssl genpkey -algorithm RSA -aes-256-cbc -out "$CA_DIR/private/ca.key.pem" -pkeyopt rsa_keygen_bits:4096
chmod 400 "$CA_DIR/private/ca.key.pem"

openssl req -new -out "$CA_DIR/certs/ca.cert.pem" -config "$CA_DIR/ca.conf" -x509 -days 365 -key "$CA_DIR/private/ca.key.pem"

openssl x509 -in "$CA_DIR/certs/ca.cert.pem" -out "$CA_DIR/ca.pem" -outform PEM

With the configuration (server/generated/ca-intermediate/ca.conf):

[ req ]
default_bits = 4096
encrypt_key = yes
default_md = sha256
string_mask = utf8only
utf8 = yes
prompt = no
x509_extensions = x509_ext
distinguished_name = distinguished_name

[ x509_ext ]
basicConstraints = critical, CA:true
nameConstraints = critical, @name_constraints
subjectKeyIdentifier = hash
issuerAltName = issuer:copy
authorityKeyIdentifier = keyid:always, issuer:always

keyUsage = digitalSignature, keyCertSign, cRLSign

[ distinguished_name ]
commonName = Barracuda Root Certificate Authority

[ ca ]
default_ca = CA_default

[ CA_default ]
base_dir = server/generated/ca-intermediate
database = $base_dir/ca.index
serial = $base_dir/ca.serial
certs = $base_dir/certs
new_certs_dir = $base_dir/newcerts
default_md = sha256
default_days = 365
email_in_dn = no
copy_extensions = copy
uniqueSubject = no




policy = root_ca_policy
private_key = $base_dir/private/ca.key.pem
certificate = $base_dir/certs/ca.cert.pem

[ ca_policy ]
countryName = supplied
stateOrProvinceName = supplied
localityName = supplied
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = supplied

[ root_ca_policy ]
countryName = match
stateOrProvinceName = match
localityName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ intermediate_ca_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ server_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional


[ name_constraints ]
permitted;DNS.0 = srv.local


It runs without errors.

Then I want to create and sign my CA intermediary scripts/generateServerCAIntermediate.sh:

##!/usr/bin/env bash
set -xeuo pipefail

CA_ROOT_DIR=server/generated/ca-root
CA_DIR=server/generated/ca-intermediate
REQ_DIR=server/requests

mkdir -p $CA_DIR
touch $CA_DIR/ca.index
openssl rand -hex 16 > $CA_DIR/ca.serial

mkdir "$CA_DIR/certs" "$CA_DIR/newcerts" "$CA_DIR/private"



openssl genpkey -algorithm RSA -aes-256-cbc -out "$CA_DIR/private/ca.key.pem" -pkeyopt rsa_keygen_bits:4096
chmod 400 "$CA_DIR/private/ca.key.pem"

openssl req -new -out "$CA_DIR/certs/ca.csr.pem" -config "$CA_DIR/ca.conf" -x509 -days 365 -key "$CA_DIR/private/ca.key.pem"



# openssl ca -out "$CA_DIR/certs/ca.cert.pem" -config "$CA_DIR/sign-ca.conf" -extensions x509_ext -days 32 -notext -key "$CA_DIR/certs/ca.csr.pem"

# openssl x509 -req -out "$CA_DIR/certs/ca.cert.pem" -CA "$CA_DIR/sign-ca.conf" -days 32 -in "$CA_DIR/certs/ca.csr.pem"

openssl ca -batch -config "$CA_DIR/sign-ca.conf" -notext -in "$CA_DIR/certs/ca.csr.pem" -out "$CA_DIR/certs/ca.cert.pem"


openssl x509 -in "$CA_DIR/certs/ca.cert.pem" -out "$CA_DIR/ca.pem" -outform PEM

echo "Copy '$CA_DIR/ca.pem' to srv@/etc/nixos/certificates/.../ca.pem"

With the intermediate CA (server/generated/ca-root/ca.conf):

[ req ]
default_bits = 4096
encrypt_key = yes
default_md = sha256
string_mask = utf8only
utf8 = yes
prompt = no
x509_extensions = x509_ext
distinguished_name = distinguished_name

[ x509_ext ]
basicConstraints = critical, CA:true
nameConstraints = critical, @name_constraints
subjectKeyIdentifier = hash
issuerAltName = issuer:copy
authorityKeyIdentifier = keyid:always, issuer:always

keyUsage = digitalSignature, keyCertSign, cRLSign

[ distinguished_name ]
commonName = Barracuda Root Certificate Authority

[ ca ]
default_ca = CA_default

[ CA_default ]
base_dir = server/generated/ca-root
database = $base_dir/ca.index
serial = $base_dir/ca.serial
certs = $base_dir/certs
new_certs_dir = $base_dir/newcerts
default_md = sha256
default_days = 365
email_in_dn = no
copy_extensions = copy
uniqueSubject = no




policy = root_ca_policy
private_key = $base_dir/private/ca.key.pem
certificate = $base_dir/certs/ca.cert.pem

[ ca_policy ]
countryName = supplied
stateOrProvinceName = supplied
localityName = supplied
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = supplied

[ root_ca_policy ]
countryName = match
stateOrProvinceName = match
localityName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ intermediate_ca_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ server_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional


[ name_constraints ]
permitted;DNS.0 = srv.local


And finally the configuration used to sign the intermediate CA (server/generated/ca-intermediate/sign-ca.conf):

[ req ]
default_bits = 4096
encrypt_key = yes
default_md = sha256
string_mask = utf8only
utf8 = yes
prompt = no
x509_extensions = x509_ext
distinguished_name = distinguished_name

[ x509_ext ]
basicConstraints = critical, CA:true, pathlen:0
nameConstraints = critical, @name_constraints
subjectKeyIdentifier = hash
issuerAltName = issuer:copy
authorityKeyIdentifier = keyid:always, issuer:always

keyUsage = digitalSignature, keyCertSign, cRLSign

[ distinguished_name ]
commonName = Barracuda Intermediate Certificate Authority

[ ca ]
default_ca = CA_default

[ CA_default ]
base_dir = server/generated/ca-root
database = $base_dir/ca.index
serial = $base_dir/ca.serial
certs = $base_dir/certs
new_certs_dir = $base_dir/newcerts
default_md = sha256
default_days = 32
email_in_dn = no
copy_extensions = copy
uniqueSubject = no




policy = intermediate_ca_policy
private_key = $base_dir/private/ca.key.pem
certificate = $base_dir/certs/ca.cert.pem

[ ca_policy ]
countryName = supplied
stateOrProvinceName = supplied
localityName = supplied
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = supplied

[ root_ca_policy ]
countryName = match
stateOrProvinceName = match
localityName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ intermediate_ca_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ server_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional


[ name_constraints ]
permitted;DNS.0 = srv.local

However, it fails on signing the intermediate CA:

+ openssl ca -batch -config server/generated/ca-intermediate/sign-ca.conf -notext -in server/generated/ca-intermediate/certs/ca.csr.pem -out server/generated/ca-intermediate/certs/ca.cert.pem
Using configuration from server/generated/ca-intermediate/sign-ca.conf
Enter pass phrase for server/generated/ca-root/private/ca.key.pem:
Error reading certificate request in server/generated/ca-intermediate/certs/ca.csr.pem
140263254656832:error:09FFF06C:PEM routines:CRYPTO_internal:no start line:/build/libressl-3.7.3/crypto/pem/pem_lib.c:694:Expecting: CERTIFICATE REQUEST

I don’t know why server/generated/ca-intermediate/certs/ca.csr.pem is not a certificate, while I used openssl req -new.

Which step did I miss?

  • You used openssl req -new ... -x509 ... which generates a self-signed cert, NOT a CSR which is what you want. Once you remove -x509 you should remove -days 32 because a CSR has no time period; only a cert does that. In addition you have the subject name of the intermediate CA the same as the root CA which will make this cert unusable because reliers will think it is self-signed (even if it’s not). Also I’m skeptical this is programming or development (although in a script) so not officially answering.

    – 




Leave a Comment