github.com/lmb/consul@v1.4.1/connect/certgen/certgen.go (about) 1 // certgen: a tool for generating test certificates on disk for use as 2 // test-fixtures and for end-to-end testing and local development. 3 // 4 // Example usage: 5 // 6 // $ go run connect/certgen/certgen.go -out-dir /tmp/connect-certs 7 // 8 // You can verify a given leaf with a given root using: 9 // 10 // $ openssl verify -verbose -CAfile ca2-ca.cert.pem ca1-svc-db.cert.pem 11 // 12 // Note that to verify via the cross-signed intermediate, openssl requires it to 13 // be bundled with the _root_ CA bundle and will ignore the cert if it's passed 14 // with the subject. You can do that with: 15 // 16 // $ openssl verify -verbose -CAfile \ 17 // <(cat ca1-ca.cert.pem ca2-xc-by-ca1.cert.pem) \ 18 // ca2-svc-db.cert.pem 19 // ca2-svc-db.cert.pem: OK 20 // 21 // Note that the same leaf and root without the intermediate should fail: 22 // 23 // $ openssl verify -verbose -CAfile ca1-ca.cert.pem ca2-svc-db.cert.pem 24 // ca2-svc-db.cert.pem: CN = db 25 // error 20 at 0 depth lookup:unable to get local issuer certificate 26 // 27 // NOTE: THIS IS A QUIRK OF OPENSSL; in Connect we distribute the roots alone 28 // and stable intermediates like the XC cert to the _leaf_. 29 package main // import "github.com/hashicorp/consul/connect/certgen" 30 31 import ( 32 "flag" 33 "fmt" 34 "io/ioutil" 35 "log" 36 "os" 37 38 "github.com/hashicorp/consul/agent/connect" 39 "github.com/hashicorp/consul/agent/structs" 40 "github.com/mitchellh/go-testing-interface" 41 ) 42 43 func main() { 44 var numCAs = 2 45 var services = []string{"web", "db", "cache"} 46 var outDir string 47 48 flag.StringVar(&outDir, "out-dir", "", 49 "REQUIRED: the dir to write certificates to") 50 flag.Parse() 51 52 if outDir == "" { 53 flag.PrintDefaults() 54 os.Exit(1) 55 } 56 57 // Create CA certs 58 var prevCA *structs.CARoot 59 for i := 1; i <= numCAs; i++ { 60 ca := connect.TestCA(&testing.RuntimeT{}, prevCA) 61 prefix := fmt.Sprintf("%s/ca%d-ca", outDir, i) 62 writeFile(prefix+".cert.pem", ca.RootCert) 63 writeFile(prefix+".key.pem", ca.SigningKey) 64 if prevCA != nil { 65 fname := fmt.Sprintf("%s/ca%d-xc-by-ca%d.cert.pem", outDir, i, i-1) 66 writeFile(fname, ca.SigningCert) 67 } 68 prevCA = ca 69 70 // Create service certs for each CA 71 for _, svc := range services { 72 certPEM, keyPEM := connect.TestLeaf(&testing.RuntimeT{}, svc, ca) 73 prefix := fmt.Sprintf("%s/ca%d-svc-%s", outDir, i, svc) 74 writeFile(prefix+".cert.pem", certPEM) 75 writeFile(prefix+".key.pem", keyPEM) 76 } 77 } 78 } 79 80 func writeFile(name, content string) { 81 fmt.Println("Writing ", name) 82 err := ioutil.WriteFile(name, []byte(content), 0600) 83 if err != nil { 84 log.Fatalf("failed writing file: %s", err) 85 } 86 }