yubihsm-go/connector/http.go

99 lines
2.0 KiB
Go
Raw Normal View History

2018-09-02 05:46:37 -07:00
package connector
import (
"bytes"
"errors"
2018-09-02 05:46:37 -07:00
"fmt"
"io/ioutil"
"net/http"
"strings"
2018-11-30 07:49:18 -08:00
"github.com/certusone/yubihsm-go/commands"
2018-09-02 05:46:37 -07:00
)
var ErrInvalidResponseValueLength = errors.New("invalid response value length")
2018-09-02 05:46:37 -07:00
type (
2018-10-01 05:48:56 -07:00
// HTTPConnector implements the HTTP based connection with the YubiHSM2 connector
2018-09-02 05:46:37 -07:00
HTTPConnector struct {
URL string
}
)
2018-10-01 05:48:56 -07:00
// NewHTTPConnector creates a new instance of HTTPConnector
2018-09-02 05:46:37 -07:00
func NewHTTPConnector(url string) *HTTPConnector {
return &HTTPConnector{
URL: url,
}
}
2018-10-01 05:48:56 -07:00
// 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()
2018-09-02 05:46:37 -07:00
if err != nil {
return
2018-09-02 05:46:37 -07:00
}
var res *http.Response
res, err = http.DefaultClient.Post("http://"+c.URL+"/connector/api", "application/octet-stream", bytes.NewReader(requestData))
2018-09-02 05:46:37 -07:00
if err != nil {
return
2018-09-02 05:46:37 -07:00
}
defer func() {
closeErr := res.Body.Close()
if err == nil {
err = closeErr
}
}()
2018-09-02 05:46:37 -07:00
if res.StatusCode != http.StatusOK {
err = fmt.Errorf("server returned non OK status code %d", res.StatusCode)
return
2018-09-02 05:46:37 -07:00
}
data, err = ioutil.ReadAll(res.Body)
2018-09-02 05:46:37 -07:00
return
2018-09-02 05:46:37 -07:00
}
2018-10-01 05:48:56 -07:00
// 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")
2018-09-02 05:46:37 -07:00
if err != nil {
return
2018-09-02 05:46:37 -07:00
}
var data []byte
data, err = ioutil.ReadAll(res.Body)
2018-09-02 05:46:37 -07:00
if err != nil {
return
2018-09-02 05:46:37 -07:00
}
2018-09-02 05:46:37 -07:00
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{}
2018-09-02 05:46:37 -07:00
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
2018-09-02 05:46:37 -07:00
}