func initializeServer() *server.Server { var hosts string fmt.Print("Keyserver Hostnames/IPs (comma-seperated): ") fmt.Scanln(&hosts) hostnames := strings.Split(hosts, ",") csr, key, err := csr.ParseRequest(&csr.CertificateRequest{ CN: "Keyless Server Authentication Certificate", Hosts: hostnames, KeyRequest: &csr.BasicKeyRequest{ A: "ecdsa", S: 384, }, }) if err != nil { log.Fatal(err) } if err := ioutil.WriteFile(keyFile, key, 0400); err != nil { log.Fatal(err) } log.Infof("Key generated and saved to %s\n", keyFile) log.Info("Server entering initialization state") s, err := server.NewServerFromFile(initCertFile, initKeyFile, caFile, net.JoinHostPort("", port), net.JoinHostPort("", metricsPort)) if err != nil { log.Fatal(err) } s.ActivationToken = []byte(initToken) go func() { log.Fatal(s.ListenAndServe()) }() cert, err := initAPICall(hostnames, string(csr)) if err != nil { log.Fatal(err) } if err := ioutil.WriteFile(certFile, cert, 0644); err != nil { log.Fatal(err) } log.Infof("Cert saved to %s\n", certFile) // Remove server from activation state and initialize issued certificate. s.ActivationToken = s.ActivationToken[:0] tlsCert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { log.Fatal(err) } s.Config.Certificates = []tls.Certificate{tlsCert} return s }
// GenerateNewCSR returns a newly generated key and CSR signed with said key func GenerateNewCSR() (csr, key []byte, err error) { req := &cfcsr.CertificateRequest{ KeyRequest: cfcsr.NewBasicKeyRequest(), } csr, key, err = cfcsr.ParseRequest(req) if err != nil { return } return }
func generateNewCSR() (csr, key []byte, err error) { req := &cfcsr.CertificateRequest{ KeyRequest: cfcsr.NewBasicKeyRequest(), } csr, key, err = cfcsr.ParseRequest(req) if err != nil { log.Debugf(`failed to generate CSR`) return } return }
func testGenerateKeypair(req *csr.CertificateRequest) (keyFile, certFile string, err error) { fail := func(err error) (string, string, error) { if keyFile != "" { os.Remove(keyFile) } if certFile != "" { os.Remove(certFile) } return "", "", err } keyFile, err = tempName() if err != nil { return fail(err) } certFile, err = tempName() if err != nil { return fail(err) } csrPEM, keyPEM, err := csr.ParseRequest(req) if err != nil { return fail(err) } if err = ioutil.WriteFile(keyFile, keyPEM, 0644); err != nil { return fail(err) } priv, err := helpers.ParsePrivateKeyPEM(keyPEM) if err != nil { return fail(err) } cert, err := selfsign.Sign(priv, csrPEM, config.DefaultConfig()) if err != nil { return fail(err) } if err = ioutil.WriteFile(certFile, cert, 0644); err != nil { return fail(err) } return }
func TestParseValidateAndSignMaliciousCSR(t *testing.T) { tempBaseDir, err := ioutil.TempDir("", "swarm-ca-test-") assert.NoError(t, err) defer os.RemoveAll(tempBaseDir) paths := ca.NewConfigPaths(tempBaseDir) rootCA, err := ca.CreateAndWriteRootCA("rootCN", paths.RootCA) assert.NoError(t, err) req := &cfcsr.CertificateRequest{ Names: []cfcsr.Name{ { O: "maliciousOrg", OU: "maliciousOU", L: "maliciousLocality", }, }, CN: "maliciousCN", Hosts: []string{"docker.com"}, KeyRequest: &cfcsr.BasicKeyRequest{A: "ecdsa", S: 256}, } csr, _, err := cfcsr.ParseRequest(req) assert.NoError(t, err) signedCert, err := rootCA.ParseValidateAndSignCSR(csr, "CN", "OU", "ORG") assert.NoError(t, err) assert.NotNil(t, signedCert) parsedCert, err := helpers.ParseCertificatesPEM(signedCert) assert.NoError(t, err) assert.Equal(t, 2, len(parsedCert)) assert.Equal(t, "CN", parsedCert[0].Subject.CommonName) assert.Equal(t, 1, len(parsedCert[0].Subject.OrganizationalUnit)) assert.Equal(t, "OU", parsedCert[0].Subject.OrganizationalUnit[0]) assert.Equal(t, 3, len(parsedCert[0].Subject.Names)) assert.Empty(t, parsedCert[0].Subject.Locality) assert.Equal(t, "ORG", parsedCert[0].Subject.Organization[0]) assert.Equal(t, "rootCN", parsedCert[1].Subject.CommonName) }
func TestNewSigner(t *testing.T) { req := ExampleRequest() lca, err := New(req, ExampleSigningConfig()) assert.NoErrorT(t, err) csrPEM, _, err := csr.ParseRequest(testRequest) assert.NoErrorT(t, err) certPEM, err := lca.SignCSR(csrPEM) assert.NoErrorT(t, err) _, err = helpers.ParseCertificatePEM(certPEM) assert.NoErrorT(t, err) certPEM, err = lca.CACertificate() assert.NoErrorT(t, err) cert, err := helpers.ParseCertificatePEM(certPEM) assert.NoErrorT(t, err) assert.BoolT(t, cert.Subject.CommonName == req.CN, "common names don't match") lca.Toggle() _, err = lca.SignCSR(csrPEM) assert.ErrorEqT(t, errDisabled, err) lca.Toggle() _, err = lca.SignCSR(certPEM) assert.ErrorT(t, err, "shouldn't be able to sign non-CSRs") p := &pem.Block{ Type: "CERTIFICATE REQUEST", Bytes: []byte(`¯\_(ツ)_/¯`), } junkCSR := pem.EncodeToMemory(p) _, err = lca.SignCSR(junkCSR) assert.ErrorT(t, err, "signing a junk CSR should fail") t.Logf("error: %s", err) }
func genSecurityConfig(s *store.MemoryStore, rootCA ca.RootCA, role, org, tmpDir string, nonSigningRoot bool) (*ca.SecurityConfig, error) { req := &cfcsr.CertificateRequest{ KeyRequest: cfcsr.NewBasicKeyRequest(), } csr, key, err := cfcsr.ParseRequest(req) if err != nil { return nil, err } // Obtain a signed Certificate nodeID := identity.NewID() // All managers get added the subject-alt-name of CA, so they can be used for cert issuance hosts := []string{role} if role == ca.ManagerRole { hosts = append(hosts, ca.CARole) } cert, err := rootCA.Signer.Sign(cfsigner.SignRequest{ Request: string(csr), // OU is used for Authentication of the node type. The CN has the random // node ID. Subject: &cfsigner.Subject{CN: nodeID, Names: []cfcsr.Name{{OU: role, O: org}}}, // Adding ou as DNS alt name, so clients can connect to ManagerRole and CARole Hosts: hosts, }) if err != nil { return nil, err } // Append the root CA Key to the certificate, to create a valid chain certChain := append(cert, rootCA.Cert...) // If we were instructed to persist the files if tmpDir != "" { paths := ca.NewConfigPaths(tmpDir) if err := ioutil.WriteFile(paths.Node.Cert, certChain, 0644); err != nil { return nil, err } if err := ioutil.WriteFile(paths.Node.Key, key, 0600); err != nil { return nil, err } } // Load a valid tls.Certificate from the chain and the key nodeCert, err := tls.X509KeyPair(certChain, key) if err != nil { return nil, err } nodeServerTLSCreds, err := rootCA.NewServerTLSCredentials(&nodeCert) if err != nil { return nil, err } nodeClientTLSCreds, err := rootCA.NewClientTLSCredentials(&nodeCert, ca.ManagerRole) if err != nil { return nil, err } err = createNode(s, nodeID, role, csr, cert) if err != nil { return nil, err } if nonSigningRoot { rootCA = ca.RootCA{ Cert: rootCA.Cert, Digest: rootCA.Digest, Pool: rootCA.Pool, } } return ca.NewSecurityConfig(&rootCA, nodeClientTLSCreds, nodeServerTLSCreds), nil }
func main() { if initCert { var hosts string fmt.Print("Keyserver Hostnames/IPs (comma-seperated): ") fmt.Scanln(&hosts) csr, key, err := csr.ParseRequest(&csr.CertificateRequest{ CN: "Keyless Server Authentication Certificate", Hosts: strings.Split(hosts, ","), KeyRequest: &csr.KeyRequest{Algo: "ecdsa", Size: 384}, }) if err != nil { log.Fatal(err) } if err := ioutil.WriteFile(keyFile, key, 0400); err != nil { log.Fatal(err) } fmt.Printf("Key generated and saved to %s\n", keyFile) fmt.Printf("Email this CSR to [email protected] for signing and save the resulting certificate to %s:\n", certFile) fmt.Print(string(csr)) return } s, err := server.NewServerFromFile(certFile, keyFile, caFile, net.JoinHostPort("", port), net.JoinHostPort("", metricsPort)) if err != nil { log.Warningf("Could not create server. Run `gokeyless -init` to get %s and %s", keyFile, certFile) log.Fatal(err) } if err := s.LoadKeysFromDir(keyDir, LoadKey); err != nil { log.Fatal(err) } // Start server in background, then listen for SIGHUPs to reload keys. go func() { log.Fatal(s.ListenAndServe()) }() if pidFile != "" { if f, err := os.Create(pidFile); err != nil { log.Errorf("error creating pid file: %v", err) } else { fmt.Fprintf(f, "%d", os.Getpid()) f.Close() } } c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP) for { select { case <-c: log.Info("Received SIGHUP, reloading keys...") if err := s.LoadKeysFromDir(keyDir, LoadKey); err != nil { log.Fatal(err) } } } }