...

Source file src/github.com/letsencrypt/boulder/test/block-a-key/main.go

Documentation: github.com/letsencrypt/boulder/test/block-a-key

     1  // block-a-key is a small utility for creating key blocklist entries.
     2  package main
     3  
     4  import (
     5  	"crypto"
     6  	"errors"
     7  	"flag"
     8  	"fmt"
     9  	"log"
    10  	"os"
    11  
    12  	"github.com/letsencrypt/boulder/core"
    13  	"github.com/letsencrypt/boulder/web"
    14  )
    15  
    16  const usageHelp = `
    17  block-a-key is utility tool for generating a SHA256 hash of the SubjectPublicKeyInfo
    18  from a certificate or a synthetic SubjectPublicKeyInfo generated from a JWK public key.
    19  It outputs the Base64 encoding of that hash.
    20  
    21  The produced encoded digest can be used with Boulder's key blocklist to block
    22  any ACME account creation or certificate requests that use the same public
    23  key.
    24  
    25  If you already have an SPKI hash, and it's a SHA256 hash, you can add it directly
    26  to the key blocklist. If it's in hex form you'll need to convert it to base64 first.
    27  
    28  installation:
    29    go install github.com/letsencrypt/boulder/test/block-a-key/...
    30  
    31  usage:
    32    block-a-key -cert <PEM encoded x509 certificate file>
    33    block-a-key -jwk <JSON encoded JWK file>
    34  
    35  output format:
    36    # <filepath>
    37    - "<base64 encoded SHA256 subject public key digest>"
    38  
    39  examples:
    40    $> block-a-key -jwk ./test/block-a-key/test/test.ecdsa.jwk.json
    41    ./test/block-a-key/test/test.ecdsa.jwk.json	cuwGhNNI6nfob5aqY90e7BleU6l7rfxku4X3UTJ3Z7M=
    42    $> block-a-key -cert ./test/block-a-key/test/test.rsa.cert.pem
    43    ./test/block-a-key/test/test.rsa.cert.pem	Qebc1V3SkX3izkYRGNJilm9Bcuvf0oox4U2Rn+b4JOE=
    44  `
    45  
    46  // keyFromCert returns the public key from a PEM encoded certificate located in
    47  // pemFile or returns an error.
    48  func keyFromCert(pemFile string) (crypto.PublicKey, error) {
    49  	c, err := core.LoadCert(pemFile)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	return c.PublicKey, nil
    54  }
    55  
    56  // keyFromJWK returns the public key from a JSON encoded JOSE JWK located in
    57  // jsonFile or returns an error.
    58  func keyFromJWK(jsonFile string) (crypto.PublicKey, error) {
    59  	jwk, err := web.LoadJWK(jsonFile)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	return jwk.Key, nil
    64  }
    65  
    66  func main() {
    67  	certFileArg := flag.String("cert", "", "path to a PEM encoded X509 certificate file")
    68  	jwkFileArg := flag.String("jwk", "", "path to a JSON encoded JWK file")
    69  
    70  	flag.Usage = func() {
    71  		fmt.Fprintf(os.Stderr, "%s\n\n", usageHelp)
    72  		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
    73  		flag.PrintDefaults()
    74  	}
    75  
    76  	flag.Parse()
    77  
    78  	if *certFileArg == "" && *jwkFileArg == "" {
    79  		log.Fatalf("error: a -cert or -jwk argument must be provided")
    80  	}
    81  
    82  	if *certFileArg != "" && *jwkFileArg != "" {
    83  		log.Fatalf("error: -cert and -jwk arguments are mutually exclusive")
    84  	}
    85  
    86  	var file string
    87  	var key crypto.PublicKey
    88  	var err error
    89  
    90  	if *certFileArg != "" {
    91  		file = *certFileArg
    92  		key, err = keyFromCert(file)
    93  	} else if *jwkFileArg != "" {
    94  		file = *jwkFileArg
    95  		key, err = keyFromJWK(file)
    96  	} else {
    97  		err = errors.New("unexpected command line state")
    98  	}
    99  	if err != nil {
   100  		log.Fatalf("error loading public key: %v", err)
   101  	}
   102  
   103  	spkiHash, err := core.KeyDigestB64(key)
   104  	if err != nil {
   105  		log.Fatalf("error computing spki hash: %v", err)
   106  	}
   107  	fmt.Printf("  # %s\n  - %s\n", file, spkiHash)
   108  }
   109  

View as plain text