Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 1 | package security |
| 2 | |
| 3 | import ( |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 4 | "crypto/ecdsa" |
| 5 | "crypto/elliptic" |
| 6 | "crypto/rand" |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 7 | "io/ioutil" |
| 8 | "os" |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 9 | "path" |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 10 | "testing" |
| 11 | ) |
| 12 | |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 13 | func TestLoadPersistentPrincipal(t *testing.T) { |
| 14 | // If the directory does not exist want os.IsNotExists. |
| 15 | _, err := LoadPersistentPrincipal("/tmp/fake/path/", nil) |
| 16 | if !os.IsNotExist(err) { |
| 17 | t.Errorf("invalid path should return does not exist error, instead got %v", err) |
| 18 | } |
| 19 | // If the key file exists and is unencrypted we should succeed. |
| 20 | dir := generatePEMFile(nil) |
| 21 | if _, err = LoadPersistentPrincipal(dir, nil); err != nil { |
| 22 | t.Errorf("unencrypted LoadPersistentPrincipal should have succeeded: %v", err) |
| 23 | } |
| 24 | os.RemoveAll(dir) |
| 25 | |
| 26 | // If the private key file exists and is encrypted we should succeed with correct passphrase. |
| 27 | passphrase := []byte("passphrase") |
| 28 | incorrect_passphrase := []byte("incorrect_passphrase") |
| 29 | dir = generatePEMFile(passphrase) |
| 30 | if _, err = LoadPersistentPrincipal(dir, passphrase); err != nil { |
| 31 | t.Errorf("encrypted LoadPersistentPrincipal should have succeeded: %v", err) |
| 32 | } |
| 33 | // and fail with an incorrect passphrase. |
| 34 | if _, err = LoadPersistentPrincipal(dir, incorrect_passphrase); err == nil { |
| 35 | t.Errorf("encrypted LoadPersistentPrincipal with incorrect passphrase should fail") |
| 36 | } |
Suharsh Sivakumar | 4684f4e | 2014-10-24 13:42:06 -0700 | [diff] [blame] | 37 | // and return PassphraseError if the passphrase is nil. |
| 38 | if _, err = LoadPersistentPrincipal(dir, nil); err != PassphraseErr { |
| 39 | t.Errorf("encrypted LoadPersistentPrincipal with nil passphrase should return PassphraseErr: %v", err) |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 40 | } |
| 41 | os.RemoveAll(dir) |
| 42 | } |
| 43 | |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 44 | // This Test checks that the all changes made to the principal's serialization |
| 45 | // format stay backwards compatible. |
| 46 | // |
| 47 | // The 'testdata' directory used by this test was generated using the |
| 48 | // principal tool as part of CL #6820. |
| 49 | // $VEYRON_BIN/principal create testdata test |
| 50 | func TestLoadPersistentPrincipalBackwardsCompatibility(t *testing.T) { |
| 51 | if _, err := LoadPersistentPrincipal("./testdata", nil); err != nil { |
| 52 | t.Fatal("LoadPersistentPrincipal is not backwards compatible: failed to read serialized principal data from CL #6820") |
| 53 | } |
| 54 | } |
| 55 | |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 56 | func TestCreatePersistentPrincipal(t *testing.T) { |
| 57 | tests := []struct { |
| 58 | Message, Passphrase []byte |
| 59 | }{ |
| 60 | {[]byte("unencrypted"), nil}, |
| 61 | {[]byte("encrypted"), []byte("passphrase")}, |
| 62 | } |
| 63 | for _, test := range tests { |
| 64 | testCreatePersistentPrincipal(t, test.Message, test.Passphrase) |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | func testCreatePersistentPrincipal(t *testing.T, message, passphrase []byte) { |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 69 | // Persistence of the BlessingRoots and BlessingStore objects is |
| 70 | // tested in other files. Here just test the persistence of the key. |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 71 | dir, err := ioutil.TempDir("", "TestCreatePersistentPrincipal") |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 72 | if err != nil { |
| 73 | t.Fatal(err) |
| 74 | } |
| 75 | defer os.RemoveAll(dir) |
| 76 | |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 77 | p, err := CreatePersistentPrincipal(dir, passphrase) |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 78 | if err != nil { |
| 79 | t.Fatal(err) |
| 80 | } |
gauthamt | b7bb39b | 2014-11-10 11:40:41 -0800 | [diff] [blame] | 81 | _, err = CreatePersistentPrincipal(dir, passphrase) |
Ankur | 4704f5f | 2014-10-23 12:40:54 -0700 | [diff] [blame] | 82 | if err == nil { |
| 83 | t.Error("CreatePersistentPrincipal passed unexpectedly") |
| 84 | } |
Ankur | 4704f5f | 2014-10-23 12:40:54 -0700 | [diff] [blame] | 85 | |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 86 | sig, err := p.Sign(message) |
| 87 | if err != nil { |
| 88 | t.Fatal(err) |
| 89 | } |
| 90 | |
Ankur | 4704f5f | 2014-10-23 12:40:54 -0700 | [diff] [blame] | 91 | p2, err := LoadPersistentPrincipal(dir, passphrase) |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 92 | if err != nil { |
Suharsh Sivakumar | 8a7fba4 | 2014-10-27 12:40:48 -0700 | [diff] [blame] | 93 | t.Fatalf("%s failed: %v", message, err) |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 94 | } |
Ankur | 4704f5f | 2014-10-23 12:40:54 -0700 | [diff] [blame] | 95 | if !sig.Verify(p2.PublicKey(), message) { |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 96 | t.Errorf("%s failed: p.PublicKey=%v, p2.PublicKey=%v", message, p.PublicKey(), p2.PublicKey()) |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 97 | } |
| 98 | } |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 99 | |
| 100 | func generatePEMFile(passphrase []byte) (dir string) { |
| 101 | dir, err := ioutil.TempDir("", "TestLoadPersistentPrincipal") |
| 102 | if err != nil { |
| 103 | panic(err) |
| 104 | } |
| 105 | key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 106 | if err != nil { |
| 107 | panic(err) |
| 108 | } |
| 109 | f, err := os.Create(path.Join(dir, privateKeyFile)) |
| 110 | if err != nil { |
| 111 | panic(err) |
| 112 | } |
| 113 | defer f.Close() |
Ankur | 73e7a93 | 2014-10-24 15:57:03 -0700 | [diff] [blame] | 114 | if err = SavePEMKey(f, key, passphrase); err != nil { |
Suharsh Sivakumar | aca1c32 | 2014-10-21 11:27:32 -0700 | [diff] [blame] | 115 | panic(err) |
| 116 | } |
| 117 | return dir |
| 118 | } |