diff options
| -rw-r--r-- | client/add-entry/main.go | 4 | ||||
| -rw-r--r-- | 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://" +} | 
