--- /dev/null +++ b/protocol/obfhttp/encoding.go @@ -0,0 +1,60 @@ +// OMV +package obfhttp + +import ( + "crypto/rand" + "encoding/base64" + "math/big" +) + +// TextCodec encodes binary data to text-safe strings and generates padding in the same alphabet. +type TextCodec interface { + Encode(data []byte) string + Decode(text string) ([]byte, error) + Name() string + GeneratePadding(length int) string +} + +// Base64Codec uses standard base64 encoding. +type Base64Codec struct{} + +func (c *Base64Codec) Encode(data []byte) string { + return base64.StdEncoding.EncodeToString(data) +} + +func (c *Base64Codec) Decode(text string) ([]byte, error) { + return base64.StdEncoding.DecodeString(text) +} + +func (c *Base64Codec) Name() string { + return "base64" +} + +func (c *Base64Codec) GeneratePadding(length int) string { + if length <= 0 { + return "" + } + // Generate random bytes and encode to base64, then trim to desired length + rawLen := (length*3)/4 + 1 + raw := make([]byte, rawLen) + _, _ = rand.Read(raw) + encoded := base64.StdEncoding.EncodeToString(raw) + if len(encoded) > length { + encoded = encoded[:length] + } + return encoded +} + +func newTextCodec(name string) TextCodec { + switch name { + case "", "base64": + return &Base64Codec{} + default: + return &Base64Codec{} + } +} + +func randomPaddingLength() int { + n, _ := rand.Int(rand.Reader, big.NewInt(128)) + return int(n.Int64()) + 16 // 16-143 chars +}