99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
package connector
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/certusone/yubihsm-go/commands"
|
|
)
|
|
|
|
var ErrInvalidResponseValueLength = errors.New("invalid response value length")
|
|
|
|
type (
|
|
// HTTPConnector implements the HTTP based connection with the YubiHSM2 connector
|
|
HTTPConnector struct {
|
|
URL string
|
|
}
|
|
)
|
|
|
|
// NewHTTPConnector creates a new instance of HTTPConnector
|
|
func NewHTTPConnector(url string) *HTTPConnector {
|
|
return &HTTPConnector{
|
|
URL: url,
|
|
}
|
|
}
|
|
|
|
// Request encodes and executes a command on the HSM and returns the binary response
|
|
func (c *HTTPConnector) Request(command *commands.CommandMessage) (data []byte, err error) {
|
|
var requestData []byte
|
|
requestData, err = command.Serialize()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var res *http.Response
|
|
res, err = http.DefaultClient.Post("http://"+c.URL+"/connector/api", "application/octet-stream", bytes.NewReader(requestData))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
defer func() {
|
|
closeErr := res.Body.Close()
|
|
if err == nil {
|
|
err = closeErr
|
|
}
|
|
}()
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
err = fmt.Errorf("server returned non OK status code %d", res.StatusCode)
|
|
return
|
|
}
|
|
|
|
data, err = ioutil.ReadAll(res.Body)
|
|
|
|
return
|
|
}
|
|
|
|
// GetStatus requests the status of the HSM connector route /connector/status
|
|
func (c *HTTPConnector) GetStatus() (status *StatusResponse, err error) {
|
|
var res *http.Response
|
|
res, err = http.DefaultClient.Get("http://" + c.URL + "/connector/status")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var data []byte
|
|
data, err = ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
bodyString := string(data)
|
|
pairs := strings.Split(bodyString, "\n")
|
|
|
|
var values []string
|
|
for _, pair := range pairs {
|
|
values = append(values, strings.Split(pair, "=")...)
|
|
}
|
|
|
|
if values == nil || len(values) < 12 {
|
|
return nil, ErrInvalidResponseValueLength
|
|
}
|
|
|
|
status = &StatusResponse{}
|
|
status.Status = Status(values[1])
|
|
status.Serial = values[3]
|
|
status.Version = values[5]
|
|
status.Pid = values[7]
|
|
status.Address = values[9]
|
|
status.Port = values[11]
|
|
|
|
err = res.Body.Close()
|
|
|
|
return
|
|
}
|