diff --git a/client/config.go b/client/config.go
new file mode 100644
index 0000000..810d9a6
--- /dev/null
+++ b/client/config.go
@@ -0,0 +1,84 @@
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"time"
+
+	"github.com/goburrow/serial"
+	"github.com/sirupsen/logrus"
+	"gopkg.in/yaml.v2"
+)
+
+type SerialConfig struct {
+	Address  string `yaml:"address"`
+	BaudRate int    `yaml:"baudrate"`
+	DataBits int    `yaml:"databits"`
+	StopBits int    `yaml:"stopbits"`
+	Parity   string `yaml:"parity"`
+}
+
+type ClientConfig struct {
+	Serial        SerialConfig `yaml:"serial_config"`
+	Paranoid      bool         `yaml:"paranoid"`
+	Debug         bool         `yaml:"debug"`
+	GNUPGBinary   string       `yaml:"gnupg_bin"`
+	OpenSSLBinary string       `yaml:"openssl_bin"`
+	MySQLDSN      string       `yaml:"mysql_dsn"`
+}
+
+var defaultConfig = ClientConfig{
+	Serial: SerialConfig{
+		Address:  "/dev/ttyUSB0",
+		BaudRate: 115200,
+		DataBits: 8,
+		StopBits: 1,
+		Parity:   "N",
+	},
+	Paranoid:      false,
+	Debug:         false,
+	OpenSSLBinary: "/usr/bin/openssl",
+	GNUPGBinary:   "/usr/bin/gpg",
+	MySQLDSN:      "<username>:<password>@/database?parseTime=true",
+}
+
+func generateExampleConfig(configFile string) (config *ClientConfig, err error) {
+	config = &defaultConfig
+	configBytes, err := yaml.Marshal(config)
+	if err != nil {
+		logrus.Errorf("could not generate configuration data")
+		return
+	}
+
+	logrus.Infof("example data for %s:\n\n---\n%s\n", configFile, configBytes)
+	return
+}
+
+func readConfig(configFile string) (config *ClientConfig, err error) {
+	source, err := ioutil.ReadFile(configFile)
+	if err != nil {
+		logrus.Errorf("opening configuration file failed: %v", err)
+		if exampleConfig, err := generateExampleConfig(configFile); err != nil {
+			return nil, err
+		} else {
+			logrus.Info("starting with default config")
+			return exampleConfig, nil
+		}
+	}
+	if err := yaml.Unmarshal(source, &config); err != nil {
+		return nil, fmt.Errorf("loading configuration file failed: %v", err)
+	}
+
+	return config, nil
+}
+
+func fillSerialConfig(clientConfig *ClientConfig) *serial.Config {
+	return &serial.Config{
+		Address:  clientConfig.Serial.Address,
+		BaudRate: clientConfig.Serial.BaudRate,
+		DataBits: clientConfig.Serial.DataBits,
+		StopBits: clientConfig.Serial.StopBits,
+		Parity:   clientConfig.Serial.Parity,
+		Timeout:  30 * time.Second,
+	}
+}
diff --git a/client/io.go b/client/io.go
new file mode 100644
index 0000000..73588fe
--- /dev/null
+++ b/client/io.go
@@ -0,0 +1,98 @@
+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
+}
diff --git a/client/main.go b/client/main.go
index 67b4237..59a82c1 100644
--- a/client/main.go
+++ b/client/main.go
@@ -1,86 +1,17 @@
 package main
 
 import (
-	"encoding/binary"
-	"errors"
 	"flag"
 	"fmt"
+	"time"
+
 	"git.cacert.org/cacert-gosigner/datastructures"
 	"git.cacert.org/cacert-gosigner/shared"
-	"io/ioutil"
-	"time"
 
 	"github.com/goburrow/serial"
 	log "github.com/sirupsen/logrus"
-	"gopkg.in/yaml.v2"
 )
 
