Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions ca/certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ func GetRemoteCA(ctx context.Context, d digest.Digest, connBroker *connectionbro

// CreateRootCA creates a Certificate authority for a new Swarm Cluster, potentially
// overwriting any existing CAs.
func CreateRootCA(rootCN string, paths CertPaths) (RootCA, error) {
func CreateRootCA(rootCN string) (RootCA, error) {
// Create a simple CSR for the CA using the default CA validator and policy
req := cfcsr.CertificateRequest{
CN: rootCN,
Expand All @@ -764,11 +764,6 @@ func CreateRootCA(rootCN string, paths CertPaths) (RootCA, error) {
return RootCA{}, err
}

// save the cert to disk
if err := saveRootCA(rootCA, paths); err != nil {
return RootCA{}, err
}

return rootCA, nil
}

Expand Down Expand Up @@ -872,7 +867,8 @@ func readCertValidity(kr KeyReader) (time.Time, time.Time, error) {

}

func saveRootCA(rootCA RootCA, paths CertPaths) error {
// SaveRootCA saves a RootCA object to disk
func SaveRootCA(rootCA RootCA, paths CertPaths) error {
// Make sure the necessary dirs exist and they are writable
err := os.MkdirAll(filepath.Dir(paths.Cert), 0755)
if err != nil {
Expand Down
61 changes: 18 additions & 43 deletions ca/certificates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,17 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}

func TestCreateRootCA(t *testing.T) {
func TestCreateRootCASaveRootCA(t *testing.T) {
tempBaseDir, err := ioutil.TempDir("", "swarm-ca-test-")
assert.NoError(t, err)
defer os.RemoveAll(tempBaseDir)

paths := ca.NewConfigPaths(tempBaseDir)

_, err = ca.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)

err = ca.SaveRootCA(rootCA, paths.RootCA)
assert.NoError(t, err)

perms, err := permbits.Stat(paths.RootCA.Cert)
Expand All @@ -80,13 +83,7 @@ func TestCreateRootCA(t *testing.T) {
}

func TestCreateRootCAExpiry(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.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)

// Convert the certificate into an object to create a RootCA
Expand All @@ -95,7 +92,6 @@ func TestCreateRootCAExpiry(t *testing.T) {
duration, err := time.ParseDuration(ca.RootCAExpiration)
assert.NoError(t, err)
assert.True(t, time.Now().Add(duration).AddDate(0, -1, 0).Before(parsedCert.NotAfter))

}

func TestGetLocalRootCA(t *testing.T) {
Expand All @@ -110,10 +106,12 @@ func TestGetLocalRootCA(t *testing.T) {
assert.Equal(t, ca.ErrNoLocalRootCA, err)

// Create the local Root CA to ensure that we can reload it correctly.
rootCA, err := ca.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)
s, err := rootCA.Signer()
assert.NoError(t, err)
err = ca.SaveRootCA(rootCA, paths.RootCA)
assert.NoError(t, err)

// No private key here
rootCA2, err := ca.GetLocalRootCA(paths.RootCA)
Expand Down Expand Up @@ -168,8 +166,9 @@ func TestGetLocalRootCAInvalidKey(t *testing.T) {

paths := ca.NewConfigPaths(tempBaseDir)
// Create the local Root CA to ensure that we can reload it correctly.
_, err = ca.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
require.NoError(t, err)
require.NoError(t, ca.SaveRootCA(rootCA, paths.RootCA))

// Write some garbage to the root key - this will cause the loading to fail
require.NoError(t, ioutil.WriteFile(paths.RootCA.Key, []byte(`-----BEGIN EC PRIVATE KEY-----\n
Expand Down Expand Up @@ -197,13 +196,7 @@ func TestEncryptECPrivateKey(t *testing.T) {
}

func TestParseValidateAndSignCSR(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.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)

csr, _, err := ca.GenerateNewCSR()
Expand All @@ -217,13 +210,7 @@ func TestParseValidateAndSignCSR(t *testing.T) {
}

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.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)

req := &cfcsr.CertificateRequest{
Expand Down Expand Up @@ -271,8 +258,7 @@ func TestGetRemoteCA(t *testing.T) {
require.NoError(t, err)
defer os.RemoveAll(tmpDir)
paths := ca.NewConfigPaths(tmpDir)

otherRootCA, err := ca.CreateRootCA("other", paths.RootCA)
otherRootCA, err := ca.CreateRootCA("other")
require.NoError(t, err)

comboCertBundle := append(tc.RootCA.Certs, otherRootCA.Certs...)
Expand Down Expand Up @@ -555,11 +541,11 @@ func TestNewRootCABundle(t *testing.T) {
paths := ca.NewConfigPaths(tempBaseDir)

// make one rootCA
secondRootCA, err := ca.CreateRootCA("rootCN2", paths.RootCA)
firstRootCA, err := ca.CreateRootCA("rootCN1")
assert.NoError(t, err)

// make a second root CA
firstRootCA, err := ca.CreateRootCA("rootCN1", paths.RootCA)
secondRootCA, err := ca.CreateRootCA("rootCN2")
assert.NoError(t, err)
s, err := firstRootCA.Signer()
require.NoError(t, err)
Expand All @@ -585,13 +571,7 @@ func TestNewRootCABundle(t *testing.T) {
}

func TestNewRootCANonDefaultExpiry(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.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)
s, err := rootCA.Signer()
require.NoError(t, err)
Expand Down Expand Up @@ -887,15 +867,10 @@ func TestRootCAWithCrossSignedIntermediates(t *testing.T) {
}

func TestNewRootCAWithPassphrase(t *testing.T) {
tempBaseDir, err := ioutil.TempDir("", "swarm-ca-test-")
assert.NoError(t, err)
defer os.RemoveAll(tempBaseDir)
defer os.Setenv(ca.PassphraseENVVar, "")
defer os.Setenv(ca.PassphraseENVVarPrev, "")

paths := ca.NewConfigPaths(tempBaseDir)

rootCA, err := ca.CreateRootCA("rootCN", paths.RootCA)
rootCA, err := ca.CreateRootCA("rootCN")
assert.NoError(t, err)
rcaSigner, err := rootCA.Signer()
assert.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion ca/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func DownloadRootCA(ctx context.Context, paths CertPaths, token string, connBrok
}

// Save root CA certificate to disk
if err = saveRootCA(rootCA, paths); err != nil {
if err = SaveRootCA(rootCA, paths); err != nil {
return RootCA{}, err
}

Expand Down
6 changes: 3 additions & 3 deletions ca/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestNewMutableTLS(t *testing.T) {
paths := NewConfigPaths(tempdir)
krw := NewKeyReadWriter(paths.Node, nil, nil)

rootCA, err := CreateRootCA("rootCN", paths.RootCA)
rootCA, err := CreateRootCA("rootCN")
require.NoError(t, err)

cert, err := rootCA.IssueAndSaveNewCertificates(krw, "CN", ManagerRole, "org")
Expand All @@ -38,7 +38,7 @@ func TestGetAndValidateCertificateSubject(t *testing.T) {
paths := NewConfigPaths(tempdir)
krw := NewKeyReadWriter(paths.Node, nil, nil)

rootCA, err := CreateRootCA("rootCN", paths.RootCA)
rootCA, err := CreateRootCA("rootCN")
require.NoError(t, err)

cert, err := rootCA.IssueAndSaveNewCertificates(krw, "CN", ManagerRole, "org")
Expand All @@ -58,7 +58,7 @@ func TestLoadNewTLSConfig(t *testing.T) {
paths := NewConfigPaths(tempdir)
krw := NewKeyReadWriter(paths.Node, nil, nil)

rootCA, err := CreateRootCA("rootCN", paths.RootCA)
rootCA, err := CreateRootCA("rootCN")
require.NoError(t, err)

// Create two different certs and two different TLS configs
Expand Down
7 changes: 5 additions & 2 deletions cmd/external-ca-example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ func main() {
}

// Initialize the Root CA.
rootCA, err := ca.CreateRootCA("external-ca-example", rootPaths)
rootCA, err := ca.CreateRootCA("external-ca-example")
if err != nil {
logrus.Fatalf("unable to initialize Root CA: %s", err)
logrus.Fatalf("unable to initialize Root CA: %s", err.Error())
}
if err := ca.SaveRootCA(rootCA, rootPaths); err != nil {
logrus.Fatalf("unable to save Root CA: %s", err.Error())
}

// Create the initial manager node credentials.
Expand Down
5 changes: 1 addition & 4 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,7 @@ func TestForceNewCluster(t *testing.T) {
t.Parallel()

// create an external CA so that we can use it to generate expired certificates
tempDir, err := ioutil.TempDir("", "external-ca")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
rootCA, err := ca.CreateRootCA("externalRoot", ca.NewConfigPaths(tempDir).RootCA)
rootCA, err := ca.CreateRootCA("externalRoot")
require.NoError(t, err)

// start a new cluster with the external CA bootstrapped
Expand Down
5 changes: 4 additions & 1 deletion node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,10 +600,13 @@ func (n *Node) loadSecurityConfig(ctx context.Context) (*ca.SecurityConfig, erro
n.unlockKey = encryption.GenerateSecretKey()
}
krw = ca.NewKeyReadWriter(paths.Node, n.unlockKey, &manager.RaftDEKData{})
rootCA, err = ca.CreateRootCA(ca.DefaultRootCN, paths.RootCA)
rootCA, err = ca.CreateRootCA(ca.DefaultRootCN)
if err != nil {
return nil, err
}
if err := ca.SaveRootCA(rootCA, paths.RootCA); err != nil {
return nil, err
}
log.G(ctx).Debug("generated CA key and certificate")
} else if err == ca.ErrNoLocalRootCA { // from previous error loading the root CA from disk
rootCA, err = ca.DownloadRootCA(ctx, paths.RootCA, n.config.JoinToken, n.connBroker)
Expand Down
10 changes: 7 additions & 3 deletions node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ func TestLoadSecurityConfigPartialCertsOnDisk(t *testing.T) {
defer os.RemoveAll(tempdir)

paths := ca.NewConfigPaths(filepath.Join(tempdir, "certificates"))
rootCA, err := ca.CreateRootCA(ca.DefaultRootCN, paths.RootCA)
rootCA, err := ca.CreateRootCA(ca.DefaultRootCN)
require.NoError(t, err)
require.NoError(t, ca.SaveRootCA(rootCA, paths.RootCA))

node, err := New(&Config{
StateDir: tempdir,
Expand Down Expand Up @@ -105,8 +106,10 @@ func TestLoadSecurityConfigLoadFromDisk(t *testing.T) {
require.NoError(t, err)

// Load successfully with valid passphrase
rootCA, err := ca.CreateRootCA(ca.DefaultRootCN, paths.RootCA)
rootCA, err := ca.CreateRootCA(ca.DefaultRootCN)
require.NoError(t, err)
require.NoError(t, ca.SaveRootCA(rootCA, paths.RootCA))

krw := ca.NewKeyReadWriter(paths.Node, []byte("passphrase"), nil)
require.NoError(t, err)
_, err = rootCA.IssueAndSaveNewCertificates(krw, identity.NewID(), ca.WorkerRole, identity.NewID())
Expand Down Expand Up @@ -134,8 +137,9 @@ func TestLoadSecurityConfigLoadFromDisk(t *testing.T) {
require.Equal(t, ErrInvalidUnlockKey, err)

// Invalid CA
rootCA, err = ca.CreateRootCA(ca.DefaultRootCN, paths.RootCA)
rootCA, err = ca.CreateRootCA(ca.DefaultRootCN)
require.NoError(t, err)
require.NoError(t, ca.SaveRootCA(rootCA, paths.RootCA))
node, err = New(&Config{
StateDir: tempdir,
JoinAddr: peer.Addr,
Expand Down