Allow block-a-key to process private key files (#7737)
The CAB/F Debian weak keys (https://github.com/cabforum/Debian-weak-keys) repository contains a bunch of DER encoded private keys that we should ensure are blocked. I hacked up the block-a-key tool to output a base64 encoded SPKI hash from an arbitrary PEM formatted private key file.
This commit is contained in:
parent
7b032a663f
commit
56d392793a
|
@ -10,6 +10,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/privatekey"
|
||||
"github.com/letsencrypt/boulder/web"
|
||||
)
|
||||
|
||||
|
@ -29,8 +30,9 @@ installation:
|
|||
go install github.com/letsencrypt/boulder/test/block-a-key/...
|
||||
|
||||
usage:
|
||||
block-a-key -cert <PEM encoded x509 certificate file>
|
||||
block-a-key -cert <PEM formatted x509 certificate file>
|
||||
block-a-key -jwk <JSON encoded JWK file>
|
||||
block-a-key -privateKey <PEM formatted private key file>
|
||||
|
||||
output format:
|
||||
# <filepath>
|
||||
|
@ -41,10 +43,21 @@ examples:
|
|||
./test/block-a-key/test/test.ecdsa.jwk.json cuwGhNNI6nfob5aqY90e7BleU6l7rfxku4X3UTJ3Z7M=
|
||||
$> block-a-key -cert ./test/block-a-key/test/test.rsa.cert.pem
|
||||
./test/block-a-key/test/test.rsa.cert.pem Qebc1V3SkX3izkYRGNJilm9Bcuvf0oox4U2Rn+b4JOE=
|
||||
$> block-a-key -privateKey private.key
|
||||
`
|
||||
|
||||
// keyFromCert returns the public key from a PEM encoded certificate located in
|
||||
// pemFile or returns an error.
|
||||
// keyFromPrivateKeyFile returns the public key from a PEM formatted private key
|
||||
// located in pemFile or returns an error.
|
||||
func keyFromPrivateKeyFile(pemFile string) (crypto.PublicKey, error) {
|
||||
_, pubKey, err := privatekey.Load(pemFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pubKey, nil
|
||||
}
|
||||
|
||||
// keyFromCert returns the public key from a PEM formatted certificate located
|
||||
// in pemFile or returns an error.
|
||||
func keyFromCert(pemFile string) (crypto.PublicKey, error) {
|
||||
c, err := core.LoadCert(pemFile)
|
||||
if err != nil {
|
||||
|
@ -64,8 +77,9 @@ func keyFromJWK(jsonFile string) (crypto.PublicKey, error) {
|
|||
}
|
||||
|
||||
func main() {
|
||||
certFileArg := flag.String("cert", "", "path to a PEM encoded X509 certificate file")
|
||||
certFileArg := flag.String("cert", "", "path to a PEM formatted X509 certificate file")
|
||||
jwkFileArg := flag.String("jwk", "", "path to a JSON encoded JWK file")
|
||||
privKeyFileArg := flag.String("privateKey", "", "path to a PEM formatted private key file")
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "%s\n\n", usageHelp)
|
||||
|
@ -75,12 +89,12 @@ func main() {
|
|||
|
||||
flag.Parse()
|
||||
|
||||
if *certFileArg == "" && *jwkFileArg == "" {
|
||||
log.Fatalf("error: a -cert or -jwk argument must be provided")
|
||||
if *certFileArg == "" && *jwkFileArg == "" && *privKeyFileArg == "" {
|
||||
log.Fatalf("error: a -cert, -jwk, or -privateKey argument must be provided")
|
||||
}
|
||||
|
||||
if *certFileArg != "" && *jwkFileArg != "" {
|
||||
log.Fatalf("error: -cert and -jwk arguments are mutually exclusive")
|
||||
if *certFileArg != "" && *jwkFileArg != "" && *privKeyFileArg != "" {
|
||||
log.Fatalf("error: -cert, -jwk, and -privateKey arguments are mutually exclusive")
|
||||
}
|
||||
|
||||
var file string
|
||||
|
@ -93,6 +107,9 @@ func main() {
|
|||
} else if *jwkFileArg != "" {
|
||||
file = *jwkFileArg
|
||||
key, err = keyFromJWK(file)
|
||||
} else if *privKeyFileArg != "" {
|
||||
file = *privKeyFileArg
|
||||
key, err = keyFromPrivateKeyFile(file)
|
||||
} else {
|
||||
err = errors.New("unexpected command line state")
|
||||
}
|
||||
|
|
|
@ -10,10 +10,11 @@ import (
|
|||
|
||||
func TestKeyBlocking(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
certPath string
|
||||
jwkPath string
|
||||
expected string
|
||||
name string
|
||||
certPath string
|
||||
jwkPath string
|
||||
privKeyPath string
|
||||
expected string
|
||||
}{
|
||||
// NOTE(@cpu): The JWKs and certificates were generated with the same
|
||||
// keypair within an algorithm/parameter family. E.g. the RSA JWK public key
|
||||
|
@ -39,16 +40,28 @@ func TestKeyBlocking(t *testing.T) {
|
|||
certPath: "test/test.rsa.cert.pem",
|
||||
expected: "Qebc1V3SkX3izkYRGNJilm9Bcuvf0oox4U2Rn+b4JOE=",
|
||||
},
|
||||
{
|
||||
name: "P-256 ECDSA Private Key",
|
||||
privKeyPath: "../hierarchy/ee-e1.key.pem",
|
||||
expected: "ysCgov5oH7fsFs+ry0ODIx7runcINcS8V/0a0NWNQSY=",
|
||||
},
|
||||
{
|
||||
name: "2048 RSA Private Key",
|
||||
privKeyPath: "../hierarchy/ee-r4.key.pem",
|
||||
expected: "ClG5+g8ypi7kMF6mxMT+gszQbwLjPsIv9mHNVjOv4FU=",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var key crypto.PublicKey
|
||||
var err error
|
||||
if tc.jwkPath != "" {
|
||||
if tc.certPath != "" {
|
||||
key, err = keyFromCert(tc.certPath)
|
||||
} else if tc.jwkPath != "" {
|
||||
key, err = keyFromJWK(tc.jwkPath)
|
||||
} else {
|
||||
key, err = keyFromCert(tc.certPath)
|
||||
key, err = keyFromPrivateKeyFile(tc.privKeyPath)
|
||||
}
|
||||
test.AssertNotError(t, err, "error getting key from input file")
|
||||
spkiHash, err := core.KeyDigestB64(key)
|
||||
|
|
Loading…
Reference in New Issue