Beispiel #1
0
func MustNewNonce() *sf.Nonce {
	n, err := sf.NewNonce()
	if err != nil {
		panic(err)
	}
	return n
}
Beispiel #2
0
// Request encrypts a request to the server and decrypts the response.
//
// If the client and server have securely exchanged keys out of band,
// confidentiality does not depend on TLS.
func (c *Client) Request(method string, path string, contents []byte) ([]byte, error) {
	nonce, err := sf.NewNonce()
	if err != nil {
		return nil, errgo.Mask(err)
	}
	encReq := box.Seal(nil, contents, (*[24]byte)(nonce), (*[32]byte)(c.serverKey), (*[32]byte)(c.keyPair.PrivateKey))
	reqMessage := wire.Message{
		ID:       nonce.Encode(),
		Contents: encReq,
	}
	reqContents, err := json.Marshal(&reqMessage)
	if err != nil {
		return nil, errgo.Mask(err)
	}
	req, err := http.NewRequest(method, c.serverURL+path, bytes.NewBuffer(reqContents))
	if err != nil {
		return nil, errgo.Mask(err)
	}
	req.Header.Set("Content-Type", "application/json")

	resp, err := c.client.Do(req)
	if err != nil {
		return nil, errgo.Mask(err)
	}
	defer resp.Body.Close()
	respContents, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, errgo.Mask(err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, errgo.Mask(newHTTPClientError(resp.StatusCode, string(respContents)))
	}
	decResp, ok := box.Open(nil, respContents, (*[24]byte)(nonce), (*[32]byte)(c.serverKey), (*[32]byte)(c.keyPair.PrivateKey))
	if !ok {
		return nil, errgo.New("failed to authenticate response from server")
	}
	return decResp, nil
}
Beispiel #3
0
// Push pushes a message to a recipient.
func (c *Client) Push(recipient string, contents []byte) error {
	nonce, err := sf.NewNonce()
	if err != nil {
		return errgo.Mask(err)
	}
	rcptKey, err := sf.DecodePublicKey(recipient)
	if err != nil {
		return errgo.Mask(err)
	}
	encMsg := box.Seal(nil, contents, (*[24]byte)(nonce), (*[32]byte)(rcptKey), (*[32]byte)(c.keyPair.PrivateKey))
	pushWire := []wire.PushMessage{{
		Message: wire.Message{
			ID:       nonce.Encode(),
			Contents: encMsg,
		},
		Recipient: recipient,
	}}
	reqContents, err := json.Marshal(&pushWire)
	if err != nil {
		return errgo.Mask(err)
	}

	respContents, err := c.Request("POST", "/outbox/"+c.keyPair.PublicKey.Encode(), reqContents)
	if err != nil {
		return errgo.Mask(err)
	}
	var pushReceipts []wire.PushReceipt
	err = json.Unmarshal(respContents, &pushReceipts)
	if err != nil {
		return errgo.Mask(err)
	}
	for _, receipt := range pushReceipts {
		if receipt.OK && receipt.ID == nonce.Encode() {
			return nil
		}
	}
	return errgo.New("not acknowledged")
}