0

I want to create a self-signed root certificate authority, such that the certificates signed by this CA are trusted by the OS which trusts the CA.

After following a couple different guides, I managed to produce certificate authority that works in a Linux machine. However, the same generation process fails when applied to my Mac.

Below is a script (generate.sh) to generate the CA and the server certificate:

#!/bin/sh

mkdir -p ./out

# CA configuration
openssl genrsa -out ./out/CA.key 2048
openssl req -x509 \
    -new \
    -nodes \
    -key ./out/CA.key \
    -sha256 -days 365 \
    -subj "/C=NA/ST=NA/L=NA/O=org/OU=orgunit/CN=special-name"\
    -out ./out/CA.pem

# server certificate
openssl genrsa -out ./out/server.key 2048
openssl req -new -key ./out/server.key \
    -subj "/C=NA/ST=NA/L=NA/O=org/OU=orgunit/CN=special-name"\
    -out ./out/server.csr
    
echo "extendedKeyUsage = serverAuth
subjectAltName=DNS:localhost" | openssl x509 -req -in ./out/server.csr \
    -CA ./out/CA.pem \
    -CAkey ./out/CA.key \
    -CAcreateserial \
    -out ./out/server.crt \
    -days 825 \
    -sha256 \
    -extfile /dev/stdin > /dev/null

I've spent some time trying to figure out what is happening, but every solution online seems to be different.

Here is the process to generate and test the certificate:

./generate.sh
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ./out/CA.pem
docker build -t cert-test .
docker run -d -p 443:443 --name cert-test cert-test
curl https://localhost:443

The server certificates are loaded to a container made by this Dockerfile:

FROM nginx:latest

COPY ./nginx/nginx.conf /etc/nginx/conf.d/
COPY ./out/server.crt /etc/ssl/certs/
COPY ./out/server.key /etc/ssl/private

EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]

with the accompanying ./nginx/nginx.conf:

server {
    listen              443 ssl;
    server_name         localhost;
    ssl_certificate     /etc/ssl/certs/server.crt;
    ssl_certificate_key /etc/ssl/private/server.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        root    /usr/share/nginx/html;
        index   index.html index.html;
    }
}

All this is available in certificate-mess.

Expected result: curl https://localhost:443 returns the nginx welcome page.

Actual result: curl https://localhost:443 does not return the nginx welcome page, instead states the website is insecure/invalid:

curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Why does this process fail for ios/macos, and how do I resolve it? I've double-checked Requirements for trusted certificates in iOS 13 and macOS 10.15, Thanks in advance.

13
  • 2
    You only describe how you generate the certificates but not how you actually use these. How did you import these into the trust store, how did you check if it works, what exact errors you get ... Commented Nov 24, 2023 at 10:23
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Commented Nov 24, 2023 at 10:26
  • @SteffenUllrich there's quite a bit of scripts and configuration files to run a simple test case, which is why I pointed it to a repository to avoid the post from cluttering. I'll copy and paste it here then.
    – David
    Commented Nov 24, 2023 at 10:28
  • updated post for clarity.
    – David
    Commented Nov 24, 2023 at 10:36
  • 1
    You must not use the same subject for CA certificate and server certificate. This is not specific to MacOS. Apart from this change (i.e. replace CN=special-name with CN=CA) for the CA it works for me on MacOS when testing the generated server certificate with openssl s_server and using curl --cacert ... as client. Commented Nov 25, 2023 at 5:15

0

You must log in to answer this question.

Browse other questions tagged .