From e5be97bd0132fbdce6eb345441b0ebdeadd96c35 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Tue, 3 Nov 2020 11:42:04 +0100 Subject: fixed hard-coded protocol and minor refactoring --- client/add-entry/main.go | 4 +-- client/client.go | 78 +++++++++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/client/add-entry/main.go b/client/add-entry/main.go index 60fabf8..34f6c44 100644 --- a/client/add-entry/main.go +++ b/client/add-entry/main.go @@ -45,7 +45,7 @@ func main() { if err != nil { glog.Fatalf("failed encoding valid signed debug info: %v", err) } - glog.Infof("add-request succeeded: %s", str) + fmt.Println(str) glog.Flush() } @@ -82,5 +82,5 @@ func setup() (*client.Client, error) { if err != nil { return nil, err } - return client.NewClient(log, &http.Client{}, c, &k), nil + return client.NewClient(log, &http.Client{}, true, c, &k), nil } 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://" +} -- cgit v1.2.3