github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/security/certificate_manager_test.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package security_test 12 13 import ( 14 "fmt" 15 "io/ioutil" 16 "os" 17 "path/filepath" 18 "strings" 19 "testing" 20 "time" 21 22 "github.com/cockroachdb/cockroach/pkg/security" 23 "github.com/cockroachdb/cockroach/pkg/util/envutil" 24 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 25 "github.com/stretchr/testify/require" 26 ) 27 28 func TestManagerWithEmbedded(t *testing.T) { 29 defer leaktest.AfterTest(t)() 30 cm, err := security.NewCertificateManager("test_certs") 31 if err != nil { 32 t.Error(err) 33 } 34 35 // Verify loaded certs. 36 if cm.CACert() == nil { 37 t.Error("expected non-nil CACert") 38 } 39 if cm.NodeCert() == nil { 40 t.Error("expected non-nil NodeCert") 41 } 42 clientCerts := cm.ClientCerts() 43 if a, e := len(clientCerts), 2; a != e { 44 t.Errorf("expected %d client certs, found %d", e, a) 45 } 46 47 if _, ok := clientCerts[security.RootUser]; !ok { 48 t.Error("no client cert for root user found") 49 } 50 51 // Verify that we can build tls.Config objects. 52 if _, err := cm.GetServerTLSConfig(); err != nil { 53 t.Error(err) 54 } 55 if _, err := cm.GetClientTLSConfig(security.NodeUser); err != nil { 56 t.Error(err) 57 } 58 if _, err := cm.GetClientTLSConfig(security.RootUser); err != nil { 59 t.Error(err) 60 } 61 if _, err := cm.GetClientTLSConfig("testuser"); err != nil { 62 t.Error(err) 63 } 64 if _, err := cm.GetClientTLSConfig("my-random-user"); err == nil { 65 t.Error("unexpected success") 66 } 67 } 68 69 func TestManagerWithPrincipalMap(t *testing.T) { 70 defer leaktest.AfterTest(t)() 71 72 // Do not mock cert access for this test. 73 security.ResetAssetLoader() 74 defer ResetTest() 75 76 defer func() { _ = security.SetCertPrincipalMap(nil) }() 77 defer func() { 78 _ = os.Setenv("COCKROACH_CERT_NODE_USER", security.NodeUser) 79 envutil.ClearEnvCache() 80 }() 81 require.NoError(t, os.Setenv("COCKROACH_CERT_NODE_USER", "node.crdb.io")) 82 83 certsDir, err := ioutil.TempDir("", "certs_test") 84 require.NoError(t, err) 85 defer func() { 86 require.NoError(t, os.RemoveAll(certsDir)) 87 }() 88 89 caKey := filepath.Join(certsDir, "ca.key") 90 require.NoError(t, security.CreateCAPair( 91 certsDir, caKey, testKeySize, time.Hour*96, true, true, 92 )) 93 require.NoError(t, security.CreateClientPair( 94 certsDir, caKey, testKeySize, time.Hour*48, true, "testuser", false, 95 )) 96 require.NoError(t, security.CreateNodePair( 97 certsDir, caKey, testKeySize, time.Hour*48, true, []string{"127.0.0.1", "foo"}, 98 )) 99 100 setCertPrincipalMap := func(s string) { 101 require.NoError(t, security.SetCertPrincipalMap(strings.Split(s, ","))) 102 } 103 newCertificateManager := func() error { 104 _, err := security.NewCertificateManager(certsDir) 105 return err 106 } 107 loadUserCert := func(user string) error { 108 cm, err := security.NewCertificateManager(certsDir) 109 if err != nil { 110 return err 111 } 112 ci := cm.ClientCerts()[user] 113 if ci == nil { 114 return fmt.Errorf("user %q not found", user) 115 } 116 return ci.Error 117 } 118 119 setCertPrincipalMap("") 120 require.Regexp(t, `node certificate has principals \["node.crdb.io" "foo"\]`, newCertificateManager()) 121 122 // We can map the "node.crdb.io" principal to "node". 123 setCertPrincipalMap("node.crdb.io:node") 124 require.NoError(t, newCertificateManager()) 125 126 // We can map the "foo" principal to "node". 127 setCertPrincipalMap("foo:node") 128 require.NoError(t, newCertificateManager()) 129 130 // Mapping the "testuser" principal to a different name should result in an 131 // error as it no longer matches the file name. 132 setCertPrincipalMap("testuser:foo,node.crdb.io:node") 133 require.Regexp(t, `client certificate has principals \["foo"\], expected "testuser"`, loadUserCert("testuser")) 134 135 // Renaming "client.testuser.crt" to "client.foo.crt" allows us to load it 136 // under that name. 137 require.NoError(t, os.Rename(filepath.Join(certsDir, "client.testuser.crt"), 138 filepath.Join(certsDir, "client.foo.crt"))) 139 require.NoError(t, os.Rename(filepath.Join(certsDir, "client.testuser.key"), 140 filepath.Join(certsDir, "client.foo.key"))) 141 setCertPrincipalMap("testuser:foo,node.crdb.io:node") 142 require.NoError(t, loadUserCert("foo")) 143 }