cacert-gosigner/client/io.go
Jan Dittberner 42d1e6e991 Refactor client into separate files
Add a main loop, move I/O code into io.go, move configuration into config.go.
Use shared.Decode24BitLength instead of manually decoding block lengths.
Fix response block decoding and checksum validation.
Add constants for commonly used byte values and use these in the signer and
the client.
2020-04-17 19:39:01 +02:00

99 lines
2.6 KiB
Go

package main
import (
"errors"
"fmt"
"github.com/goburrow/serial"
log "github.com/sirupsen/logrus"
"git.cacert.org/cacert-gosigner/datastructures"
"git.cacert.org/cacert-gosigner/shared"
)
func sendHandShake(port serial.Port) error {
log.Debug("Shaking hands ...")
if length, err := port.Write([]byte{shared.HandshakeByte}); err != nil {
return fmt.Errorf("could not write handshake byte: %v", err)
} else {
log.Tracef("wrote %d handshake bytes", length)
}
handShakeResponse := make([]byte, 1)
if length, err := port.Read(handShakeResponse); err != nil {
return fmt.Errorf("failed to read handshake response: %v", err)
} else {
log.Tracef("read %d bytes", length)
}
if handShakeResponse[0] != shared.AckByte {
return fmt.Errorf("invalid handshake response expected 0x10 received %x", handShakeResponse[0])
}
log.Debug("Handshake successful")
return nil
}
func receiveResponse(port *serial.Port, responseChan *chan datastructures.SignerResponse, errorChan *chan error) {
header, err := shared.ReceiveBytes(port, 1, 20)
if err != nil {
*errorChan <- err
return
}
if header[0] != shared.HandshakeByte {
*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x%x", header, shared.HandshakeByte)
}
log.Tracef("received handshake byte")
if _, err := (*port).Write([]byte{shared.AckByte}); err != nil {
*errorChan <- errors.New("could not write ACK")
return
}
log.Tracef("sent ACK byte")
lengthBytes, err := shared.ReceiveBytes(port, 3, 2)
if err != nil {
*errorChan <- err
return
}
blockLength := datastructures.Decode24BitLength(lengthBytes)
log.Tracef("received block length %d", blockLength)
blockData, err := shared.ReceiveBytes(port, blockLength, 5)
if err != nil {
*errorChan <- err
return
}
log.Tracef("received bytes %v", blockData)
checkSum, err := shared.ReceiveBytes(port, 1, 2)
if err != nil {
*errorChan <- err
return
}
log.Tracef("received checksum 0x%x", checkSum[0])
trailer, err := shared.ReceiveBytes(port, len(shared.MagicTrailer), 2)
if err != nil {
*errorChan <- err
return
}
if string(trailer) != shared.MagicTrailer {
*errorChan <- errors.New("expected trailer bytes not found")
return
}
log.Tracef("received valid trailer bytes")
if _, err := (*port).Write([]byte{shared.AckByte}); err != nil {
*errorChan <- fmt.Errorf("could not write ACK byte: %v", err)
return
}
log.Tracef("sent ACK byte")
signerResponse, err := datastructures.SignerResponseFromData(lengthBytes, blockData, checkSum[0])
if err != nil {
*errorChan <- err
return
}
log.Infof("received response of type %s", signerResponse.Action)
*responseChan <- *signerResponse
}