42d1e6e991
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.
99 lines
2.6 KiB
Go
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
|
|
}
|