aboutsummaryrefslogtreecommitdiff
path: root/client/client.go
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-11-03 11:42:04 +0100
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-11-03 11:42:04 +0100
commite5be97bd0132fbdce6eb345441b0ebdeadd96c35 (patch)
treeb547e911a3af19906675f9bbf813a3084c9abdaf /client/client.go
parent2d6e12fd0260f8bf0f466e47767c5e68330e2bf1 (diff)
fixed hard-coded protocol and minor refactoring
Diffstat (limited to 'client/client.go')
-rw-r--r--client/client.go78
1 files changed, 44 insertions, 34 deletions
diff --git a/client/client.go b/client/client.go
index bf854b9..c2d6407 100644
--- a/client/client.go
+++ b/client/client.go
@@ -19,49 +19,49 @@ import (
"golang.org/x/net/context/ctxhttp"
)
+// Client is an HTTP(S) client that talks to an ST log
type Client struct {
Log *descriptor.Log
Client *http.Client
Chain []*x509.Certificate
PrivateKey *ed25519.PrivateKey
+ useHttp bool
}
// NewClient returns a new log client
-func NewClient(log *descriptor.Log, client *http.Client, chain []*x509.Certificate, privateKey *ed25519.PrivateKey) *Client {
+func NewClient(log *descriptor.Log, client *http.Client, useHttp bool, chain []*x509.Certificate, privateKey *ed25519.PrivateKey) *Client {
return &Client{
Log: log,
Chain: chain,
Client: client,
PrivateKey: privateKey,
+ useHttp: useHttp,
}
}
+// AddEntry creates, signs, and adds a new ChecksumV1 entry to the log
func (c *Client) AddEntry(ctx context.Context, name, checksum []byte) (*stfe.StItem, error) {
- glog.V(3).Info("creating add-entry request")
leaf, err := stfe.NewChecksumV1(name, checksum).Marshal()
if err != nil {
return nil, fmt.Errorf("failed marshaling StItem: %v", err)
}
- data, err := json.Marshal(struct {
- Item string `json:"item"`
- Scheme uint16 `json:"signature_scheme"`
- Signature string `json:"signature"`
- Chain []string `json:"chain"`
- }{
- Item: base64.StdEncoding.EncodeToString(leaf),
- Scheme: uint16(tls.Ed25519),
- Signature: base64.StdEncoding.EncodeToString(ed25519.Sign(*c.PrivateKey, leaf)),
- Chain: c.b64Chain(),
+ data, err := json.Marshal(stfe.AddEntryRequest{
+ Item: base64.StdEncoding.EncodeToString(leaf),
+ Signature: base64.StdEncoding.EncodeToString(ed25519.Sign(*c.PrivateKey, leaf)),
+ SignatureScheme: uint16(tls.Ed25519),
+ Chain: c.b64Chain(),
})
if err != nil {
return nil, fmt.Errorf("failed creating post data: %v", err)
}
- // TODO: make http(s) config option
- req, err := http.NewRequest("POST", "http://"+c.Log.BaseUrl+"/add-entry", bytes.NewBuffer(data))
+ glog.V(3).Infof("created post data: %s", string(data))
+
+ req, err := http.NewRequest("POST", c.protocol()+c.Log.BaseUrl+"/add-entry", bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("failed creating http request: %v", err)
}
req.Header.Set("Content-Type", "application/json")
+ glog.V(2).Infof("created request: %s %s", req.Method, req.URL)
var itemStr string
if err := c.doRequest(ctx, req, &itemStr); err != nil {
@@ -75,6 +75,7 @@ func (c *Client) AddEntry(ctx context.Context, name, checksum []byte) (*stfe.StI
if err := item.Unmarshal(b); err != nil {
return nil, fmt.Errorf("failed decoding StItem: %v", err)
}
+ glog.V(3).Infof("got StItem: %s", item)
if item.Format != stfe.StFormatSignedDebugInfoV1 {
return nil, fmt.Errorf("bad StItem format: %v", item.Format)
@@ -82,29 +83,10 @@ func (c *Client) AddEntry(ctx context.Context, name, checksum []byte) (*stfe.StI
if err := item.SignedDebugInfoV1.Verify(c.Log.Scheme, c.Log.PublicKey, leaf); err != nil {
return nil, fmt.Errorf("bad SignedDebugInfoV1 signature: %v", err)
}
+ glog.V(2).Infof("add-entry request succeeded")
return &item, nil
}
-func (c *Client) doRequest(ctx context.Context, req *http.Request, out interface{}) error {
- glog.V(3).Infof("sending request: %v %v", req.Method, req.URL)
- rsp, err := ctxhttp.Do(ctx, c.Client, req)
- if err != nil {
- return fmt.Errorf("http request failed: %v", err)
- }
- body, err := ioutil.ReadAll(rsp.Body)
- rsp.Body.Close()
- if err != nil {
- return fmt.Errorf("http body read failed: %v", err)
- }
- if rsp.StatusCode != http.StatusOK {
- return fmt.Errorf("http status code not ok: %v", rsp.StatusCode)
- }
- if err := json.Unmarshal(body, out); err != nil {
- return fmt.Errorf("failed decoding json body: %v", err)
- }
- return nil
-}
-
func (c *Client) GetSth(ctx context.Context) (*stfe.StItem, error) {
glog.V(2).Info("creating get-sth request")
return nil, fmt.Errorf("TODO")
@@ -137,3 +119,31 @@ func (c *Client) b64Chain() []string {
}
return chain
}
+
+// doRequest sends an HTTP request and decodes the resulting json body into out
+func (c *Client) doRequest(ctx context.Context, req *http.Request, out interface{}) error {
+ rsp, err := ctxhttp.Do(ctx, c.Client, req)
+ if err != nil {
+ return fmt.Errorf("http request failed: %v", err)
+ }
+ body, err := ioutil.ReadAll(rsp.Body)
+ rsp.Body.Close()
+ if err != nil {
+ return fmt.Errorf("http body read failed: %v", err)
+ }
+ if rsp.StatusCode != http.StatusOK {
+ return fmt.Errorf("http status code not ok: %v", rsp.StatusCode)
+ }
+ if err := json.Unmarshal(body, out); err != nil {
+ return fmt.Errorf("failed decoding json body: %v", err)
+ }
+ return nil
+}
+
+// protocol returns a protocol string that preceeds the log's base url
+func (c *Client) protocol() string {
+ if c.useHttp {
+ return "http://"
+ }
+ return "https://"
+}