skeeto / passphrase2pgp

Generate a PGP key from a passphrase
The Unlicense
187 stars 14 forks source link

feature request: generate self-signed certificate #7

Closed KAction closed 3 years ago

KAction commented 3 years ago

Subject says it all. Currently I can generate gpg key from passphrase to do signing/encryption, ssh key to authenticate to ssh server. I also have self-signed certificate that I use to authenticate myself to some web services. Would it be possible to generate SSL certificate from passphrase too?

Thank you for your work "passphrase2pgp" and "enchive". It already saved me a lot of time.

skeeto commented 3 years ago

I'm interested in supporting this. The idea of tossing out web service passwords, including password manager, and relying on my tool instead sounds very appealing.

Though, unfortunately, I have no experience with client certificates beyond knowing they exist. What web services support them, particularly self-signed certificates? I'd like something real to test against. A lesson I learned while building this tool is that there's a gap between the OpenPGP spec and what implementations actually do. When I search, all I find are crummy articles by CAs trying to sell them or instructions for how to generate them (sequences of inscrutable openssl commands) which fall short of doing something actually useful. As far as I can tell, the tooling and infrastructure are still in the stone ages, about where server certificates were a decade or more ago.

You mentioned "SSL certificate" but in an effort to be more precise this would really be an X.509 certificate, right? Which wouldn't necessarily have to do specifically with SSL or TLS. As for the encoding, it seems like the default output should be DER and --armor selects PEM. It also probably makes sense to support --protect. I have no idea how to handle the metadata (C, O, CN, etc.).

passphrase2pgp --format x509 >secret.der passphrase2pgp --format x509 --armor >secret.pem passphrase2pgp --format x509 --public >public.der passphrase2pgp --format x509 --public --armor >public.pem

KAction commented 3 years ago

Well, I am not expert either, but here is what I do:

  1. Generate certificate with following incantation:

    openssl req -nodes -x509 -newkey ed25519 \
        -keyout secret.key -out public.pem -days 3650 \
        -config /etc/ssl/openssl.cnf
  2. Configure nginx to validate certificate with following lines:

    ssl_verify_client optional;
    ssl_client_certificate  ${trusted};
    location / {
           if ($ssl_client_verify != SUCCESS) {
              return 401;
     }

I put into "trusted" concatenation of trusted certificates, essentially re-implementing ssh over ssl.

  1. Now you receive 401 to all requests unless you specify certificate with "curl -E public.pem --key secret.key".

As for meta-data, it would be enough for my needs to only fill-in email and name, exactly what we have on gpg key.

skeeto commented 3 years ago

Thanks! That will be perfect as an example and for testing.