From 02445a8d77af2d91ad2ce1545d5c7d8449a1424c Mon Sep 17 00:00:00 2001 From: 0xluk Date: Fri, 7 Feb 2025 16:37:31 +0200 Subject: [PATCH] added decode and encode passcode to base64; needed for config services --- common/passcode.go | 40 ++++++++++++++++++++++++++++++ common/passcode_test.go | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 common/passcode.go create mode 100644 common/passcode_test.go diff --git a/common/passcode.go b/common/passcode.go new file mode 100644 index 0000000..a9d7f4b --- /dev/null +++ b/common/passcode.go @@ -0,0 +1,40 @@ +package common + +import ( + "bytes" + "encoding/base64" + "encoding/binary" + "github.com/pkg/errors" +) + +func EncodePasscodeToBase64(passcode [4]uint64) (string, error) { + buf := new(bytes.Buffer) + for i, num := range passcode { + err := binary.Write(buf, binary.BigEndian, num) + if err != nil { + return "", errors.Wrapf(err, "writing passcode index %d to buffer", i) + } + } + + return base64.StdEncoding.EncodeToString(buf.Bytes()), nil +} + +func DecodePasscodeFromBase64(encodedPasscode string) ([4]uint64, error) { + var arr [4]uint64 + + // Decode Base64 to raw bytes + data, err := base64.StdEncoding.DecodeString(encodedPasscode) + if err != nil { + return arr, err + } + + // Read the bytes into the uint64 array + buf := bytes.NewReader(data) + for i := range arr { + if err := binary.Read(buf, binary.BigEndian, &arr[i]); err != nil { + return arr, errors.Wrapf(err, "reading passcode index %d from buffer", i) + } + } + + return arr, nil +} diff --git a/common/passcode_test.go b/common/passcode_test.go new file mode 100644 index 0000000..f90e27a --- /dev/null +++ b/common/passcode_test.go @@ -0,0 +1,54 @@ +package common + +import ( + "encoding/base64" + "github.com/stretchr/testify/require" + "testing" +) + +func TestEncodeDecodePasscodeBase64(t *testing.T) { + // Test cases with different uint64 values + tcs := []struct { + name string + passcode [4]uint64 + }{ + {"Zero values", [4]uint64{0, 0, 0, 0}}, + {"Small values", [4]uint64{1, 2, 3, 4}}, + {"Mixed values_1", [4]uint64{123, 456, 789, 101112}}, + {"Mixed values_2", [4]uint64{123, 0, 789, 101112}}, + {"Mixed values_3", [4]uint64{123, 456, 789, 0}}, + {"Mixed values_3", [4]uint64{0, 456, 789, 101112}}, + {"Large values", [4]uint64{18446744073709551615, 9223372036854775807, 1000000000000000000, 500}}, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + // Encode the passcode + encoded, err := EncodePasscodeToBase64(tc.passcode) + require.NoError(t, err, "Failed to encode passcode to Base64") + + // Decode it back + decoded, err := DecodePasscodeFromBase64(encoded) + require.NoError(t, err, "Failed to decode Base64 string") + + require.Equal(t, tc.passcode, decoded, "Decoded passcode does not match original") + }) + } +} + +// TestDecodeInvalidBase64 checks handling of invalid Base64 input +func TestDecodeInvalidBase64(t *testing.T) { + invalidBase64 := "invalid@@@base64##" + + _, err := DecodePasscodeFromBase64(invalidBase64) + require.Error(t, err, "decode passcode should return an error") +} + +// TestDecodeIncorrectSize checks handling of incorrect byte sizes +func TestDecodeIncorrectSize(t *testing.T) { + // Base64-encoded string representing less than 4 * 8 = 32 bytes + incorrectBase64 := base64.StdEncoding.EncodeToString([]byte{1, 2, 3, 4}) + + _, err := DecodePasscodeFromBase64(incorrectBase64) + require.Error(t, err, "decode passcode should return an error") +}