github.com/decred/dcrlnd@v0.7.6/chanbackup/crypto_test.go (about) 1 package chanbackup 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 8 "github.com/decred/dcrd/dcrec/secp256k1/v4" 9 "github.com/decred/dcrlnd/keychain" 10 ) 11 12 var ( 13 testWalletPrivKey = []byte{ 14 0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf, 15 0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9, 16 0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f, 17 0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90, 18 } 19 ) 20 21 type mockKeyRing struct { 22 fail bool 23 } 24 25 func (m *mockKeyRing) DeriveNextKey(keyFam keychain.KeyFamily) (keychain.KeyDescriptor, error) { 26 return keychain.KeyDescriptor{}, nil 27 } 28 func (m *mockKeyRing) DeriveKey(keyLoc keychain.KeyLocator) (keychain.KeyDescriptor, error) { 29 if m.fail { 30 return keychain.KeyDescriptor{}, fmt.Errorf("fail") 31 } 32 33 pub := secp256k1.PrivKeyFromBytes(testWalletPrivKey).PubKey() 34 return keychain.KeyDescriptor{ 35 PubKey: pub, 36 }, nil 37 } 38 39 // TestEncryptDecryptPayload tests that given a static key, we're able to 40 // properly decrypt and encrypted payload. We also test that we'll reject a 41 // ciphertext that has been modified. 42 func TestEncryptDecryptPayload(t *testing.T) { 43 t.Parallel() 44 45 payloadCases := []struct { 46 // plaintext is the string that we'll be encrypting. 47 plaintext []byte 48 49 // mutator allows a test case to modify the ciphertext before 50 // we attempt to decrypt it. 51 mutator func(*[]byte) 52 53 // valid indicates if this test should pass or fail. 54 valid bool 55 }{ 56 // Proper payload, should decrypt. 57 { 58 plaintext: []byte("payload test plain text"), 59 mutator: nil, 60 valid: true, 61 }, 62 63 // Mutator modifies cipher text, shouldn't decrypt. 64 { 65 plaintext: []byte("payload test plain text"), 66 mutator: func(p *[]byte) { 67 // Flip a byte in the payload to render it invalid. 68 (*p)[0] ^= 1 69 }, 70 valid: false, 71 }, 72 73 // Cipher text is too small, shouldn't decrypt. 74 { 75 plaintext: []byte("payload test plain text"), 76 mutator: func(p *[]byte) { 77 // Modify the cipher text to be zero length. 78 *p = []byte{} 79 }, 80 valid: false, 81 }, 82 } 83 84 keyRing := &mockKeyRing{} 85 86 for i, payloadCase := range payloadCases { 87 var cipherBuffer bytes.Buffer 88 89 // First, we'll encrypt the passed payload with our scheme. 90 payloadReader := bytes.NewBuffer(payloadCase.plaintext) 91 err := encryptPayloadToWriter( 92 *payloadReader, &cipherBuffer, keyRing, 93 ) 94 if err != nil { 95 t.Fatalf("unable encrypt paylaod: %v", err) 96 } 97 98 // If we have a mutator, then we'll wrong the mutator over the 99 // cipher text, then reset the main buffer and re-write the new 100 // cipher text. 101 if payloadCase.mutator != nil { 102 cipherText := cipherBuffer.Bytes() 103 104 payloadCase.mutator(&cipherText) 105 106 cipherBuffer.Reset() 107 cipherBuffer.Write(cipherText) 108 } 109 110 plaintext, err := decryptPayloadFromReader(&cipherBuffer, keyRing) 111 112 switch { 113 // If this was meant to be a valid decryption, but we failed, 114 // then we'll return an error. 115 case err != nil && payloadCase.valid: 116 t.Fatalf("unable to decrypt valid payload case %v", i) 117 118 // If this was meant to be an invalid decryption, and we didn't 119 // fail, then we'll return an error. 120 case err == nil && !payloadCase.valid: 121 t.Fatalf("payload was invalid yet was able to decrypt") 122 } 123 124 // Only if this case was mean to be valid will we ensure the 125 // resulting decrypted plaintext matches the original input. 126 if payloadCase.valid && 127 !bytes.Equal(plaintext, payloadCase.plaintext) { 128 t.Fatalf("#%v: expected %v, got %v: ", i, 129 payloadCase.plaintext, plaintext) 130 } 131 } 132 } 133 134 // TestInvalidKeyEncryption tests that encryption fails if we're unable to 135 // obtain a valid key. 136 func TestInvalidKeyEncryption(t *testing.T) { 137 t.Parallel() 138 139 var b bytes.Buffer 140 err := encryptPayloadToWriter(b, &b, &mockKeyRing{true}) 141 if err == nil { 142 t.Fatalf("expected error due to fail key gen") 143 } 144 } 145 146 // TestInvalidKeyDecrytion tests that decryption fails if we're unable to 147 // obtain a valid key. 148 func TestInvalidKeyDecrytion(t *testing.T) { 149 t.Parallel() 150 151 var b bytes.Buffer 152 _, err := decryptPayloadFromReader(&b, &mockKeyRing{true}) 153 if err == nil { 154 t.Fatalf("expected error due to fail key gen") 155 } 156 }