gitlab.com/SkynetLabs/skyd@v1.6.9/cmd/skyc/skykeycmd_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "gitlab.com/SkynetLabs/skyd/node/api/client" 9 "gitlab.com/SkynetLabs/skyd/skykey" 10 ) 11 12 const testSkykeyString string = "skykey:Aa71WcCoKFwVGAVotJh3USAslb8dotVJp2VZRRSAG2QhYRbuTbQhjDolIJ1nOlQ-rWYK29_1xee5?name=test_key1" 13 14 // TestSkykeyCommands tests the basic functionality of the siac skykey commands 15 // interface. More detailed testing of the skykey manager is done in the skykey 16 // package. 17 func TestSkykeyCommands(t *testing.T) { 18 if testing.Short() { 19 t.SkipNow() 20 } 21 22 groupDir := skycTestDir(t.Name()) 23 24 // Define subtests 25 subTests := []subTest{ 26 {name: "TestDuplicateSkykeyAdd", test: testDuplicateSkykeyAdd}, 27 {name: "TestChangeKeyEntropyKeepName", test: testChangeKeyEntropyKeepName}, 28 {name: "TestAddKeyTwice", test: testAddKeyTwice}, 29 {name: "TestDelete", test: testDeleteKey}, 30 {name: "TestInvalidSkykeyType", test: testInvalidSkykeyType}, 31 {name: "TestSkykeyGet", test: testSkykeyGet}, 32 {name: "TestSkykeyGetUsingNameAndID", test: testSkykeyGetUsingNameAndID}, 33 {name: "TestSkykeyGetUsingNoNameAndNoID", test: testSkykeyGetUsingNoNameAndNoID}, 34 {name: "TestSkykeyListKeys", test: testSkykeyListKeys}, 35 {name: "TestSkykeyListKeysDoesntShowPrivateKeys", test: testSkykeyListKeysDoesntShowPrivateKeys}, 36 {name: "TestSkykeyListKeysAdditionalKeys", test: testSkykeyListKeysAdditionalKeys}, 37 {name: "TestSkykeyListKeysAdditionalKeysDoesntShowPrivateKeys", test: testSkykeyListKeysAdditionalKeysDoesntShowPrivateKeys}, 38 } 39 40 // Run tests 41 if err := runSubTests(t, groupDir, subTests); err != nil { 42 t.Fatal(err) 43 } 44 } 45 46 // testDuplicateSkykeyAdd tests that adding with duplicate Skykey will return 47 // duplicate name error. 48 func testDuplicateSkykeyAdd(t *testing.T, c client.Client) { 49 err := skykeyAdd(c, testSkykeyString) 50 if err != nil { 51 t.Fatal(err) 52 } 53 54 err = skykeyAdd(c, testSkykeyString) 55 if !strings.Contains(err.Error(), skykey.ErrSkykeyWithIDAlreadyExists.Error()) { 56 t.Fatal("Expected duplicate name error but got", err) 57 } 58 } 59 60 // testChangeKeyEntropyKeepName tests that adding with changed entropy but the 61 // same Skykey will return duplicate name error. 62 func testChangeKeyEntropyKeepName(t *testing.T, c client.Client) { 63 // Change the key entropy, but keep the same name. 64 var sk skykey.Skykey 65 err := sk.FromString(testSkykeyString) 66 if err != nil { 67 t.Fatal(err) 68 } 69 sk.Entropy[0] ^= 1 // flip the first byte. 70 71 skString, err := sk.ToString() 72 if err != nil { 73 t.Fatal(err) 74 } 75 76 // This should return a duplicate name error. 77 err = skykeyAdd(c, skString) 78 if !strings.Contains(err.Error(), skykey.ErrSkykeyWithNameAlreadyExists.Error()) { 79 t.Fatal("Expected duplicate name error but got", err) 80 } 81 } 82 83 // testAddKeyTwice tests that creating a Skykey with the same key name twice 84 // returns duplicate name error. 85 func testAddKeyTwice(t *testing.T, c client.Client) { 86 // Check that adding same key twice returns an error. 87 keyName := "createkey1" 88 _, err := skykeyCreate(c, keyName, skykey.TypePublicID.ToString()) 89 if err != nil { 90 t.Fatal(err) 91 } 92 _, err = skykeyCreate(c, keyName, skykey.TypePublicID.ToString()) 93 if !strings.Contains(err.Error(), skykey.ErrSkykeyWithNameAlreadyExists.Error()) { 94 t.Fatal("Expected error when creating key with same name") 95 } 96 } 97 98 // testDeleteKey tests that deleting a Skykey by name or id actually deletes 99 // the key 100 func testDeleteKey(t *testing.T, c client.Client) { 101 // Create a key. 102 keyName := "keyToDeleteByName" 103 _, err := skykeyCreate(c, keyName, skykey.TypePublicID.ToString()) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 // Get the Key 109 sk, err := c.SkykeyGetByName(keyName) 110 if err != nil { 111 t.Fatal(err) 112 } 113 if sk.Name != keyName { 114 t.Fatalf("Expected Skykey name %v but got %v", keyName, sk.Name) 115 } 116 117 // Delete key by name 118 err = c.SkykeyDeleteByNamePost(keyName) 119 if err != nil { 120 t.Fatal(err) 121 } 122 123 // Try and get the key again 124 _, err = c.SkykeyGetByName(keyName) 125 if err == nil || !strings.Contains(err.Error(), skykey.ErrNoSkykeysWithThatName.Error()) { 126 t.Fatalf("Expected Error to contain %v and got %v", skykey.ErrNoSkykeysWithThatName, err) 127 } 128 129 // Create key again 130 _, err = skykeyCreate(c, keyName, skykey.TypePublicID.ToString()) 131 if err != nil { 132 t.Fatal(err) 133 } 134 135 // Get ID 136 sk, err = c.SkykeyGetByName(keyName) 137 if err != nil { 138 t.Fatal(err) 139 } 140 141 // Delete key by ID 142 err = c.SkykeyDeleteByIDPost(sk.ID()) 143 if err != nil { 144 t.Fatal(err) 145 } 146 147 // Try and get the key again 148 _, err = c.SkykeyGetByName(keyName) 149 if err == nil || !strings.Contains(err.Error(), skykey.ErrNoSkykeysWithThatName.Error()) { 150 t.Fatalf("Expected Error to contain %v and got %v", skykey.ErrNoSkykeysWithThatName, err) 151 } 152 } 153 154 // testInvalidSkykeyType tests that invalid cipher types are caught. 155 func testInvalidSkykeyType(t *testing.T, c client.Client) { 156 // Verify invalid type returns error 157 _, err := skykeyCreate(c, "createkey2", skykey.TypeInvalid.ToString()) 158 if !strings.Contains(err.Error(), skykey.ErrInvalidSkykeyType.Error()) { 159 t.Fatal("Expected error when creating key with invalid skykeytpe", err) 160 } 161 162 // Submitting a blank skykey type should succeed and default to private 163 keyName := "blankType" 164 _, err = skykeyCreate(c, keyName, "") 165 if err != nil { 166 t.Fatal(err) 167 } 168 sk, err := c.SkykeyGetByName(keyName) 169 if err != nil { 170 t.Fatal(err) 171 } 172 if sk.Type != skykey.TypePrivateID { 173 t.Fatal("Skykey type expected to be private") 174 } 175 // Delete Key to not impact future sub tests 176 err = c.SkykeyDeleteByNamePost(keyName) 177 if err != nil { 178 t.Fatal(err) 179 } 180 // Verify a random type gives an error 181 _, err = skykeyCreate(c, "", "not a type") 182 if !strings.Contains(err.Error(), skykey.ErrInvalidSkykeyType.Error()) { 183 t.Fatal("Expected error when creating key with invalid skykeytpe", err) 184 } 185 } 186 187 // testSkykeyGet tests skykeyGet with known key should not return any errors. 188 func testSkykeyGet(t *testing.T, c client.Client) { 189 keyName := "createkey testSkykeyGet" 190 newSkykey, err := skykeyCreate(c, keyName, skykey.TypePublicID.ToString()) 191 if err != nil { 192 t.Fatal(err) 193 } 194 195 // Test skykeyGet 196 // known key should have no errors. 197 getKeyStr, err := skykeyGet(c, keyName, "") 198 if err != nil { 199 t.Fatal(err) 200 } 201 if getKeyStr != newSkykey { 202 t.Fatal("Expected keys to match") 203 } 204 } 205 206 // testSkykeyGetUsingNameAndID tests using both name and id params should return an 207 // error. 208 func testSkykeyGetUsingNameAndID(t *testing.T, c client.Client) { 209 _, err := skykeyGet(c, "name", "id") 210 if err == nil { 211 t.Fatal("Expected error when using both name and id") 212 } 213 } 214 215 // testSkykeyGetUsingNoNameAndNoID test using neither name or id param should return an 216 // error. 217 func testSkykeyGetUsingNoNameAndNoID(t *testing.T, c client.Client) { 218 _, err := skykeyGet(c, "", "") 219 if err == nil { 220 t.Fatal("Expected error when using neither name or id params") 221 } 222 } 223 224 // testSkykeyListKeys tests that skykeyListKeys shows key names, ids and keys 225 func testSkykeyListKeys(t *testing.T, c client.Client) { 226 nKeys := 3 227 nExtraLines := 3 228 keyStrings := make([]string, nKeys) 229 keyNames := make([]string, nKeys) 230 keyIDs := make([]string, nKeys) 231 232 initSkykeyData(t, c, keyStrings, keyNames, keyIDs) 233 234 keyListString, err := skykeyListKeys(c, true) 235 if err != nil { 236 t.Fatal(err) 237 } 238 for i := 0; i < nKeys; i++ { 239 if !strings.Contains(keyListString, keyNames[i]) { 240 t.Log(keyListString) 241 t.Fatal("Missing key name!", i) 242 } 243 if !strings.Contains(keyListString, keyIDs[i]) { 244 t.Log(keyListString) 245 t.Fatal("Missing id!", i) 246 } 247 if !strings.Contains(keyListString, keyStrings[i]) { 248 t.Log(keyListString) 249 t.Fatal("Missing key!", i) 250 } 251 } 252 keyList := strings.Split(keyListString, "\n") 253 if len(keyList) != nKeys+nExtraLines { 254 t.Log(keyListString) 255 t.Fatalf("Unexpected number of lines/keys %d, Expected %d", len(keyList), nKeys+nExtraLines) 256 } 257 } 258 259 // testKskykeyListKeysDoesntShowPrivateKeys tests that skykeyListKeys shows key names, ids and 260 // doesn't show private keys 261 func testSkykeyListKeysDoesntShowPrivateKeys(t *testing.T, c client.Client) { 262 nKeys := 3 263 nExtraLines := 3 264 keyStrings := make([]string, nKeys) 265 keyNames := make([]string, nKeys) 266 keyIDs := make([]string, nKeys) 267 268 initSkykeyData(t, c, keyStrings, keyNames, keyIDs) 269 270 keyListString, err := skykeyListKeys(c, false) 271 if err != nil { 272 t.Fatal(err) 273 } 274 for i := 0; i < nKeys; i++ { 275 if !strings.Contains(keyListString, keyNames[i]) { 276 t.Log(keyListString) 277 t.Fatal("Missing key name!", i) 278 } 279 if !strings.Contains(keyListString, keyIDs[i]) { 280 t.Log(keyListString) 281 t.Fatal("Missing id!", i) 282 } 283 if strings.Contains(keyListString, keyStrings[i]) { 284 t.Log(keyListString) 285 t.Fatal("Found key!", i) 286 } 287 } 288 keyList := strings.Split(keyListString, "\n") 289 if len(keyList) != nKeys+nExtraLines { 290 t.Fatal("Unexpected number of lines/keys", len(keyList)) 291 } 292 } 293 294 // testSkykeyListKeysAdditionalKeys tests that after creating additional keys, 295 // skykeyListKeys shows all key names, ids and keys 296 func testSkykeyListKeysAdditionalKeys(t *testing.T, c client.Client) { 297 nExtraKeys := 10 298 nKeys := 3 + nExtraKeys 299 keyStrings := make([]string, nKeys) 300 keyNames := make([]string, nKeys) 301 keyIDs := make([]string, nKeys) 302 303 initSkykeyData(t, c, keyStrings, keyNames, keyIDs) 304 305 // Count the number of public/private keys we create. 306 expectedNumPublic := nKeys - nExtraKeys // initial keys are public 307 expectedNumPrivate := 0 308 309 // Add extra keys 310 for i := 0; i < nExtraKeys; i++ { 311 skykeyType := skykey.TypePrivateID 312 if i%2 == 0 { 313 skykeyType = skykey.TypePublicID 314 expectedNumPublic += 1 315 } else { 316 expectedNumPrivate += 1 317 } 318 319 nextName := fmt.Sprintf("extrakey-%d", i) 320 keyNames = append(keyNames, nextName) 321 nextSkStr, err := skykeyCreate(c, nextName, skykeyType.ToString()) 322 if err != nil { 323 t.Fatal(err) 324 } 325 var nextSkykey skykey.Skykey 326 err = nextSkykey.FromString(nextSkStr) 327 if err != nil { 328 t.Fatal(err) 329 } 330 keyIDs = append(keyIDs, nextSkykey.ID().ToString()) 331 keyStrings = append(keyStrings, nextSkStr) 332 } 333 334 // Check that all the key names and key data is there. 335 keyListString, err := skykeyListKeys(c, true) 336 if err != nil { 337 t.Fatal(err) 338 } 339 for i := 0; i < nKeys; i++ { 340 if !strings.Contains(keyListString, keyNames[i]) { 341 t.Log(keyListString) 342 t.Fatal("Missing key name!", i) 343 } 344 if !strings.Contains(keyListString, keyIDs[i]) { 345 t.Log(keyListString) 346 t.Fatal("Missing id!", i) 347 } 348 if !strings.Contains(keyListString, keyStrings[i]) { 349 t.Log(keyListString) 350 t.Fatal("Missing key!", i) 351 } 352 } 353 354 // Check that the expected number of public/private keys were created. 355 numPublic := strings.Count(keyListString, skykey.TypePublicID.ToString()) 356 numPrivate := strings.Count(keyListString, skykey.TypePrivateID.ToString()) 357 if numPublic != expectedNumPublic { 358 t.Log(keyListString) 359 t.Fatalf("Expected %d %s keys got %d instead", numPublic, skykey.TypePublicID.ToString(), expectedNumPublic) 360 } 361 if numPrivate != expectedNumPrivate { 362 t.Log(keyListString) 363 t.Fatalf("Expected %d %s keys got %d instead", numPrivate, skykey.TypePrivateID.ToString(), expectedNumPrivate) 364 } 365 } 366 367 // testSkykeyListKeysAdditionalKeysDoesntShowPrivateKeys tests that after creating additional keys, 368 // skykeyListKeys shows all key names, ids and doesn't show private keys 369 func testSkykeyListKeysAdditionalKeysDoesntShowPrivateKeys(t *testing.T, c client.Client) { 370 nExtraKeys := 10 371 nPrevKeys := 3 372 nKeys := nPrevKeys + nExtraKeys 373 nExtraLines := 3 374 keyStrings := make([]string, nPrevKeys) 375 keyNames := make([]string, nPrevKeys) 376 keyIDs := make([]string, nPrevKeys) 377 378 initSkykeyData(t, c, keyStrings, keyNames, keyIDs) 379 380 // Get extra keys 381 for i := 0; i < nExtraKeys; i++ { 382 nextName := fmt.Sprintf("extrakey-%d", i) 383 keyNames = append(keyNames, nextName) 384 nextSkStr, err := skykeyGet(c, nextName, "") 385 if err != nil { 386 t.Fatal(err) 387 } 388 var nextSkykey skykey.Skykey 389 err = nextSkykey.FromString(nextSkStr) 390 if err != nil { 391 t.Fatal(err) 392 } 393 keyIDs = append(keyIDs, nextSkykey.ID().ToString()) 394 keyStrings = append(keyStrings, nextSkStr) 395 } 396 397 // Make sure key data isn't shown but otherwise the same checks pass. 398 keyListString, err := skykeyListKeys(c, false) 399 if err != nil { 400 t.Fatal(err) 401 } 402 for i := 0; i < nKeys; i++ { 403 if !strings.Contains(keyListString, keyNames[i]) { 404 t.Log(keyListString) 405 t.Fatal("Missing key name!", i) 406 } 407 if !strings.Contains(keyListString, keyIDs[i]) { 408 t.Log(keyListString) 409 t.Fatal("Missing id!", i) 410 } 411 if strings.Contains(keyListString, keyStrings[i]) { 412 t.Log(keyListString) 413 t.Fatal("Found key!", i) 414 } 415 } 416 keyList := strings.Split(keyListString, "\n") 417 if len(keyList) != nKeys+nExtraLines { 418 t.Fatal("Unexpected number of lines/keys", len(keyList)) 419 } 420 } 421 422 // initSkykeyData initializes keyStrings, keyNames, keyIDS slices with existing Skykey data 423 func initSkykeyData(t *testing.T, c client.Client, keyStrings, keyNames, keyIDs []string) { 424 keyName1 := "createkey1" 425 keyName2 := "createkey testSkykeyGet" 426 427 getKeyStr1, err := skykeyGet(c, keyName1, "") 428 if err != nil { 429 t.Fatal(err) 430 } 431 432 getKeyStr2, err := skykeyGet(c, keyName2, "") 433 if err != nil { 434 t.Fatal(err) 435 } 436 437 keyNames[0] = "key1" 438 keyNames[1] = keyName1 439 keyNames[2] = keyName2 440 keyStrings[0] = testSkykeyString 441 keyStrings[1] = getKeyStr1 442 keyStrings[2] = getKeyStr2 443 444 var sk skykey.Skykey 445 err = sk.FromString(testSkykeyString) 446 if err != nil { 447 t.Fatal(err) 448 } 449 keyIDs[0] = sk.ID().ToString() 450 451 err = sk.FromString(getKeyStr1) 452 if err != nil { 453 t.Fatal(err) 454 } 455 keyIDs[1] = sk.ID().ToString() 456 457 err = sk.FromString(getKeyStr2) 458 if err != nil { 459 t.Fatal(err) 460 } 461 keyIDs[2] = sk.ID().ToString() 462 }