-type SerialConfig struct {
-	Address  string `yaml:"address"`
-	BaudRate int    `yaml:"baudrate"`
-	DataBits int    `yaml:"databits"`
-	StopBits int    `yaml:"stopbits"`
-	Parity   string `yaml:"parity"`
-}
-
-type ClientConfig struct {
-	Serial        SerialConfig `yaml:"serial_config"`
-	Paranoid      bool         `yaml:"paranoid"`
-	Debug         bool         `yaml:"debug"`
-	GNUPGBinary   string       `yaml:"gnupg_bin"`
-	OpenSSLBinary string       `yaml:"openssl_bin"`
-	MySQLDSN      string       `yaml:"mysql_dsn"`
-}
-
-var defaultConfig = ClientConfig{
-	Serial: SerialConfig{
-		Address:  "/dev/ttyUSB0",
-		BaudRate: 115200,
-		DataBits: 8,
-		StopBits: 1,
-		Parity:   "N",
-	},
-	Paranoid:      false,
-	Debug:         false,
-	OpenSSLBinary: "/usr/bin/openssl",
-	GNUPGBinary:   "/usr/bin/gpg",
-	MySQLDSN:      "<username>:<password>@/database?parseTime=true",
-}
-
-const HandshakeByte = 0x02
-const AckByte = 0x10
-const NackByte = 0x11
-
-func readConfig(configFile string) (config *ClientConfig, err error) {
-	source, err := ioutil.ReadFile(configFile)
-	if err != nil {
-		log.Errorf("opening configuration file failed: %v", err)
-		if exampleConfig, err := generateExampleConfig(configFile); err != nil {
-			return nil, err
-		} else {
-			log.Info("starting with default config")
-			return exampleConfig, nil
-		}
-	}
-	if err := yaml.Unmarshal(source, &config); err != nil {
-		return nil, fmt.Errorf("loading configuration file failed: %v", err)
-	}
-
-	return config, nil
-}
-
-func generateExampleConfig(configFile string) (config *ClientConfig, err error) {
-	config = &defaultConfig
-	configBytes, err := yaml.Marshal(config)
-	if err != nil {
-		log.Errorf("could not generate configuration data")
-		return
-	}
-
-	log.Infof("example data for %s:\n\n---\n%s\n", configFile, configBytes)
-	return
-}
-
 func main() {
 	var configFile string
 
@@ -94,177 +25,127 @@ func main() {
 	if clientConfig, err = readConfig(configFile); err != nil {
 		log.Panic(err)
 	}
-	serialConfig = &serial.Config{
-		Address:  clientConfig.Serial.Address,
-		BaudRate: clientConfig.Serial.BaudRate,
-		DataBits: clientConfig.Serial.DataBits,
-		StopBits: clientConfig.Serial.StopBits,
-		Parity:   clientConfig.Serial.Parity,
-		Timeout:  30 * time.Second,
-	}
+	serialConfig = fillSerialConfig(clientConfig)
 	if clientConfig.Debug {
 		log.SetLevel(log.DebugLevel)
 	}
 
-	log.Debugf("connecting %+v", serialConfig)
+	log.Infof("connecting to %s", serialConfig.Address)
+	log.Tracef("serial parameters %v", serialConfig)
 	port, err := serial.Open(serialConfig)
 	if err != nil {
 		log.Fatal(err)
 	}
-	log.Debug("connected")
+	log.Debug("serial port connected")
 	defer func() {
 		err := port.Close()
 		if err != nil {
 			log.Fatal(err)
 		}
-		log.Debug("closed")
+		log.Debug("serial port closed")
 	}()
 
-	request := datastructures.NewNulRequest()
-	timeout := time.After(2700 * time.Millisecond)
 	errorChannel := make(chan error, 1)
-	responseChannel := make(chan *datastructures.SignerResponse, 1)
+	responseChannel := make(chan datastructures.SignerResponse, 1)
+	crlCheck := 0
 
-	go func() {
-		if response, err := SendRequest(port, request); err != nil {
-			errorChannel <- err
-		} else {
-			responseChannel <- response
+	log.Debug("starting main loop")
+
+	for {
+		requestChannel := make(chan datastructures.SignerRequest, 1)
+
+		go HandleRequests(&port, &responseChannel, &errorChannel, &requestChannel)
+
+		log.Debug("handling GPG database ...")
+		// HandleGPG(&requestChannel)
+		log.Debug("issuing certificates ...")
+		// HandleCertificates(&requestChannel)
+		log.Debug("revoking certificates ...")
+		// RevokeCertificates(&requestChannel)
+
+		crlCheck++
+		if crlCheck%100 == 0 {
+			log.Debug("refresh CRLs ...")
+			// RefreshCRLs(&requestChannel)
 		}
-	}()
 
-	select {
-	case <-timeout:
-		log.Fatal("timeout")
-	case err := <-errorChannel:
-		log.Fatal(err)
-	case response := <-responseChannel:
-		if err := Process(response); err != nil {
-			log.Fatal(err)
+		log.Debug("send NUL request to keep connection open")
+		requestChannel <- *datastructures.NewNulRequest()
+
+		select {
+		case response := <-responseChannel:
+			if err := Process(response); err != nil {
+				log.Error(err)
+			}
+		case err := <-errorChannel:
+			log.Error(err)
+		}
+
+		log.Debug("sleep for 2.7 seconds")
+		time.Sleep(2700 * time.Millisecond)
+	}
+}
+
+func Process(response datastructures.SignerResponse) (err error) {
+	log.Infof("process response of type %s", response.Action)
+	log.Tracef("process response %v", response)
+
+	switch response.Action {
+	case datastructures.ActionNul:
+		log.Trace("received response for NUL request")
+		return
+	default:
+		return fmt.Errorf("unsupported action in response 0x%x", response.Action)
+	}
+}
+
+func HandleRequests(port *serial.Port, responseChan *chan datastructures.SignerResponse, errorChan *chan error, requestChan *chan datastructures.SignerRequest) {
+	for {
+		select {
+		case request := <-*requestChan:
+			SendRequest(port, responseChan, errorChan, &request)
 		}
 	}
 }
 
-func Process(response *datastructures.SignerResponse) error {
-	log.Debugf("process %v", response)
-	return nil
-}
+func SendRequest(port *serial.Port, responseChan *chan datastructures.SignerResponse, errorChan *chan error, request *datastructures.SignerRequest) {
+	log.Tracef("send request %v to serial port %v", *request, *port)
+	if err := sendHandShake(*port); err != nil {
+		*errorChan <- err
+		return
+	}
 
-func sendHandShake(port serial.Port) error {
-	log.Debug("Shaking hands ...")
-	if length, err := port.Write([]byte{HandshakeByte}); err != nil {
-		return fmt.Errorf("could not write handshake byte: %v", err)
+	requestBytes := request.Serialize()
+	if length, err := (*port).Write(requestBytes); err != nil {
+		*errorChan <- err
+		return
 	} else {
-		log.Debugf("wrote %d handshake bytes", length)
+		log.Tracef("wrote %d request bytes", length)
+	}
+
+	if length, err := (*port).Write([]byte{datastructures.CalculateXorCheckSum([][]byte{requestBytes})}); err != nil {
+		*errorChan <- err
+		return
+	} else {
+		log.Tracef("wrote %d checksum bytes", length)
+	}
+
+	if length, err := (*port).Write([]byte(shared.MagicTrailer)); err != nil {
+		*errorChan <- err
+		return
+	} else {
+		log.Tracef("wrote %d trailer 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.Debugf("read %d bytes", length)
-	}
-	if handShakeResponse[0] != 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 []byte, errorChan *chan error) {
 	header, err := shared.ReceiveBytes(port, 1, 20)
 	if err != nil {
 		*errorChan <- err
 		return
 	}
-	if header[0] != HandshakeByte {
-		*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x%x", header, HandshakeByte)
-	}
-
-	if _, err := (*port).Write([]byte{AckByte}); err != nil {
-		*errorChan <- errors.New("could not write ACK")
+	if header[0] != shared.AckByte {
+		*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x%x", header, shared.AckByte)
 		return
 	}
 
-	lengthBytes, err := shared.ReceiveBytes(port, 3, 2)
-	if err != nil {
-		*errorChan <- err
-		return
-	}
-	blockLength := binary.BigEndian.Uint32([]byte{0x0, lengthBytes[0], lengthBytes[1], lengthBytes[2]})
-	blockData, err := shared.ReceiveBytes(port, int(blockLength), 5)
-	if err != nil {
-		*errorChan <- err
-		return
-	}
-
-	checkSum, err := shared.ReceiveBytes(port, 1, 2)
-	if err != nil {
-		*errorChan <- err
-		return
-	}
-	log.Debugf("block checksum is %d", checkSum)
-	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
-	}
-
-	if _, err := (*port).Write([]byte{AckByte}); err != nil {
-		*errorChan <- fmt.Errorf("could not write ACK byte: %v", err)
-	}
-	*responseChan <- blockData
-
-	return
-}
-
-func SendRequest(port serial.Port, request *datastructures.SignerRequest) (response *datastructures.SignerResponse, err error) {
-	log.Debugf("send request %v to serial port %v", request, port)
-
-	if err = sendHandShake(port); err != nil {
-		return nil, err
-	}
-
-	requestBytes := request.Serialize()
-	if length, err := port.Write(requestBytes); err != nil {
-		log.Fatal(err)
-	} else {
-		log.Debugf("wrote %d request bytes", length)
-	}
-
-	if length, err := port.Write([]byte{datastructures.CalculateXorCheckSum([][]byte{requestBytes})}); err != nil {
-		log.Fatal(err)
-	} else {
-		log.Debugf("wrote %d checksum bytes", length)
-	}
-
-	if length, err := port.Write([]byte(shared.MagicTrailer)); err != nil {
-		log.Fatal(err)
-	} else {
-		log.Debugf("wrote %d trailer bytes", length)
-	}
-
-	header, err := shared.ReceiveBytes(&port, 1, 20)
-	if err != nil {
-		return nil, err
-	}
-	if header[0] != AckByte {
-		return nil, fmt.Errorf("unexpected byte 0x%x expected 0x%x", header, AckByte)
-	}
-
-	responseChan := make(chan []byte, 1)
-	errChan := make(chan error, 1)
-	go receiveResponse(&port, &responseChan, &errChan)
-
-	select {
-	case responseData := <-responseChan:
-		log.Debugf("response data: %v", responseData)
-	case err := <-errChan:
-		log.Errorf("%v", err)
-	}
-
-	return nil, nil
+	receiveResponse(port, responseChan, errorChan)
 }
diff --git a/datastructures/common.go b/datastructures/common.go
index 6f29667..e3ccb63 100644
--- a/datastructures/common.go
+++ b/datastructures/common.go
@@ -6,6 +6,15 @@ type Action uint8
 
 const ActionNul = Action(0)
 
+func (a Action) String() string {
+	switch a {
+	case ActionNul:
+		return "NUL"
+	default:
+		return "unknown"
+	}
+}
+
 func encode24BitLength(data []byte) []byte {
 	lengthBytes := make([]byte, 4)
 	binary.BigEndian.PutUint32(lengthBytes, uint32(len(data)))
@@ -13,7 +22,7 @@ func encode24BitLength(data []byte) []byte {
 }
 
 // calculate length from 24 bits of data in network byte order
-func decode24BitLength(bytes []byte) int {
+func Decode24BitLength(bytes []byte) int {
 	return int(binary.BigEndian.Uint32([]byte{0x0, bytes[0], bytes[1], bytes[2]}))
 }
 
diff --git a/datastructures/signerrequest.go b/datastructures/signerrequest.go
index c15c461..90f5cb4 100644
--- a/datastructures/signerrequest.go
+++ b/datastructures/signerrequest.go
@@ -25,19 +25,19 @@ type SignerRequest struct {
 const protocolVersion = 1
 
 func SignerRequestFromData(lengthBytes []byte, blockData []byte, checkSum byte) (*SignerRequest, error) {
-	headerLength := decode24BitLength(blockData[0:3])
+	headerLength := Decode24BitLength(blockData[0:3])
 	headerBytes := blockData[3 : 3+headerLength]
 
 	contentBytes := blockData[3+headerLength:]
-	content1Length := decode24BitLength(contentBytes[0:3])
+	content1Length := Decode24BitLength(contentBytes[0:3])
 	content1 := string(contentBytes[3 : 3+content1Length])
 
 	content2Offset := 3 + content1Length
-	content2Length := decode24BitLength(contentBytes[content2Offset : content2Offset+3])
+	content2Length := Decode24BitLength(contentBytes[content2Offset : content2Offset+3])
 	content2 := string(contentBytes[3+content2Offset : 3+content2Offset+content2Length])
 
 	content3Offset := 3 + content2Offset + content2Length
-	content3Length := decode24BitLength(contentBytes[content3Offset : content3Offset+3])
+	content3Length := Decode24BitLength(contentBytes[content3Offset : content3Offset+3])
 	content3 := string(contentBytes[3+content3Offset : 3+content3Offset+content3Length])
 
 	calculated := CalculateXorCheckSum([][]byte{lengthBytes, blockData})
@@ -79,8 +79,8 @@ func (r SignerRequest) Serialize() []byte {
 
 func NewNulRequest() *SignerRequest {
 	return &SignerRequest{
-		Version: protocolVersion,
-		Action:  ActionNul,
+		Version:  protocolVersion,
+		Action:   ActionNul,
 		Content1: time.Now().UTC().Format("010203042006.05"),
 	}
 }
diff --git a/datastructures/signerresponse.go b/datastructures/signerresponse.go
index f6c36ba..9502e48 100644
--- a/datastructures/signerresponse.go
+++ b/datastructures/signerresponse.go
@@ -17,20 +17,26 @@ type SignerResponse struct {
 }
 
 func SignerResponseFromData(lengthBytes []byte, blockData []byte, checkSum byte) (*SignerResponse, error) {
-	headerLength := decode24BitLength(lengthBytes)
-	headerBytes := blockData[3 : 3+headerLength]
+	if len(blockData) < 3 {
+		return nil, errors.New("begin of structure corrupt")
+	}
 
-	contentBytes := blockData[3+headerLength:]
-	content1Length := decode24BitLength(contentBytes[0:3])
-	content1 := string(contentBytes[3 : 3+content1Length])
+	offset := 0
+	headerLength := Decode24BitLength(blockData[offset : offset+3])
+	offset += 3
+	headerBytes := blockData[offset : offset+headerLength]
+	offset += headerLength
 
-	content2Offset := 3 + content1Length
-	content2Length := decode24BitLength(contentBytes[content2Offset : content2Offset+3])
-	content2 := string(contentBytes[3+content2Offset : 3+content2Offset+content2Length])
-
-	content3Offset := 3 + content2Offset + content2Length
-	content3Length := decode24BitLength(contentBytes[content3Offset : content3Offset+3])
-	content3 := string(contentBytes[3+content3Offset : 3+content3Offset+content3Length])
+	content := make([]string, 3)
+	for offset < len(blockData) {
+		dataLength := Decode24BitLength(blockData[offset : offset+3])
+		if len(blockData)-3 < dataLength {
+			return nil, errors.New("structure cut off")
+		}
+		offset += 3
+		content = append(content, string(blockData[offset:offset+dataLength]))
+		offset += dataLength
+	}
 
 	calculated := CalculateXorCheckSum([][]byte{lengthBytes, blockData})
 	if checkSum != calculated {
@@ -42,9 +48,9 @@ func SignerResponseFromData(lengthBytes []byte, blockData []byte, checkSum byte)
 		Action:    Action(headerBytes[1]),
 		Reserved1: headerBytes[2],
 		Reserved2: headerBytes[3],
-		Content1:  content1,
-		Content2:  content2,
-		Content3:  content3,
+		Content1:  content[0],
+		Content2:  content[1],
+		Content3:  content[2],
 	}, nil
 }
 
diff --git a/shared/shared.go b/shared/shared.go
index d0d6c12..1677f1c 100644
--- a/shared/shared.go
+++ b/shared/shared.go
@@ -1,3 +1,7 @@
 package shared
 
 const MagicTrailer = "rie4Ech7"
+
+const HandshakeByte = 0x02
+const AckByte = 0x10
+const NackByte = 0x11
diff --git a/signer/main.go b/signer/main.go
index 3e9e57d..56329b1 100644
--- a/signer/main.go
+++ b/signer/main.go
@@ -1,15 +1,15 @@
 package main
 
 import (
-	"encoding/binary"
 	"errors"
 	"flag"
 	"fmt"
-	"git.cacert.org/cacert-gosigner/datastructures"
-	"git.cacert.org/cacert-gosigner/shared"
 	"log"
 	"time"
 
+	"git.cacert.org/cacert-gosigner/datastructures"
+	"git.cacert.org/cacert-gosigner/shared"
+
 	"github.com/goburrow/serial"
 )
 
@@ -96,7 +96,7 @@ func SendResponse(port *serial.Port, response *datastructures.SignerResponse) er
 	}
 
 	tryAgain := true
-	for ; tryAgain; {
+	for tryAgain {
 		data := response.Serialize()
 		if _, err := (*port).Write(data); err != nil {
 			return err
@@ -150,11 +150,11 @@ func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest,
 		*errorChan <- err
 		return
 	}
-	if header[0] != 0x02 {
-		*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x02", header)
+	if header[0] != shared.HandshakeByte {
+		*errorChan <- fmt.Errorf("unexpected byte 0x%x expected 0x%x", header[0], shared.HandshakeByte)
 	}
 
-	if _, err := (*port).Write([]byte{0x10}); err != nil {
+	if _, err := (*port).Write([]byte{shared.AckByte}); err != nil {
 		*errorChan <- errors.New("could not write ACK")
 		return
 	}
@@ -164,8 +164,8 @@ func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest,
 		*errorChan <- err
 		return
 	}
-	blockLength := binary.BigEndian.Uint32([]byte{0x0, lengthBytes[0], lengthBytes[1], lengthBytes[2]})
-	blockData, err := shared.ReceiveBytes(port, int(blockLength), 5)
+	blockLength := datastructures.Decode24BitLength(lengthBytes)
+	blockData, err := shared.ReceiveBytes(port, blockLength, 5)
 	if err != nil {
 		*errorChan <- err
 		return
@@ -199,4 +199,3 @@ func Receive(port *serial.Port, commandChan *chan datastructures.SignerRequest,
 
 	*commandChan <- *command
 }
-