Cloak/internal/client/auth.go

60 lines
1.9 KiB
Go
Raw Normal View History

2018-10-07 17:09:45 +00:00
package client
import (
"crypto/rand"
"crypto/sha256"
"encoding/binary"
"github.com/cbeuw/Cloak/internal/util"
"github.com/cbeuw/ecies"
)
func MakeRandomField(sta *State) []byte {
t := make([]byte, 8)
binary.BigEndian.PutUint64(t, uint64(sta.Now().Unix()/12*60*60))
rand := util.PsudoRandBytes(16, sta.Now().UnixNano())
preHash := make([]byte, 56)
copy(preHash[0:32], sta.SID)
copy(preHash[32:40], t)
copy(preHash[40:56], rand)
h := sha256.New()
h.Write(preHash)
ret := make([]byte, 32)
copy(ret[0:16], rand)
copy(ret[16:32], h.Sum(nil)[0:16])
return ret
}
func MakeSessionTicket(sta *State) []byte {
t := make([]byte, 8)
binary.BigEndian.PutUint64(t, uint64(sta.Now().Unix()/int64(sta.TicketTimeHint)))
plain := make([]byte, 40)
copy(plain, sta.SID)
copy(plain[32:], t)
// With the default settings (P256, AES128, SHA256) of the ecies package, len(ct)==153.
//
// ciphertext is composed of 3 parts: marshalled X and Y coordinates on the curve,
// iv+ciphertext of the block cipher (aes128 in this case),
// and the hmac which is 32 bytes because it's sha256
//
// The marshalling is done by crypto/elliptic.Marshal. According to the code,
// the size after marshall is 65
//
// IV is 16 bytes. The size of ciphertext is equal to the plaintext, which is 40,
// that is 32 bytes of SID + 8 bytes of timestamp/tickettimehint.
// 16+40 = 56
//
// Then the hmac is 32 bytes
//
// 65+56+32=153
ct, _ := ecies.Encrypt(rand.Reader, sta.Pub, plain, nil, nil)
sessionTicket := make([]byte, 192)
// The reason for ct[1:] is that, the first byte of ct is always 0x04
// This is specified in the section 4.3.6 of ANSI X9.62 (the uncompressed form).
// This is a flag that is useless to us and it will expose our pattern
// (because the sessionTicket isn't fully random anymore). Therefore we drop it.
copy(sessionTicket, ct[1:])
copy(sessionTicket[152:], util.PsudoRandBytes(40, sta.Now().UnixNano()))
return sessionTicket
}