Exemple #1
0
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
}
Exemple #2
0
// 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
}
Exemple #3
0
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
}
Exemple #5
0
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)
}
Exemple #7
0
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
}
Exemple #8
0
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)
			}
		}
	}
}