skeeto / passphrase2pgp

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

New output format: tls (Closes: #7) #8

Closed KAction closed 3 years ago

KAction commented 3 years ago

Introduce feature to generate self-signed TLS certificate from passphrase.

KAction commented 3 years ago

FWIW: I replaced my previous certificate with one generate with this code, and so far both nginx and openvpn are fine with that.

skeeto commented 3 years ago

Thanks! I think this is about 90% of the way there. I have a modified version of your patch in my x509 branch (56df9d0) with these changes:

While an obvious choice, the PGP key ID might be the wrong choice for the serial number. Per the OpenPGP spec it's derived from the (public key, creation date) tuple, but the creation date component is actually rather inconvenient. I'm considering just hashing the public key by itself to derive a 20-octet serial number.

Thoughts?

KAction commented 3 years ago
skeeto commented 3 years ago

key.Created() defaults to unix epoch 0 just like you had hardcoded for NotBefore, so the default remains deterministic and unchanged. If it defaulted to time.Now() then PGP key IDs wouldn't be stable. The --now (-n) option causes it to use the current time, though this has limited usefulness for PGP. Here's an example key created on my branch that's dated to the beginning of this year:

$ env - ./passphrase2pgp -u example -f x509 -i /dev/null -t $(date -ud 2021-01-01 +%s) | openssl x509 -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            5f:11:0c:47:28:97:ea:0e:96:80:97:eb:7f:21:6d:70:1c:80:c5:52
        Signature Algorithm: ED25519
        Issuer: CN = example
        Validity
            Not Before: Jan  1 00:00:00 2021 GMT
            Not After : Dec 31 23:59:59 9999 GMT
        Subject: CN = example
        Subject Public Key Info:
            Public Key Algorithm: ED25519
                ED25519 Public-Key:
                pub:
                    f0:6f:30:a5:df:7a:83:bb:c2:61:97:60:68:c7:96:
                    37:76:98:75:b4:86:48:1a:98:5f:37:4c:e8:9e:3f:
                    0f:e8
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
    Signature Algorithm: ED25519
         a1:90:c7:49:b6:bd:13:4f:f6:b5:a3:73:32:0d:46:15:a8:d3:
         ef:e4:0a:35:a5:f2:f5:8c:e5:48:d7:41:71:cd:d2:80:6a:11:
         61:63:30:1a:12:e5:c4:8d:b6:b5:20:0e:a4:1f:2a:d2:54:8b:
         3c:80:0b:ba:83:40:47:c2:7c:0d
-----BEGIN CERTIFICATE-----
MIH3MIGqoAMCAQICFF8RDEcol+oOloCX638hbXAcgMVSMAUGAytlcDASMRAwDgYD
VQQDEwdleGFtcGxlMCAXDTIxMDEwMTAwMDAwMFoYDzk5OTkxMjMxMjM1OTU5WjAS
MRAwDgYDVQQDEwdleGFtcGxlMCowBQYDK2VwAyEA8G8wpd96g7vCYZdgaMeWN3aY
dbSGSBqYXzdM6J4/D+ijEDAOMAwGA1UdEwEB/wQCMAAwBQYDK2VwA0EAoZDHSba9
E0/2taNzMg1GFajT7+QKNaXy9YzlSNdBcc3SgGoRYWMwGhLlxI22tSAOpB8q0lSL
PIALuoNAR8J8DQ==
-----END CERTIFICATE-----

If you run this command yourself you'll get exactly the same output. The serial number is the same as the PGP key ID for the same key. Currently if you change the date the serial number changes but the key material remains the same. Now that I've thought more, by the time I submit this I'm going to change it so that the serial number depends only on the key material (1ec43b7).

Some software, even including older versions of GnuPG, treats a zero date as null/special, and so certificates with zero dates confuses such software. Sometimes they fail closed ("invalid certificate" error for a valid certificate), and, alarmily, sometimes they fail open (zero means ignore expiry). It's handy to be able to set a custom value.

I do not understand problems of using constant certificate serial number.

Serial numbers are supposed to be unique within a CA. Suppose for instance you wanted to create two different certificates for the same --uid by using two different passphrases. Both will be serial number 1 from the same issuer, so they would definitely be in conflict. With my change they have globally unique serial numbers.

But even outside of that I know from experience that OpenSSL will abort loading two different CA certificates with the same serial number (e.g. the EV and non-EV certificates for the same subject). I don't have any experience with client certificates (and I don't know how to make OpenSSL use them for anything) so I don't know the failure modes for them.

KAction commented 3 years ago

Thanks for explanation. Now I have no concerns. Can you please cut new release after you include this new feature? I'd like to get this feature into distribution.

skeeto commented 3 years ago

Merged as 668f964, tagged as v1.2.0. Thanks, Dmitry!