func (bc *BtcCred) SignOcReq(req *msg.OcReq, conf *util.BitcoindConf) error { h, err := getReqSigDataHash(req) if err != nil { return err } hb64 := base64.StdEncoding.EncodeToString(h) msg, err := btcjson.NewSignMessageCmd(nil, bc.Addr, hb64) if err != nil { return fmt.Errorf("error while making cmd: %v", err.Error()) } json, err := msg.MarshalJSON() if err != nil { return fmt.Errorf("error while marshaling: %v", err.Error()) } resp, err := btcjson.RpcCommand(conf.User, conf.Password, conf.Server, json) if err != nil { return fmt.Errorf("error while making bitcoind JSON-RPC: %v", err.Error()) } sig, ok := resp.Result.(string) if !ok { return errors.New("error during bitcoind JSON-RPC") } req.Coins = append(req.Coins, fmt.Sprintf(bc.Addr)) req.CoinSigs = append(req.CoinSigs, fmt.Sprintf(sig)) return nil }
func sendRequest(c *node.Client, req *msg.OcReq) *msg.OcResp { // Parse/attach payments if *fDefer != "" { pv, err := msg.NewPaymentValueParseString(*fDefer) if err != nil { log.Fatal(err.Error()) } req.AttachDeferredPayment(pv) } // TODO(ortutay): handle non-deferred payments err := c.SignRequest(req) if err != nil { log.Fatal(err.Error()) } if *fVerbosity > 0 { fmt.Printf("sending request to %v\n%v\n\n", *fAddr, req.String()) } resp, err := c.SendRequest(*fAddr, req) if err != nil { log.Fatal(err.Error()) } fmt.Printf("%v\n", resp.String()) if resp.Status == msg.PLEASE_PAY { var pr msg.PaymentRequest err := json.Unmarshal(resp.Body, &pr) if err != nil { panic(err) } fmt.Printf("Server is requesting payment: %v%v to %v\n", util.S2B(pr.Amount), pr.Currency, pr.Addr) } return resp }
func getReqSigDataHash(req *msg.OcReq) ([]byte, error) { var buf bytes.Buffer req.WriteSignablePortion(&buf) hasher := sha256.New() _, err := hasher.Write(buf.Bytes()) if err != nil { return nil, fmt.Errorf("error while hashing: %v", err.Error()) } h := hasher.Sum([]byte{}) return h, nil }
func (o *OcCred) SignOcReq(req *msg.OcReq) error { h, err := getReqSigDataHash(req) if err != nil { return err } randBytes := make([]byte, SIG_RAND_NUM_BYTES) _, err = rand.Read(randBytes) if err != nil { return errors.New("error generating random bytes") } r, s, err := ecdsa.Sign(bytes.NewReader(randBytes), o.Priv, h) if err != nil { return fmt.Errorf("error during ECDSA signature: %v", err.Error()) } req.ID = o.ID() req.Sig = fmt.Sprintf("%x,%x", r, s) return nil }
func (c *Client) SendRequest(addr string, req *msg.OcReq) (*msg.OcResp, error) { if req.Nonce != "" { // TODO(ortutay): add nonce support panic("expected no nonce") } conn, err := net.Dial("tcp", addr) if err != nil { return nil, fmt.Errorf("error while dialing: %v", err.Error()) } err = req.Write(conn) if err != nil { return nil, fmt.Errorf("error while writing to conn: %v", err.Error()) } resp, err := msg.ReadOcResp(bufio.NewReader(conn)) if err != nil { return nil, fmt.Errorf("error while reading: %v", err.Error()) } return resp, nil }
func makeReq(args []string, body []byte) (*msg.OcReq, error) { s := strings.Split(args[0], ".") if len(s) != 2 { return nil, fmt.Errorf("expected server.method, but got: %v", args[0]) } reqArgs := args[1:] req := msg.OcReq{ ID: "", Sig: "", Nonce: "", Service: s[0], Method: s[1], Args: reqArgs, PaymentType: "", PaymentTxn: "", ContentLength: 0, } if body != nil { req.SetBody(body) req.ContentLength = len(body) req.Body = body } return &req, nil }