4

I'm trying to create a simple Makefile command in order to install self-signed certificate for local development of an Angular app.

When I do this manually (by double-clicking on the certificate file, then opening a detail of it and setting everything to Always Trust) it works perfectly. On the other hand, the following command should do the same without any manual action, and as a matter of fact, it does (at least I couldn't find any difference in certificate details).

security add-trusted-cert -d -r trustRoot -k "/Users/${USER}/Library/Keychains/login.keychain" certificates/local.angular.domain.crt

I also tried it with a sudo command (the only difference when using sudo is that it doesn't open the native popup for password, which I prefer as the user can authenticate using a fingerprint).

Here's my whole Makefile command

install-certificate:
    # generate certificate
    git clone https://github.com/RubenVermeulen/generate-trusted-ssl-certificate.git
    cd generate-trusted-ssl-certificate && \
        sed -i.backup 's/CN.*/CN = local\.angular\.domain/g' ./openssl-custom.cnf && \
        sed -i.backup 's/DNS\.1.*/DNS\.1 = \*\.local\.angular\.domain/g' ./openssl-custom.cnf && \
        sed -i.backup 's/DNS\.2.*/DNS\.2 = local\.angular\.domain/g' ./openssl-custom.cnf && \
        bash generate.sh
    mkdir -p certificates
    mv generate-trusted-ssl-certificate/server.key certificates/local.angular.domain.key
    mv generate-trusted-ssl-certificate/server.crt certificates/local.angular.domain.crt
    rm -rf generate-trusted-ssl-certificate

    # add certificate as trusted
    security add-trusted-cert -d -r trustRoot -k "/Users/${USER}/Library/Keychains/login.keychain" certificates/local.angular.domain.crt
    grep -qxF '127.0.0.1 local.angular.domain' /etc/hosts || sudo -- sh -c "echo '127.0.0.1 local.angular.domain' >> /etc/hosts"

    # clear DNS cache
    sudo dscacheutil -flushcache
    sudo killall -HUP mDNSResponder

This should be relatively easy to replicate as it generates the certificate itself and cleans up afterwards. Might be worth mentioning that the angular app runs on port 4200 (https://local.angular.domain:4200) which works smoothly when certificate is added manually. When added by the above command it shows the NET::ERR_CERT_AUTHORITY_INVALID. When I opened both certificates' details in chrome - they are the same. Thank you for any advice.

Dawid Zbiński
  • 5,521
  • 8
  • 43
  • 70
  • Just to clarify, the command works, but it doesn't work when run as part of a Makefile? Is there any log output in the system logs or as a result of the command? (See Console.app to view system logs). – njha Dec 05 '19 at 00:01
  • The command itself works and it works in the Makefile as well, the difference here is even though it sets everything as "Always Trust" while using command, it somehow does not work and Authority is still not unknown (`NET::ERR_CERT_AUTHORITY_INVALID`). The certificate looks exactly the same when I do it manually or using script. That's what my question is, what's the difference and how comes that even though they seem to be exactly the same it doesn't trust the one signed with a command. – Dawid Zbiński Dec 05 '19 at 06:00
  • If you're on macOS, you can just run the commands above and you'll be able to generate/sign a difference. Although, in order to test it (see it's not working) you'll need a server to use those keys for communication. – Dawid Zbiński Dec 05 '19 at 06:01

1 Answers1

1

The web server needs the certificate as well as the associated private key.

But it looks like the command security add-trusted-cert does not import the private key (the .key file). You should consider using security import.

user803422
  • 2,636
  • 2
  • 18
  • 36
  • I didn't know that, but apparently I have next 18 hours to reward you with the bounty. If you have some time I'll be thankful and more than happy to reward you, if you can show me how to make it work with the `import` command. Thank you. – Dawid Zbiński Dec 10 '19 at 13:30