diff options
Diffstat (limited to 'crypto/recovery_test.go')
| -rw-r--r-- | crypto/recovery_test.go | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/crypto/recovery_test.go b/crypto/recovery_test.go new file mode 100644 index 0000000..2ee18f0 --- /dev/null +++ b/crypto/recovery_test.go @@ -0,0 +1,215 @@ +/* + * recovery_test.go - tests for recovery codes in the crypto package + * tests key wrapping/unwrapping and key generation + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package crypto + +import ( + "bytes" + "fmt" + "testing" +) + +const fakeSecretRecoveryCode = "EYTCMJRG-EYTCMJRG-EYTCMJRG-EYTCMJRG-EYTCMJRG-EYTCMJRG-EYTA====" + +var fakeSecretKey, _ = makeKey(38, InternalKeyLen) + +// Note that this function is INSECURE. FOR TESTING ONLY +func getRecoveryCodeFromKey(key *Key) ([]byte, error) { + var buf bytes.Buffer + if err := WriteRecoveryCode(key, &buf); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func getRandomRecoveryCodeBuffer() ([]byte, error) { + key, err := NewRandomKey(InternalKeyLen) + if err != nil { + return nil, err + } + return getRecoveryCodeFromKey(key) +} + +func getKeyFromRecoveryCode(buf []byte) (*Key, error) { + return ReadRecoveryCode(bytes.NewReader(buf)) +} + +// Given a key, make a recovery code from that key, use that code to rederive +// another key and check if they are the same. +func testKeyEncodeDecode(key *Key) error { + buf, err := getRecoveryCodeFromKey(key) + if err != nil { + return err + } + + key2, err := getKeyFromRecoveryCode(buf) + if err != nil { + return err + } + + if !bytes.Equal(key.data, key2.data) { + return fmt.Errorf("encoding then decoding %x didn't yield the same key", key.data) + } + return nil +} + +// Given a recovery code, make a key from that recovery code, use that key to +// rederive another recovery code and check if they are the same. +func testRecoveryDecodeEncode(buf []byte) error { + key, err := getKeyFromRecoveryCode(buf) + if err != nil { + return err + } + + buf2, err := getRecoveryCodeFromKey(key) + if err != nil { + return err + } + + if !bytes.Equal(buf, buf2) { + return fmt.Errorf("decoding then encoding %x didn't yield the same key", buf) + } + return nil +} + +func TestGetRandomRecoveryString(t *testing.T) { + b, err := getRandomRecoveryCodeBuffer() + if err != nil { + t.Fatal(err) + } + + t.Log(string(b)) + // t.Fail() // Uncomment to see an example random recovery code +} + +func TestFakeSecretKey(t *testing.T) { + buf, err := getRecoveryCodeFromKey(fakeSecretKey) + if err != nil { + t.Fatal(err) + } + + recoveryCode := string(buf) + if recoveryCode != fakeSecretRecoveryCode { + t.Errorf("got '%s' instead of '%s'", recoveryCode, fakeSecretRecoveryCode) + } +} + +func TestEncodeDecode(t *testing.T) { + key, err := NewRandomKey(InternalKeyLen) + if err != nil { + t.Fatal(err) + } + + if err = testKeyEncodeDecode(key); err != nil { + t.Error(err) + } +} + +func TestDecodeEncode(t *testing.T) { + buf, err := getRandomRecoveryCodeBuffer() + if err != nil { + t.Fatal(err) + } + + if err = testRecoveryDecodeEncode(buf); err != nil { + t.Error(err) + } +} + +func TestWrongLengthError(t *testing.T) { + key, err := NewRandomKey(InternalKeyLen - 1) + if err != nil { + t.Fatal(err) + } + + if _, err = getRecoveryCodeFromKey(key); err == nil { + t.Error("key with wrong length should have failed to encode") + } +} + +func TestBadCharacterError(t *testing.T) { + buf, err := getRandomRecoveryCodeBuffer() + // Lowercase letters not allowed + buf[3] = 'k' + if _, err = getKeyFromRecoveryCode(buf); err == nil { + t.Error("lowercase letters should make decoding fail") + } +} + +func TestBadEndCharacterError(t *testing.T) { + buf, err := getRandomRecoveryCodeBuffer() + // Separator must be '-' + buf[blockSize] = '_' + if _, err = getKeyFromRecoveryCode(buf); err == nil { + t.Error("any separator that isn't '-' should make decoding fail") + } +} + +func BenchmarkEncode(b *testing.B) { + key, err := NewRandomKey(InternalKeyLen) + if err != nil { + b.Fatal(err) + } + + for n := 0; n < b.N; n++ { + if _, err = getRecoveryCodeFromKey(key); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkDecode(b *testing.B) { + buf, err := getRandomRecoveryCodeBuffer() + if err != nil { + b.Fatal(err) + } + + for n := 0; n < b.N; n++ { + if _, err = getKeyFromRecoveryCode(buf); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkEncodeDecode(b *testing.B) { + key, err := NewRandomKey(InternalKeyLen) + if err != nil { + b.Fatal(err) + } + + for n := 0; n < b.N; n++ { + if err = testKeyEncodeDecode(key); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkDecodeEncode(b *testing.B) { + buf, err := getRandomRecoveryCodeBuffer() + if err != nil { + b.Fatal(err) + } + + for n := 0; n < b.N; n++ { + if err = testRecoveryDecodeEncode(buf); err != nil { + b.Fatal(err) + } + } +} |