Replace all panics in browserbiometrics with proper error checking
This commit is contained in:
parent
d6e1cd2633
commit
d940af61fa
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
@ -25,44 +26,50 @@ func setupCommunication() {
|
||||
}
|
||||
}
|
||||
|
||||
func dataToBytes(msg SendMessage) []byte {
|
||||
func dataToBytes(msg SendMessage) ([]byte, error) {
|
||||
byteMsg, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to marshal OutgoingMessage struct to slice of bytes: " + err.Error())
|
||||
return nil, fmt.Errorf("unable to marshal OutgoingMessage struct to slice of bytes: %w", err)
|
||||
}
|
||||
return byteMsg
|
||||
return byteMsg, nil
|
||||
}
|
||||
|
||||
func writeMessageLength(msg []byte) {
|
||||
func writeMessageLength(msg []byte) error {
|
||||
err := binary.Write(os.Stdout, nativeEndian, uint32(len(msg)))
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to write message length to Stdout: " + err.Error())
|
||||
return fmt.Errorf("unable to write message length to stdout: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readMessageLength(msg []byte) int {
|
||||
var length uint32
|
||||
func readMessageLength(msg []byte) (int, error) {
|
||||
var length int
|
||||
buf := bytes.NewBuffer(msg)
|
||||
err := binary.Read(buf, nativeEndian, &length)
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to read bytes representing message length:" + err.Error())
|
||||
return 0, fmt.Errorf("Unable to read bytes representing message length: %w", err)
|
||||
}
|
||||
return int(length)
|
||||
return length, nil
|
||||
}
|
||||
|
||||
func send(msg SendMessage) {
|
||||
byteMsg := dataToBytes(msg)
|
||||
func send(msg SendMessage) error {
|
||||
byteMsg, err := dataToBytes(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logging.Debugf("[SENSITIVE] Sending message: " + string(byteMsg))
|
||||
writeMessageLength(byteMsg)
|
||||
err = writeMessageLength(byteMsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var msgBuf bytes.Buffer
|
||||
_, err := msgBuf.Write(byteMsg)
|
||||
_, err = msgBuf.Write(byteMsg)
|
||||
if err != nil {
|
||||
logging.Panicf(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = msgBuf.WriteTo(os.Stdout)
|
||||
if err != nil {
|
||||
logging.Panicf(err.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func pkcs7Pad(b []byte, blocksize int) ([]byte, error) {
|
||||
if blocksize <= 0 {
|
||||
return nil, ErrInvalidBlockSize
|
||||
}
|
||||
if b == nil || len(b) == 0 {
|
||||
if len(b) == 0 {
|
||||
return nil, ErrInvalidPKCS7Data
|
||||
}
|
||||
n := blocksize - (len(b) % blocksize)
|
||||
@ -37,7 +37,7 @@ func pkcs7Unpad(b []byte, blocksize int) ([]byte, error) {
|
||||
if blocksize <= 0 {
|
||||
return nil, ErrInvalidBlockSize
|
||||
}
|
||||
if b == nil || len(b) == 0 {
|
||||
if len(b) == 0 {
|
||||
return nil, ErrInvalidPKCS7Data
|
||||
}
|
||||
if len(b)%blocksize != 0 {
|
||||
@ -56,10 +56,10 @@ func pkcs7Unpad(b []byte, blocksize int) ([]byte, error) {
|
||||
return b[:len(b)-n], nil
|
||||
}
|
||||
|
||||
func decryptStringSymmetric(key []byte, ivb64 string, data string) string {
|
||||
func decryptStringSymmetric(key []byte, ivb64 string, data string) (string, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return "", err
|
||||
}
|
||||
iv, _ := base64.StdEncoding.DecodeString(ivb64)
|
||||
ciphertext, _ := base64.StdEncoding.DecodeString(data)
|
||||
@ -67,19 +67,19 @@ func decryptStringSymmetric(key []byte, ivb64 string, data string) string {
|
||||
bm.CryptBlocks(ciphertext, ciphertext)
|
||||
ciphertext, _ = pkcs7Unpad(ciphertext, aes.BlockSize)
|
||||
|
||||
return string(ciphertext)
|
||||
return string(ciphertext), nil
|
||||
}
|
||||
|
||||
func encryptStringSymmetric(key []byte, data []byte) EncryptedString {
|
||||
func encryptStringSymmetric(key []byte, data []byte) (EncryptedString, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return EncryptedString{}, err
|
||||
}
|
||||
data, _ = pkcs7Pad(data, block.BlockSize())
|
||||
ciphertext := make([]byte, aes.BlockSize+len(data))
|
||||
iv := ciphertext[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
panic(err)
|
||||
return EncryptedString{}, err
|
||||
}
|
||||
bm := cipher.NewCBCEncrypter(block, iv)
|
||||
bm.CryptBlocks(ciphertext[aes.BlockSize:], data)
|
||||
@ -88,15 +88,15 @@ func encryptStringSymmetric(key []byte, data []byte) EncryptedString {
|
||||
IV: base64.StdEncoding.EncodeToString(ciphertext[:aes.BlockSize]),
|
||||
Data: base64.StdEncoding.EncodeToString(ciphertext[aes.BlockSize:]),
|
||||
EncType: 0,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func generateTransportKey() []byte {
|
||||
func generateTransportKey() ([]byte, error) {
|
||||
key := make([]byte, 32)
|
||||
if _, err := io.ReadFull(rand.Reader, key); err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
return key
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func rsaEncrypt(keyB64 string, message []byte) (string, error) {
|
||||
|
@ -26,13 +26,17 @@ const appID = "com.quexten.bw-bio-handler"
|
||||
|
||||
var transportKey []byte
|
||||
|
||||
func Main(rtCfg *config.RuntimeConfig) {
|
||||
func Main(rtCfg *config.RuntimeConfig) error {
|
||||
logging.Debugf("Starting browserbiometrics")
|
||||
transportKey = generateTransportKey()
|
||||
var err error
|
||||
transportKey, err = generateTransportKey()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.Debugf("Generated transport key")
|
||||
|
||||
setupCommunication()
|
||||
readLoop(rtCfg)
|
||||
return readLoop(rtCfg)
|
||||
}
|
||||
|
||||
func DetectAndInstallBrowsers() error {
|
||||
|
@ -3,6 +3,7 @@ package browserbiometrics
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
@ -14,7 +15,7 @@ import (
|
||||
|
||||
var runtimeConfig *config.RuntimeConfig
|
||||
|
||||
func readLoop(rtCfg *config.RuntimeConfig) {
|
||||
func readLoop(rtCfg *config.RuntimeConfig) error {
|
||||
runtimeConfig = rtCfg
|
||||
v := bufio.NewReader(os.Stdin)
|
||||
s := bufio.NewReaderSize(v, bufferSize)
|
||||
@ -23,64 +24,86 @@ func readLoop(rtCfg *config.RuntimeConfig) {
|
||||
lengthNum := int(0)
|
||||
|
||||
logging.Debugf("Sending connected message")
|
||||
send(SendMessage{
|
||||
err := send(SendMessage{
|
||||
Command: "connected",
|
||||
AppID: appID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logging.Debugf("Starting read loop")
|
||||
for b, err := s.Read(lengthBytes); b > 0 && err == nil; b, err = s.Read(lengthBytes) {
|
||||
lengthNum = readMessageLength(lengthBytes)
|
||||
lengthNum, err = readMessageLength(lengthBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := make([]byte, lengthNum)
|
||||
_, err := s.Read(content)
|
||||
if err != nil && err != io.EOF {
|
||||
logging.Panicf(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
parseMessage(content)
|
||||
err = parseMessage(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseMessage(msg []byte) {
|
||||
func parseMessage(msg []byte) error {
|
||||
logging.Debugf("Received message: " + string(msg))
|
||||
|
||||
var genericMessage GenericRecvMessage
|
||||
err := json.Unmarshal(msg, &genericMessage)
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to unmarshal json to struct: " + err.Error())
|
||||
return fmt.Errorf("unable to unmarshal json to struct: %w", err)
|
||||
}
|
||||
|
||||
if _, ok := (genericMessage.Message.(map[string]interface{})["command"]); ok {
|
||||
logging.Debugf("Message is unencrypted")
|
||||
|
||||
var unmsg UnencryptedRecvMessage
|
||||
err := json.Unmarshal(msg, &unmsg)
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to unmarshal json to struct: " + err.Error())
|
||||
return fmt.Errorf("unable to unmarshal json to struct: %w", err)
|
||||
}
|
||||
|
||||
handleUnencryptedMessage(unmsg)
|
||||
err = handleUnencryptedMessage(unmsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
logging.Debugf("Message is encrypted")
|
||||
|
||||
var encmsg EncryptedRecvMessage
|
||||
err := json.Unmarshal(msg, &encmsg)
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to unmarshal json to struct: " + err.Error())
|
||||
return fmt.Errorf("unable to unmarshal json to struct: %w", err)
|
||||
}
|
||||
|
||||
decryptedMessage := decryptStringSymmetric(transportKey, encmsg.Message.IV, encmsg.Message.Data)
|
||||
decryptedMessage, err := decryptStringSymmetric(transportKey, encmsg.Message.IV, encmsg.Message.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var payloadMsg PayloadMessage
|
||||
err = json.Unmarshal([]byte(decryptedMessage), &payloadMsg)
|
||||
if err != nil {
|
||||
logging.Panicf("Unable to unmarshal json to struct: " + err.Error())
|
||||
return fmt.Errorf("unable to unmarshal json to struct: %w", err)
|
||||
}
|
||||
|
||||
handlePayloadMessage(payloadMsg, genericMessage.AppID)
|
||||
err = handlePayloadMessage(payloadMsg, genericMessage.AppID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleUnencryptedMessage(msg UnencryptedRecvMessage) {
|
||||
func handleUnencryptedMessage(msg UnencryptedRecvMessage) error {
|
||||
logging.Debugf("Received unencrypted message: %+v", msg.Message)
|
||||
logging.Debugf(" with command: %s", msg.Message.Command)
|
||||
|
||||
@ -88,17 +111,22 @@ func handleUnencryptedMessage(msg UnencryptedRecvMessage) {
|
||||
case "setupEncryption":
|
||||
sharedSecret, err := rsaEncrypt(msg.Message.PublicKey, transportKey)
|
||||
if err != nil {
|
||||
logging.Panicf(err.Error())
|
||||
return err
|
||||
}
|
||||
send(SendMessage{
|
||||
err = send(SendMessage{
|
||||
Command: "setupEncryption",
|
||||
AppID: msg.AppID,
|
||||
SharedSecret: sharedSecret,
|
||||
})
|
||||
break
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func handlePayloadMessage(msg PayloadMessage, appID string) {
|
||||
|
||||
func handlePayloadMessage(msg PayloadMessage, appID string) error {
|
||||
logging.Debugf("Received unencrypted message: %+v", msg)
|
||||
|
||||
switch msg.Command {
|
||||
@ -108,7 +136,7 @@ func handlePayloadMessage(msg PayloadMessage, appID string) {
|
||||
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if runtimeConfig.GoldwardenSocketPath == "" {
|
||||
@ -127,16 +155,12 @@ func handlePayloadMessage(msg PayloadMessage, appID string) {
|
||||
|
||||
result, err := client.NewUnixSocketClient(runtimeConfig).SendToAgent(messages.GetBiometricsKeyRequest{})
|
||||
if err != nil {
|
||||
logging.Errorf("Unable to send message to agent: %s", err.Error())
|
||||
return
|
||||
return fmt.Errorf("Unable to send message to agent: %w", err)
|
||||
}
|
||||
switch result.(type) {
|
||||
case messages.GetBiometricsKeyResponse:
|
||||
if err != nil {
|
||||
logging.Panicf(err.Error())
|
||||
}
|
||||
|
||||
var key = result.(messages.GetBiometricsKeyResponse).Key
|
||||
switch result := result.(type) {
|
||||
case messages.GetBiometricsKeyResponse:
|
||||
var key = result.Key
|
||||
var payloadMsg ReceiveMessage = ReceiveMessage{
|
||||
Command: "biometricUnlock",
|
||||
Response: "unlocked",
|
||||
@ -145,18 +169,23 @@ func handlePayloadMessage(msg PayloadMessage, appID string) {
|
||||
}
|
||||
payloadStr, err := json.Marshal(payloadMsg)
|
||||
if err != nil {
|
||||
logging.Panicf(err.Error())
|
||||
return err
|
||||
}
|
||||
logging.Debugf("Payload: %s", payloadStr)
|
||||
|
||||
encStr := encryptStringSymmetric(transportKey, payloadStr)
|
||||
send(SendMessage{
|
||||
encStr, err := encryptStringSymmetric(transportKey, payloadStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = send(SendMessage{
|
||||
AppID: appID,
|
||||
Message: encStr,
|
||||
})
|
||||
break
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user