github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/pkg/crypto/mac_test.go (about) 1 package crypto 2 3 import ( 4 "math/rand" 5 "reflect" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 ) 12 13 var testStrings = []string{"foo", "bar", "baz"} 14 15 func TestMACMessageWithName(t *testing.T) { 16 value := []byte("myvalue") 17 18 k1 := []byte("0123456789012345") 19 k2 := []byte("0123456789012345") 20 k3 := []byte("9876543210987654") 21 o1 := MACConfig{Name: "message1"} 22 o2 := MACConfig{Name: ""} 23 o3 := MACConfig{Name: "message1"} 24 25 encoded, err1 := EncodeAuthMessage(o1, k1, value, nil) 26 require.NoError(t, err1) 27 28 v, err2 := DecodeAuthMessage(o1, k1, encoded, nil) 29 require.NoError(t, err2) 30 31 if !assert.EqualValues(t, v, value) { 32 t.Fatalf("Expected %v, got %v.", v, value) 33 } 34 _, err3 := DecodeAuthMessage(o2, k2, encoded, nil) 35 require.Error(t, err3) 36 37 _, err4 := DecodeAuthMessage(o3, k3, encoded, nil) 38 require.Error(t, err4) 39 40 _, err5 := DecodeAuthMessage(o1, k1, encoded, []byte("plop")) 41 require.Error(t, err5) 42 43 encoded2, err6 := EncodeAuthMessage(o1, k1, value, []byte("foo")) 44 require.NoError(t, err6) 45 46 _, err7 := DecodeAuthMessage(o1, k1, encoded2, []byte("foo")) 47 require.NoError(t, err7) 48 49 _, err8 := DecodeAuthMessage(o1, k1, encoded2, []byte("plop")) 50 require.Error(t, err8) 51 } 52 53 func TestMACMessageWithoutName(t *testing.T) { 54 value := []byte("myvalue") 55 56 k1 := []byte("0123456789012345") 57 k2 := []byte("0123456789012345") 58 k3 := []byte("9876543210987654") 59 o1 := MACConfig{Name: ""} 60 o2 := MACConfig{Name: "message1"} 61 o3 := MACConfig{Name: ""} 62 63 encoded, err1 := EncodeAuthMessage(o1, k1, value, nil) 64 require.NoError(t, err1) 65 66 v, err2 := DecodeAuthMessage(o1, k1, encoded, nil) 67 require.NoError(t, err2) 68 69 if !reflect.DeepEqual(v, value) { 70 t.Fatalf("Expected %v, got %v.", value, v) 71 } 72 _, err3 := DecodeAuthMessage(o2, k2, encoded, nil) 73 require.Error(t, err3) 74 75 _, err4 := DecodeAuthMessage(o3, k3, encoded, nil) 76 require.Error(t, err4) 77 } 78 79 func TestMACWrongMessage(t *testing.T) { 80 k := []byte("0123456789012345") 81 o := MACConfig{ 82 Name: "name", 83 MaxLen: 256, 84 } 85 86 { 87 _, err := DecodeAuthMessage(o, k, []byte(""), nil) 88 require.Equal(t, errMACInvalid, err) 89 } 90 91 { 92 _, err := DecodeAuthMessage(o, k, []byte("ccc"), nil) 93 require.Equal(t, errMACInvalid, err) 94 } 95 96 { 97 buf := Base64Encode(GenerateRandomBytes(32)) 98 _, err := DecodeAuthMessage(o, k, buf, nil) 99 require.Equal(t, errMACInvalid, err) 100 } 101 102 { 103 buf := Base64Encode(createMAC(k, []byte(""))) 104 _, err := DecodeAuthMessage(o, k, buf, nil) 105 require.Equal(t, errMACInvalid, err) 106 } 107 108 rng := rand.New(rand.NewSource(time.Now().UnixNano())) 109 for i := 0; i < 10000; i++ { 110 buf := Base64Encode(GenerateRandomBytes(rng.Intn(1000))) 111 _, err := DecodeAuthMessage(o, k, buf, nil) 112 require.Equal(t, errMACInvalid, err) 113 } 114 } 115 116 func TestMACMaxAge(t *testing.T) { 117 key := GenerateRandomBytes(16) 118 val := []byte("coucou") 119 add := []byte("additional") 120 c1 := MACConfig{ 121 Name: "max", 122 MaxAge: 1 * time.Second, 123 } 124 c2 := MACConfig{ 125 Name: "max", 126 MaxAge: 10 * time.Second, 127 } 128 129 var msg1, msg2 []byte 130 131 { 132 var err error 133 msg1, err = EncodeAuthMessage(c1, key, val, add) 134 require.NoError(t, err) 135 136 msg2, err = EncodeAuthMessage(c2, key, val, add) 137 require.NoError(t, err) 138 } 139 140 { 141 ret1, err := DecodeAuthMessage(c1, key, msg1, add) 142 require.NoError(t, err) 143 144 assert.Equal(t, val, ret1) 145 146 ret2, err := DecodeAuthMessage(c2, key, msg2, add) 147 require.NoError(t, err) 148 149 assert.Equal(t, val, ret2) 150 } 151 152 time.Sleep(1500 * time.Millisecond) 153 154 { 155 ret1, err := DecodeAuthMessage(c1, key, msg1, add) 156 assert.Error(t, err) 157 assert.Nil(t, ret1) 158 assert.Equal(t, errMACExpired, err) 159 160 ret2, err := DecodeAuthMessage(c2, key, msg2, add) 161 assert.NoError(t, err) 162 assert.Equal(t, val, ret2) 163 } 164 } 165 166 func TestAuthentication(t *testing.T) { 167 hashKey := []byte("secret-key") 168 for _, value := range testStrings { 169 mac := createMAC(hashKey, []byte(value)) 170 require.Len(t, mac, macLen) 171 172 ok1 := verifyMAC(hashKey, []byte(value), mac) 173 require.True(t, ok1) 174 175 ok2 := verifyMAC(hashKey, GenerateRandomBytes(32), mac) 176 require.False(t, ok2) 177 } 178 }