diff --git a/internal/server/TLS.go b/internal/server/TLS.go index 219ab8c..1adfd88 100644 --- a/internal/server/TLS.go +++ b/internal/server/TLS.go @@ -36,7 +36,7 @@ func (TLS) handshake(clientHello []byte, privateKey crypto.PrivateKey, originalC finisher = func(sessionKey []byte) (preparedConn net.Conn, err error) { preparedConn = originalConn - reply, err := composeReply(ch, ai.sharedSecret, sessionKey) + reply, err := composeReply(ch, ai.sharedSecret[:], sessionKey) if err != nil { err = fmt.Errorf("failed to compose TLS reply: %v", err) return @@ -54,24 +54,25 @@ func (TLS) handshake(clientHello []byte, privateKey crypto.PrivateKey, originalC } func unmarshalClientHello(ch *ClientHello, staticPv crypto.PrivateKey) (ai authenticationInfo, err error) { - ai.randPubKey = ch.random - ephPub, ok := ecdh.Unmarshal(ai.randPubKey) + copy(ai.randPubKey[:], ch.random) + ephPub, ok := ecdh.Unmarshal(ai.randPubKey[:]) if !ok { err = ErrInvalidPubKey return } - ai.sharedSecret = ecdh.GenerateSharedSecret(staticPv, ephPub) + copy(ai.sharedSecret[:], ecdh.GenerateSharedSecret(staticPv, ephPub)) var keyShare []byte keyShare, err = parseKeyShare(ch.extensions[[2]byte{0x00, 0x33}]) if err != nil { return } - ai.ciphertextWithTag = append(ch.sessionId, keyShare...) - if len(ai.ciphertextWithTag) != 64 { - err = fmt.Errorf("%v: %v", ErrCiphertextLength, len(ai.ciphertextWithTag)) + ctxTag := append(ch.sessionId, keyShare...) + if len(ctxTag) != 64 { + err = fmt.Errorf("%v: %v", ErrCiphertextLength, len(ctxTag)) return } + copy(ai.ciphertextWithTag[:], ctxTag) return } diff --git a/internal/server/auth.go b/internal/server/auth.go index 6bdc7c5..a0627b7 100644 --- a/internal/server/auth.go +++ b/internal/server/auth.go @@ -22,9 +22,9 @@ type ClientInfo struct { } type authenticationInfo struct { - sharedSecret []byte - randPubKey []byte - ciphertextWithTag []byte + sharedSecret [32]byte + randPubKey [32]byte + ciphertextWithTag [64]byte } const ( @@ -37,7 +37,7 @@ var ErrUnreconisedProtocol = errors.New("unreconised protocol") // touchStone checks if a the authenticationInfo are valid. It doesn't check if the UID is authorised func touchStone(ai authenticationInfo, now func() time.Time) (info ClientInfo, err error) { var plaintext []byte - plaintext, err = util.AESGCMDecrypt(ai.randPubKey[0:12], ai.sharedSecret, ai.ciphertextWithTag) + plaintext, err = util.AESGCMDecrypt(ai.randPubKey[0:12], ai.sharedSecret[:], ai.ciphertextWithTag[:]) if err != nil { return } diff --git a/internal/server/state.go b/internal/server/state.go index 15abe99..1ab2a50 100644 --- a/internal/server/state.go +++ b/internal/server/state.go @@ -232,12 +232,10 @@ func (sta *State) UsedRandomCleaner() { } } -func (sta *State) registerRandom(r []byte) bool { - var random [32]byte - copy(random[:], r) +func (sta *State) registerRandom(r [32]byte) bool { sta.usedRandomM.Lock() - _, used := sta.usedRandom[random] - sta.usedRandom[random] = sta.Now().Unix() + _, used := sta.usedRandom[r] + sta.usedRandom[r] = sta.Now().Unix() sta.usedRandomM.Unlock() return used } diff --git a/internal/server/websocket.go b/internal/server/websocket.go index 7d33c82..175c647 100644 --- a/internal/server/websocket.go +++ b/internal/server/websocket.go @@ -48,7 +48,7 @@ func (WebSocket) handshake(reqPacket []byte, privateKey crypto.PrivateKey, origi rand.Read(nonce) // reply: [12 bytes nonce][32 bytes encrypted session key][16 bytes authentication tag] - encryptedKey, err := util.AESGCMEncrypt(nonce, ai.sharedSecret, sessionKey) // 32 + 16 = 48 bytes + encryptedKey, err := util.AESGCMEncrypt(nonce, ai.sharedSecret[:], sessionKey) // 32 + 16 = 48 bytes if err != nil { err = fmt.Errorf("failed to encrypt reply: %v", err) return @@ -74,19 +74,20 @@ func unmarshalHidden(hidden []byte, staticPv crypto.PrivateKey) (ai authenticati return } - ai.randPubKey = hidden[0:32] - ephPub, ok := ecdh.Unmarshal(ai.randPubKey) + copy(ai.randPubKey[:], hidden[0:32]) + ephPub, ok := ecdh.Unmarshal(ai.randPubKey[:]) if !ok { err = ErrInvalidPubKey return } - ai.sharedSecret = ecdh.GenerateSharedSecret(staticPv, ephPub) + copy(ai.sharedSecret[:], ecdh.GenerateSharedSecret(staticPv, ephPub)) - ai.ciphertextWithTag = hidden[32:] - if len(ai.ciphertextWithTag) != 64 { - err = fmt.Errorf("%v: %v", ErrCiphertextLength, len(ai.ciphertextWithTag)) + if len(hidden[32:]) != 64 { + err = fmt.Errorf("%v: %v", ErrCiphertextLength, len(hidden[32:])) return } + + copy(ai.ciphertextWithTag[:], hidden[32:]) return }