github.com/itscaro/cli@v0.0.0-20190705081621-c9db0fe93829/cli/command/trust/key_generate_test.go (about) 1 package trust 2 3 import ( 4 "encoding/pem" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "testing" 10 11 "github.com/docker/cli/cli/config" 12 "github.com/docker/cli/internal/test" 13 "github.com/theupdateframework/notary" 14 "github.com/theupdateframework/notary/passphrase" 15 "github.com/theupdateframework/notary/trustmanager" 16 tufutils "github.com/theupdateframework/notary/tuf/utils" 17 "gotest.tools/assert" 18 is "gotest.tools/assert/cmp" 19 ) 20 21 func TestTrustKeyGenerateErrors(t *testing.T) { 22 testCases := []struct { 23 name string 24 args []string 25 expectedError string 26 }{ 27 { 28 name: "not-enough-args", 29 expectedError: "requires exactly 1 argument", 30 }, 31 { 32 name: "too-many-args", 33 args: []string{"key-1", "key-2"}, 34 expectedError: "requires exactly 1 argument", 35 }, 36 } 37 38 tmpDir, err := ioutil.TempDir("", "docker-key-generate-test-") 39 assert.NilError(t, err) 40 defer os.RemoveAll(tmpDir) 41 config.SetDir(tmpDir) 42 43 for _, tc := range testCases { 44 cli := test.NewFakeCli(&fakeClient{}) 45 cmd := newKeyGenerateCommand(cli) 46 cmd.SetArgs(tc.args) 47 cmd.SetOutput(ioutil.Discard) 48 assert.ErrorContains(t, cmd.Execute(), tc.expectedError) 49 } 50 } 51 52 func TestGenerateKeySuccess(t *testing.T) { 53 pubKeyCWD, err := ioutil.TempDir("", "pub-keys-") 54 assert.NilError(t, err) 55 defer os.RemoveAll(pubKeyCWD) 56 57 privKeyStorageDir, err := ioutil.TempDir("", "priv-keys-") 58 assert.NilError(t, err) 59 defer os.RemoveAll(privKeyStorageDir) 60 61 passwd := "password" 62 cannedPasswordRetriever := passphrase.ConstantRetriever(passwd) 63 // generate a single key 64 keyName := "alice" 65 privKeyFileStore, err := trustmanager.NewKeyFileStore(privKeyStorageDir, cannedPasswordRetriever) 66 assert.NilError(t, err) 67 68 pubKeyPEM, err := generateKeyAndOutputPubPEM(keyName, privKeyFileStore) 69 assert.NilError(t, err) 70 71 assert.Check(t, is.Equal(keyName, pubKeyPEM.Headers["role"])) 72 // the default GUN is empty 73 assert.Check(t, is.Equal("", pubKeyPEM.Headers["gun"])) 74 // assert public key header 75 assert.Check(t, is.Equal("PUBLIC KEY", pubKeyPEM.Type)) 76 77 // check that an appropriate ~/<trust_dir>/private/<key_id>.key file exists 78 expectedPrivKeyDir := filepath.Join(privKeyStorageDir, notary.PrivDir) 79 _, err = os.Stat(expectedPrivKeyDir) 80 assert.NilError(t, err) 81 82 keyFiles, err := ioutil.ReadDir(expectedPrivKeyDir) 83 assert.NilError(t, err) 84 assert.Check(t, is.Len(keyFiles, 1)) 85 privKeyFilePath := filepath.Join(expectedPrivKeyDir, keyFiles[0].Name()) 86 87 // verify the key content 88 privFrom, _ := os.OpenFile(privKeyFilePath, os.O_RDONLY, notary.PrivExecPerms) 89 defer privFrom.Close() 90 fromBytes, _ := ioutil.ReadAll(privFrom) 91 privKeyPEM, _ := pem.Decode(fromBytes) 92 assert.Check(t, is.Equal(keyName, privKeyPEM.Headers["role"])) 93 // the default GUN is empty 94 assert.Check(t, is.Equal("", privKeyPEM.Headers["gun"])) 95 // assert encrypted header 96 assert.Check(t, is.Equal("ENCRYPTED PRIVATE KEY", privKeyPEM.Type)) 97 // check that the passphrase matches 98 _, err = tufutils.ParsePKCS8ToTufKey(privKeyPEM.Bytes, []byte(passwd)) 99 assert.NilError(t, err) 100 101 // check that the public key exists at the correct path if we use the helper: 102 returnedPath, err := writePubKeyPEMToDir(pubKeyPEM, keyName, pubKeyCWD) 103 assert.NilError(t, err) 104 expectedPubKeyPath := filepath.Join(pubKeyCWD, keyName+".pub") 105 assert.Check(t, is.Equal(returnedPath, expectedPubKeyPath)) 106 _, err = os.Stat(expectedPubKeyPath) 107 assert.NilError(t, err) 108 // check that the public key is the only file output in CWD 109 cwdKeyFiles, err := ioutil.ReadDir(pubKeyCWD) 110 assert.NilError(t, err) 111 assert.Check(t, is.Len(cwdKeyFiles, 1)) 112 } 113 114 func TestValidateKeyArgs(t *testing.T) { 115 pubKeyCWD, err := ioutil.TempDir("", "pub-keys-") 116 assert.NilError(t, err) 117 defer os.RemoveAll(pubKeyCWD) 118 119 err = validateKeyArgs("a", pubKeyCWD) 120 assert.NilError(t, err) 121 122 err = validateKeyArgs("a/b", pubKeyCWD) 123 assert.Error(t, err, "key name \"a/b\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character") 124 125 err = validateKeyArgs("-", pubKeyCWD) 126 assert.Error(t, err, "key name \"-\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character") 127 128 assert.NilError(t, ioutil.WriteFile(filepath.Join(pubKeyCWD, "a.pub"), []byte("abc"), notary.PrivExecPerms)) 129 err = validateKeyArgs("a", pubKeyCWD) 130 assert.Error(t, err, fmt.Sprintf("public key file already exists: \"%s\"", filepath.Join(pubKeyCWD, "a.pub"))) 131 132 err = validateKeyArgs("a", "/random/dir/") 133 assert.Error(t, err, "public key path does not exist: \"/random/dir/\"") 134 }