1// Copyright 2018 The NATS Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package nkeys 15 16import ( 17 "bytes" 18 "crypto/rand" 19 "encoding/base64" 20 "io" 21 "os" 22 "regexp" 23 "testing" 24 25 "golang.org/x/crypto/ed25519" 26) 27 28func TestVersion(t *testing.T) { 29 // Semantic versioning 30 verRe := regexp.MustCompile(`\d+.\d+.\d+(-\S+)?`) 31 if !verRe.MatchString(Version) { 32 t.Fatalf("Version not compatible with semantic versioning: %q", Version) 33 } 34} 35 36func TestVersionMatchesTag(t *testing.T) { 37 tag := os.Getenv("TRAVIS_TAG") 38 if tag == "" { 39 t.SkipNow() 40 } 41 // We expect a tag of the form vX.Y.Z. If that's not the case, 42 // we need someone to have a look. So fail if first letter is not 43 // a `v` 44 if tag[0] != 'v' { 45 t.Fatalf("Expect tag to start with `v`, tag is: %s", tag) 46 } 47 // Strip the `v` from the tag for the version comparison. 48 if Version != tag[1:] { 49 t.Fatalf("Version (%s) does not match tag (%s)", Version, tag[1:]) 50 } 51} 52 53func TestEncode(t *testing.T) { 54 var rawKey [32]byte 55 56 _, err := io.ReadFull(rand.Reader, rawKey[:]) 57 if err != nil { 58 t.Fatalf("Unexpected error reading from crypto/rand: %v", err) 59 } 60 _, err = Encode(PrefixByteUser, rawKey[:]) 61 if err != nil { 62 t.Fatalf("Unexpected error from Encode: %v", err) 63 } 64 str, err := Encode(22<<3, rawKey[:]) 65 if err == nil { 66 t.Fatal("Expected an error from Encode but received nil") 67 } 68 if str != nil { 69 t.Fatalf("Expected empty string from Encode: got %s", str) 70 } 71} 72 73func TestDecode(t *testing.T) { 74 var rawKey [32]byte 75 76 _, err := io.ReadFull(rand.Reader, rawKey[:]) 77 if err != nil { 78 t.Fatalf("Unexpected error reading from crypto/rand: %v", err) 79 } 80 str, err := Encode(PrefixByteUser, rawKey[:]) 81 if err != nil { 82 t.Fatalf("Unexpected error from Encode: %v", err) 83 } 84 85 decoded, err := Decode(PrefixByteUser, str) 86 if err != nil { 87 t.Fatalf("Unexpected error from Decode: %v", err) 88 } 89 if !bytes.Equal(decoded, rawKey[:]) { 90 t.Fatalf("Decoded does not match the original") 91 } 92} 93 94func TestSeed(t *testing.T) { 95 var rawKeyShort [16]byte 96 97 _, err := io.ReadFull(rand.Reader, rawKeyShort[:]) 98 if err != nil { 99 t.Fatalf("Unexpected error reading from crypto/rand: %v", err) 100 } 101 // Seeds need to be 64 bytes 102 if _, err := EncodeSeed(PrefixByteUser, rawKeyShort[:]); err != ErrInvalidSeedLen { 103 t.Fatalf("Did not receive ErrInvalidSeed error, received %v", err) 104 } 105 // Seeds need to be typed with only public types. 106 if _, err := EncodeSeed(PrefixByteSeed, rawKeyShort[:]); err != ErrInvalidPrefixByte { 107 t.Fatalf("Did not receive ErrInvalidPrefixByte error, received %v", err) 108 } 109 110 var rawSeed [ed25519.SeedSize]byte 111 112 _, err = io.ReadFull(rand.Reader, rawSeed[:]) 113 if err != nil { 114 t.Fatalf("Unexpected error reading from crypto/rand: %v", err) 115 } 116 117 seed, err := EncodeSeed(PrefixByteUser, rawSeed[:]) 118 if err != nil { 119 t.Fatalf("EncodeSeed received an error: %v", err) 120 } 121 122 pre, decoded, err := DecodeSeed(seed) 123 if err != nil { 124 t.Fatalf("Got an unexpected error from DecodeSeed: %v", err) 125 } 126 if pre != PrefixByteUser { 127 t.Fatalf("Expected the prefix to be PrefixByteUser(%v), got %v", 128 PrefixByteUser, pre) 129 } 130 if !bytes.Equal(decoded, rawSeed[:]) { 131 t.Fatalf("Decoded seed does not match the original") 132 } 133} 134 135func TestAccount(t *testing.T) { 136 account, err := CreateAccount() 137 if err != nil { 138 t.Fatalf("Expected non-nil error on CreateAccount, received %v", err) 139 } 140 if account == nil { 141 t.Fatal("Expect a non-nil account") 142 } 143 seed, err := account.Seed() 144 if err != nil { 145 t.Fatalf("Unexpected error retrieving seed: %v", err) 146 } 147 _, err = Decode(PrefixByteSeed, seed) 148 if err != nil { 149 t.Fatalf("Expected a proper seed string, got %s", seed) 150 } 151 152 // Check Public 153 public, err := account.PublicKey() 154 if err != nil { 155 t.Fatalf("Received an error retrieving public key: %v", err) 156 } 157 if public[0] != 'A' { 158 t.Fatalf("Expected a prefix of 'A' but got %c", public[0]) 159 } 160 if !IsValidPublicAccountKey(public) { 161 t.Fatalf("Not a valid public account key") 162 } 163 164 // Check Private 165 private, err := account.PrivateKey() 166 if err != nil { 167 t.Fatalf("Received an error retrieving private key: %v", err) 168 } 169 if private[0] != 'P' { 170 t.Fatalf("Expected a prefix of 'P' but got %v", private[0]) 171 } 172 173 // Check Sign and Verify 174 data := []byte("Hello World") 175 sig, err := account.Sign(data) 176 if err != nil { 177 t.Fatalf("Unexpected error signing from account: %v", err) 178 } 179 if len(sig) != ed25519.SignatureSize { 180 t.Fatalf("Expected signature size of %d but got %d", 181 ed25519.SignatureSize, len(sig)) 182 } 183 err = account.Verify(data, sig) 184 if err != nil { 185 t.Fatalf("Unexpected error verifying signature: %v", err) 186 } 187} 188 189func TestUser(t *testing.T) { 190 user, err := CreateUser() 191 if err != nil { 192 t.Fatalf("Expected non-nil error on CreateUser, received %v", err) 193 } 194 if user == nil { 195 t.Fatal("Expect a non-nil user") 196 } 197 198 // Check Public 199 public, err := user.PublicKey() 200 if err != nil { 201 t.Fatalf("Received an error retrieving public key: %v", err) 202 } 203 if public[0] != 'U' { 204 t.Fatalf("Expected a prefix of 'U' but got %c", public[0]) 205 } 206 if !IsValidPublicUserKey(public) { 207 t.Fatalf("Not a valid public user key") 208 } 209} 210 211func TestOperator(t *testing.T) { 212 operator, err := CreateOperator() 213 if err != nil { 214 t.Fatalf("Expected non-nil error on CreateOperator, received %v", err) 215 } 216 if operator == nil { 217 t.Fatal("Expect a non-nil operator") 218 } 219 220 // Check Public 221 public, err := operator.PublicKey() 222 if err != nil { 223 t.Fatalf("Received an error retrieving public key: %v", err) 224 } 225 if public[0] != 'O' { 226 t.Fatalf("Expected a prefix of 'O' but got %c", public[0]) 227 } 228 if !IsValidPublicOperatorKey(public) { 229 t.Fatalf("Not a valid public cluster key") 230 } 231} 232 233func TestCluster(t *testing.T) { 234 cluster, err := CreateCluster() 235 if err != nil { 236 t.Fatalf("Expected non-nil error on CreateCluster, received %v", err) 237 } 238 if cluster == nil { 239 t.Fatal("Expect a non-nil cluster") 240 } 241 242 // Check Public 243 public, err := cluster.PublicKey() 244 if err != nil { 245 t.Fatalf("Received an error retrieving public key: %v", err) 246 } 247 if public[0] != 'C' { 248 t.Fatalf("Expected a prefix of 'C' but got %c", public[0]) 249 } 250 if !IsValidPublicClusterKey(public) { 251 t.Fatalf("Not a valid public cluster key") 252 } 253} 254 255func TestServer(t *testing.T) { 256 server, err := CreateServer() 257 if err != nil { 258 t.Fatalf("Expected non-nil error on CreateServer, received %v", err) 259 } 260 if server == nil { 261 t.Fatal("Expect a non-nil server") 262 } 263 264 // Check Public 265 public, err := server.PublicKey() 266 if err != nil { 267 t.Fatalf("Received an error retrieving public key: %v", err) 268 } 269 if public[0] != 'N' { 270 t.Fatalf("Expected a prefix of 'N' but got %c", public[0]) 271 } 272 if !IsValidPublicServerKey(public) { 273 t.Fatalf("Not a valid public server key") 274 } 275} 276 277func TestPrefixByte(t *testing.T) { 278 user, _ := CreateUser() 279 pub, _ := user.PublicKey() 280 if pre := Prefix(pub); pre != PrefixByteUser { 281 t.Fatalf("Expected %s, got %s\n", PrefixByteUser, pre) 282 } 283 seed, _ := user.Seed() 284 if pre := Prefix(string(seed)); pre != PrefixByteSeed { 285 t.Fatalf("Expected %s, got %s\n", PrefixByteSeed, pre) 286 } 287 if pre := Prefix("SEED"); pre != PrefixByteUnknown { 288 t.Fatalf("Expected %s, got %s\n", PrefixByteUnknown, pre) 289 } 290 account, _ := CreateAccount() 291 pub, _ = account.PublicKey() 292 if pre := Prefix(pub); pre != PrefixByteAccount { 293 t.Fatalf("Expected %s, got %s\n", PrefixByteAccount, pre) 294 } 295} 296 297func TestIsValidPublic(t *testing.T) { 298 user, _ := CreateUser() 299 pub, _ := user.PublicKey() 300 if !IsValidPublicKey(pub) { 301 t.Fatalf("Expected pub to be a valid public key") 302 } 303 seed, _ := user.Seed() 304 if IsValidPublicKey(string(seed)) { 305 t.Fatalf("Expected seed to not be a valid public key") 306 } 307 if IsValidPublicKey("BAD") { 308 t.Fatalf("Expected BAD to not be a valid public key") 309 } 310 account, _ := CreateAccount() 311 pub, _ = account.PublicKey() 312 if !IsValidPublicKey(pub) { 313 t.Fatalf("Expected pub to be a valid public key") 314 } 315} 316 317func TestFromPublic(t *testing.T) { 318 // Create a User 319 user, err := CreateUser() 320 if err != nil { 321 t.Fatalf("Expected non-nil error on CreateUser, received %v", err) 322 } 323 if user == nil { 324 t.Fatal("Expect a non-nil user") 325 } 326 327 // Now create a publickey only KeyPair 328 publicKey, err := user.PublicKey() 329 if err != nil { 330 t.Fatalf("Error retrieving public key from user: %v", err) 331 } 332 publicKeyClone, _ := user.PublicKey() 333 if publicKeyClone != publicKey { 334 t.Fatalf("Expected the public keys to match: %q vs %q", publicKeyClone, publicKey) 335 } 336 337 pubUser, err := FromPublicKey(publicKey) 338 if err != nil { 339 t.Fatalf("Error creating public key only user: %v", err) 340 } 341 342 publicKey2, err := pubUser.PublicKey() 343 if err != nil { 344 t.Fatalf("Error retrieving public key from public user: %v", err) 345 } 346 // Make sure they match 347 if publicKey2 != publicKey { 348 t.Fatalf("Expected the public keys to match: %q vs %q", publicKey2, publicKey) 349 } 350 351 if _, err = pubUser.PrivateKey(); err == nil { 352 t.Fatalf("Expected and error trying to get private key") 353 } 354 if _, err := pubUser.Seed(); err == nil { 355 t.Fatalf("Expected and error trying to get seed") 356 } 357 358 data := []byte("Hello World") 359 360 // Can't sign.. 361 if _, err = pubUser.Sign(data); err != ErrCannotSign { 362 t.Fatalf("Expected %v, but got %v", ErrCannotSign, err) 363 } 364 365 // Should be able to verify with pubUser. 366 sig, err := user.Sign(data) 367 if err != nil { 368 t.Fatalf("Unexpected error signing from user: %v", err) 369 } 370 371 err = pubUser.Verify(data, sig) 372 if err != nil { 373 t.Fatalf("Unexpected error verifying signature: %v", err) 374 } 375 376 // Create another user to sign and make sure verify fails. 377 user2, _ := CreateUser() 378 sig, _ = user2.Sign(data) 379 380 err = pubUser.Verify(data, sig) 381 if err == nil { 382 t.Fatalf("Expected verification to fail.") 383 } 384} 385 386func TestFromSeed(t *testing.T) { 387 account, err := CreateAccount() 388 if err != nil { 389 t.Fatalf("Expected non-nil error on CreateAccount, received %v", err) 390 } 391 if account == nil { 392 t.Fatal("Expect a non-nil account") 393 } 394 395 data := []byte("Hello World") 396 sig, err := account.Sign(data) 397 if err != nil { 398 t.Fatalf("Unexpected error signing from account: %v", err) 399 } 400 401 seed, err := account.Seed() 402 if err != nil { 403 t.Fatalf("Unexpected error retrieving seed: %v", err) 404 } 405 // Make sure the seed starts with SA 406 if !bytes.HasPrefix(seed, []byte("SA")) { 407 t.Fatalf("Expected seed to start with 'SA', go '%s'", seed[:2]) 408 } 409 410 account2, err := FromSeed(seed) 411 if err != nil { 412 t.Fatalf("Error recreating account from seed: %v", err) 413 } 414 if account2 == nil { 415 t.Fatal("Expect a non-nil account") 416 } 417 err = account2.Verify(data, sig) 418 if err != nil { 419 t.Fatalf("Unexpected error verifying signature: %v", err) 420 } 421} 422 423func TestKeyPairFailures(t *testing.T) { 424 var tooshort [8]byte 425 if _, err := EncodeSeed(PrefixByteUser, tooshort[:]); err == nil { 426 t.Fatal("Expected an error with insufficient rand") 427 } 428 429 if _, err := CreatePair(PrefixBytePrivate); err == nil { 430 t.Fatal("Expected an error with non-public prefix") 431 } 432 kpbad := &kp{[]byte("SEEDBAD")} 433 if _, _, err := kpbad.keys(); err == nil { 434 t.Fatal("Expected an error decoding keys with a bad seed") 435 } 436 if _, err := kpbad.PublicKey(); err == nil { 437 t.Fatal("Expected an error getting PublicKey from KP with a bad seed") 438 } 439 if _, err := kpbad.PrivateKey(); err == nil { 440 t.Fatal("Expected an error getting PrivateKey from KP with a bad seed") 441 } 442 if _, err := kpbad.Sign([]byte("ok")); err == nil { 443 t.Fatal("Expected an error from Signing from KP with a bad seed") 444 } 445} 446 447func TestBadDecode(t *testing.T) { 448 if _, err := decode([]byte("foo!")); err == nil { 449 t.Fatal("Expected an error decoding non-base32") 450 } 451 if _, err := decode([]byte("OK")); err == nil { 452 t.Fatal("Expected an error decoding a too short string") 453 } 454 455 // Create invalid checksum 456 account, _ := CreateAccount() 457 pkey, _ := account.PublicKey() 458 bpkey := []byte(pkey) 459 bpkey[len(pkey)-1] = '0' 460 bpkey[len(pkey)-2] = '0' 461 if _, err := decode(bpkey); err == nil { 462 t.Fatal("Expected error on decode with bad checksum") 463 } 464 465 if _, err := Decode(PrefixByteUser, []byte(pkey)); err == nil { 466 t.Fatal("Expected error on Decode with mismatched prefix") 467 } 468 if _, err := Decode(PrefixByte(3<<3), []byte(pkey)); err == nil { 469 t.Fatal("Expected error on Decode with invalid prefix") 470 } 471 if _, err := Decode(PrefixByteAccount, bpkey); err == nil { 472 t.Fatal("Expected error on Decode with bad checksum") 473 } 474 // Seed version 475 if _, _, err := DecodeSeed(bpkey); err == nil { 476 t.Fatal("Expected error on DecodeSeed with bad checksum") 477 } 478 if _, _, err := DecodeSeed([]byte(pkey)); err == nil { 479 t.Fatal("Expected error on DecodeSeed with bad seed type") 480 } 481 482 seed, _ := account.Seed() 483 bseed := []byte(seed) 484 bseed[1] = 'S' 485 if _, _, err := DecodeSeed(bseed); err == nil { 486 t.Fatal("Expected error on DecodeSeed with bad prefix type") 487 } 488 if _, err := FromSeed(bseed); err == nil { 489 t.Fatal("Expected error on FromSeed with bad prefix type") 490 } 491 492 if _, err := FromPublicKey(string(bpkey)); err == nil { 493 t.Fatal("Expected error on FromPublicKey with bad checksum") 494 } 495 if _, err := FromPublicKey(string(seed)); err == nil { 496 t.Fatal("Expected error on FromPublicKey with bad checksum") 497 } 498} 499 500func TestFromRawSeed(t *testing.T) { 501 user, err := CreateUser() 502 if err != nil { 503 t.Fatalf("Expected non-nil error on CreateUser, received %v", err) 504 } 505 se, _ := user.Seed() 506 _, raw, _ := DecodeSeed(se) 507 user2, err := FromRawSeed(PrefixByteUser, raw) 508 if err != nil { 509 t.Fatalf("Expected non-nil error on FromRawSeed, received %v", err) 510 } 511 s2e, _ := user2.Seed() 512 if !bytes.Equal(se, s2e) { 513 t.Fatalf("Expected the seeds to be the same, got %v vs %v\n", se, s2e) 514 } 515} 516 517func TestWipe(t *testing.T) { 518 user, err := CreateUser() 519 if err != nil { 520 t.Fatalf("Expected non-nil error on CreateUser, received %v", err) 521 } 522 pubKey, err := user.PublicKey() 523 if err != nil { 524 t.Fatalf("Received an error retrieving public key: %v", err) 525 } 526 seed := user.(*kp).seed 527 // Copy so we know the original 528 copy := append([]byte{}, seed...) 529 user.Wipe() 530 // Make sure new seed is nil 531 if wiped := user.(*kp).seed; wiped != nil { 532 t.Fatalf("Expected the seed to be nil, got %q", wiped) 533 } 534 // Make sure the original seed is not equal to the seed in memory. 535 if bytes.Equal(seed, copy) { 536 t.Fatalf("Expected the memory for the seed to be randomized") 537 } 538 539 // Now test public 540 user, err = FromPublicKey(pubKey) 541 if err != nil { 542 t.Fatalf("Received an error create KeyPair from PublicKey: %v", err) 543 } 544 545 edPub := user.(*pub).pub 546 // Copy so we know the original 547 copy = append([]byte{}, edPub...) 548 549 user.Wipe() 550 551 // First check pre was changed 552 if user.(*pub).pre != '0' { 553 t.Fatalf("Expected prefix to be changed") 554 } 555 556 // Make sure the original key is not equal to the one in memory. 557 if bytes.Equal(edPub, copy) { 558 t.Fatalf("Expected the memory for the pubKey to be randomized") 559 } 560} 561 562const ( 563 nonceRawLen = 16 564 nonceLen = 22 // base64.RawURLEncoding.EncodedLen(nonceRawLen) 565) 566 567func BenchmarkSign(b *testing.B) { 568 data := make([]byte, nonceRawLen) 569 nonce := make([]byte, nonceLen) 570 rand.Read(data) 571 base64.RawURLEncoding.Encode(nonce, data) 572 573 user, err := CreateUser() 574 if err != nil { 575 b.Fatalf("Error creating User Nkey: %v", err) 576 } 577 578 b.ResetTimer() 579 for i := 0; i < b.N; i++ { 580 if _, err := user.Sign(nonce); err != nil { 581 b.Fatalf("Error signing nonce: %v", err) 582 } 583 } 584} 585 586func BenchmarkVerify(b *testing.B) { 587 data := make([]byte, nonceRawLen) 588 nonce := make([]byte, nonceLen) 589 rand.Read(data) 590 base64.RawURLEncoding.Encode(nonce, data) 591 592 user, err := CreateUser() 593 if err != nil { 594 b.Fatalf("Error creating User Nkey: %v", err) 595 } 596 sig, err := user.Sign(nonce) 597 if err != nil { 598 b.Fatalf("Error sigining nonce: %v", err) 599 } 600 601 b.ResetTimer() 602 for i := 0; i < b.N; i++ { 603 if err := user.Verify(nonce, sig); err != nil { 604 b.Fatalf("Error verifying nonce: %v", err) 605 } 606 } 607} 608 609func BenchmarkPublicVerify(b *testing.B) { 610 data := make([]byte, nonceRawLen) 611 nonce := make([]byte, nonceLen) 612 rand.Read(data) 613 base64.RawURLEncoding.Encode(nonce, data) 614 615 user, err := CreateUser() 616 if err != nil { 617 b.Fatalf("Error creating User Nkey: %v", err) 618 } 619 sig, err := user.Sign(nonce) 620 if err != nil { 621 b.Fatalf("Error sigining nonce: %v", err) 622 } 623 pk, err := user.PublicKey() 624 if err != nil { 625 b.Fatalf("Could not extract public key from user: %v", err) 626 } 627 pub, err := FromPublicKey(pk) 628 if err != nil { 629 b.Fatalf("Could not create public key pair from public key string: %v", err) 630 } 631 632 b.ResetTimer() 633 for i := 0; i < b.N; i++ { 634 if err := pub.Verify(nonce, sig); err != nil { 635 b.Fatalf("Error verifying nonce: %v", err) 636 } 637 } 638} 639 640func TestValidateKeyPairRole(t *testing.T) { 641 okp, err := CreateOperator() 642 if err != nil { 643 t.Fatal(err) 644 } 645 akp, err := CreateAccount() 646 if err != nil { 647 t.Fatal(err) 648 } 649 ukp, err := CreateUser() 650 if err != nil { 651 t.Fatal(err) 652 } 653 ckp, err := CreateCluster() 654 if err != nil { 655 t.Fatal(err) 656 } 657 skp, err := CreateServer() 658 if err != nil { 659 t.Fatal(err) 660 } 661 662 var keyroles = []struct { 663 kp KeyPair 664 roles []PrefixByte 665 ok bool 666 name string 667 }{ 668 {kp: okp, name: "want operator", roles: []PrefixByte{PrefixByteOperator}, ok: true}, 669 {kp: akp, name: "want account", roles: []PrefixByte{PrefixByteAccount}, ok: true}, 670 {kp: ukp, name: "want user", roles: []PrefixByte{PrefixByteUser}, ok: true}, 671 {kp: ckp, name: "want cluster", roles: []PrefixByte{PrefixByteCluster}, ok: true}, 672 {kp: skp, name: "want server", roles: []PrefixByte{PrefixByteServer}, ok: true}, 673 674 {kp: okp, name: "want account or operator", roles: []PrefixByte{PrefixByteOperator, PrefixByteAccount}, ok: true}, 675 {kp: akp, name: "want account or operator", roles: []PrefixByte{PrefixByteOperator, PrefixByteAccount}, ok: true}, 676 677 {kp: akp, name: "want operator got account", roles: []PrefixByte{PrefixByteOperator}, ok: false}, 678 {kp: ukp, name: "want account or operator got user", roles: []PrefixByte{PrefixByteOperator, PrefixByteAccount}, ok: false}, 679 } 680 681 for _, e := range keyroles { 682 err := CompatibleKeyPair(e.kp, e.roles...) 683 if err == nil && !e.ok { 684 t.Fatalf("test %q should have failed but didn't", e.name) 685 } 686 if err != nil && e.ok { 687 t.Fatalf("test %q should have not failed: %v", e.name, err) 688 689 } 690 if err != nil && !e.ok && err != ErrIncompatibleKey { 691 t.Fatalf("unexpected error type for %q: %v", e.name, err) 692 } 693 } 694} 695