Adds support for new Huobi authorised requests and a tool for ecdsa keys

Fixes: https://github.com/thrasher-/gocryptotrader/issues/150
This commit is contained in:
Adrian Gallagher
2018-07-13 15:54:31 +10:00
parent e5b3ce8de8
commit 4fadc6ff48
7 changed files with 268 additions and 36 deletions

View File

@@ -85,27 +85,27 @@ type FundHistory struct {
// Base stores the individual exchange information
type Base struct {
Name string
Enabled bool
Verbose bool
Websocket bool
RESTPollingDelay time.Duration
AuthenticatedAPISupport bool
APISecret, APIKey, ClientID string
Nonce nonce.Nonce
TakerFee, MakerFee, Fee float64
BaseCurrencies []string
AvailablePairs []string
EnabledPairs []string
AssetTypes []string
PairsLastUpdated int64
SupportsAutoPairUpdating bool
SupportsRESTTickerBatching bool
HTTPTimeout time.Duration
WebsocketURL string
APIUrl string
RequestCurrencyPairFormat config.CurrencyPairFormatConfig
ConfigCurrencyPairFormat config.CurrencyPairFormatConfig
Name string
Enabled bool
Verbose bool
Websocket bool
RESTPollingDelay time.Duration
AuthenticatedAPISupport bool
APISecret, APIKey, APIAuthPEMKey, ClientID string
Nonce nonce.Nonce
TakerFee, MakerFee, Fee float64
BaseCurrencies []string
AvailablePairs []string
EnabledPairs []string
AssetTypes []string
PairsLastUpdated int64
SupportsAutoPairUpdating bool
SupportsRESTTickerBatching bool
HTTPTimeout time.Duration
WebsocketURL string
APIUrl string
RequestCurrencyPairFormat config.CurrencyPairFormatConfig
ConfigCurrencyPairFormat config.CurrencyPairFormatConfig
*request.Requester
}

View File

@@ -2,11 +2,17 @@ package huobi
import (
"bytes"
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"log"
"net/url"
"strconv"
"strings"
"time"
"github.com/thrasher-/gocryptotrader/common"
@@ -82,6 +88,7 @@ func (h *HUOBI) Setup(exch config.ExchangeConfig) {
h.Enabled = true
h.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
h.SetAPIKeys(exch.APIKey, exch.APISecret, "", false)
h.APIAuthPEMKey = exch.APIAuthPEMKey
h.SetHTTPClientTimeout(exch.HTTPTimeout)
h.RESTPollingDelay = exch.RESTPollingDelay
h.Verbose = exch.Verbose
@@ -723,7 +730,34 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url
headers["Content-Type"] = "application/x-www-form-urlencoded"
hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret))
values.Set("Signature", common.Base64Encode(hmac))
signature := common.Base64Encode(hmac)
values.Set("Signature", signature)
pemKey := strings.NewReader(h.APIAuthPEMKey)
pemBytes, err := ioutil.ReadAll(pemKey)
if err != nil {
return fmt.Errorf("Huobi unable to ioutil.ReadAll PEM key: %s", err)
}
block, _ := pem.Decode(pemBytes)
if block == nil {
return fmt.Errorf("Huobi block is nil")
}
x509Encoded := block.Bytes
privKey, err := x509.ParseECPrivateKey(x509Encoded)
if err != nil {
return fmt.Errorf("Huobi unable to ParseECPrivKey: %s", err)
}
r, s, err := ecdsa.Sign(rand.Reader, privKey, common.GetSHA256([]byte(signature)))
if err != nil {
return fmt.Errorf("Huobi unable to sign: %s", err)
}
privSig := r.Bytes()
privSig = append(privSig, s.Bytes()...)
values.Set("PrivateSignature", common.Base64Encode(privSig))
url := fmt.Sprintf("%s%s", huobiAPIURL, endpoint)
url = common.EncodeURLValues(url, values)

View File

@@ -1,9 +1,16 @@
package huobi
import (
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"io/ioutil"
"strconv"
"strings"
"testing"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
@@ -251,3 +258,29 @@ func TestCancelWithdraw(t *testing.T) {
t.Error("Test failed - Huobi TestCancelWithdraw: Invalid withdraw-ID was valid")
}
}
func TestPEMLoadAndSign(t *testing.T) {
t.Parallel()
pemKey := strings.NewReader(h.APIAuthPEMKey)
pemBytes, err := ioutil.ReadAll(pemKey)
if err != nil {
t.Fatalf("Test Failed. TestPEMLoadAndSign Unable to ioutil.ReadAll PEM key: %s", err)
}
block, _ := pem.Decode(pemBytes)
if block == nil {
t.Fatalf("Test Failed. TestPEMLoadAndSign Block is nil")
}
x509Encoded := block.Bytes
privKey, err := x509.ParseECPrivateKey(x509Encoded)
if err != nil {
t.Fatalf("Test Failed. TestPEMLoadAndSign Unable to ParseECPrivKey: %s", err)
}
_, _, err = ecdsa.Sign(rand.Reader, privKey, common.GetSHA256([]byte("test")))
if err != nil {
t.Fatalf("Test Failed. TestPEMLoadAndSign Unable to sign: %s", err)
}
}