mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 17:44:35 +03:00
mox!
This commit is contained in:
61
mox-/recvid.go
Normal file
61
mox-/recvid.go
Normal file
@ -0,0 +1,61 @@
|
||||
package mox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var idCipher cipher.Block
|
||||
var idRand []byte
|
||||
|
||||
func init() {
|
||||
// Init for tests. Overwritten in ../serve.go.
|
||||
err := ReceivedIDInit([]byte("0123456701234567"), []byte("01234567"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// ReceivedIDInit sets an AES key (must be 16 bytes) and random buffer (must be
|
||||
// 8 bytes) for use by ReceivedID.
|
||||
func ReceivedIDInit(key, rand []byte) error {
|
||||
var err error
|
||||
idCipher, err = aes.NewCipher(key)
|
||||
idRand = rand
|
||||
return err
|
||||
}
|
||||
|
||||
// ReceivedID returns an ID for use in a message Received header.
|
||||
//
|
||||
// The ID is based on the cid. The cid itself is a counter and would leak the
|
||||
// number of connections in received headers. Instead they are obfuscated by
|
||||
// encrypting them with AES with a per-install key and random buffer. This allows
|
||||
// recovery of the cid based on the id. See subcommand cid.
|
||||
func ReceivedID(cid int64) string {
|
||||
buf := make([]byte, 16)
|
||||
copy(buf, idRand)
|
||||
binary.BigEndian.PutUint64(buf[8:], uint64(cid))
|
||||
idCipher.Encrypt(buf, buf)
|
||||
return base64.RawURLEncoding.EncodeToString(buf)
|
||||
}
|
||||
|
||||
// ReceivedToCid returns the cid given a ReceivedID.
|
||||
func ReceivedToCid(s string) (cid int64, err error) {
|
||||
buf, err := base64.RawURLEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("decode base64: %v", err)
|
||||
}
|
||||
if len(buf) != 16 {
|
||||
return 0, fmt.Errorf("bad length, got %d, expect 16", len(buf))
|
||||
}
|
||||
idCipher.Decrypt(buf, buf)
|
||||
if !bytes.Equal(buf[:8], idRand) {
|
||||
return 0, fmt.Errorf("rand mismatch")
|
||||
}
|
||||
cid = int64(binary.BigEndian.Uint64(buf[8:]))
|
||||
return cid, nil
|
||||
}
|
Reference in New Issue
Block a user