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 }