client.go 2.4 KB
Newer Older
S
stormgbs 已提交
1 2 3 4 5
package client

import (
	"bytes"
	"crypto/tls"
6
	"encoding/base64"
S
stormgbs 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"

	"github.com/alibaba/inclavare-containers/shim/runtime/signature/types"

	"github.com/golang/glog"
)

type SignStandard string

const (
	PKCS1 SignStandard = "pkcs1"
)

// Client
type Client interface {
	Sign(data []byte) (signature []byte, publicKey []byte, err error)
	GetStandard() SignStandard
}

//var _ Client = &pkcs1Client{}

type pkcs1Client struct {
	internalClient *http.Client
	serviceBaseURL *url.URL
	standard       SignStandard
}

func NewClient(standard SignStandard, serviceBaseURL *url.URL) Client {
	switch standard {
	case PKCS1:
		return &pkcs1Client{
			serviceBaseURL: serviceBaseURL,
			standard:       PKCS1,
		}
	default:
		return &pkcs1Client{
			serviceBaseURL: serviceBaseURL,
			standard:       PKCS1,
		}
	}
}

func (c *pkcs1Client) init() {
	c.internalClient = &http.Client{
		Transport: &http.Transport{
			//TODO: verify server
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}
}

func (c *pkcs1Client) Sign(data []byte) (signature []byte, publicKey []byte, err error) {
	if c.internalClient == nil {
		c.init()
	}
	var url string
	if strings.HasSuffix(c.serviceBaseURL.String(), "/") {
		url = fmt.Sprintf("%s%s", c.serviceBaseURL.String(), string(c.standard))
	} else {
		url = fmt.Sprintf("%s/%s", c.serviceBaseURL.String(), string(c.standard))
	}
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
	if err != nil {
		glog.Errorf("failed to new sign request, %v", err)
		return nil, nil, err
	}
	req.Header.Set("Content-Type", "text/plain")
	resp, err := c.internalClient.Do(req)
	if err != nil || resp.StatusCode != 200 {
		glog.Errorf("request sign error,%v", err)
		return nil, nil, err
	}
	defer resp.Body.Close()
	signedBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		glog.Errorf("failed to read sign response,%v", err)
		return nil, nil, err
	}
	payload := &types.SignaturePayload{}
	if err := json.Unmarshal(signedBytes, payload); err != nil {
		glog.Errorf("failed to unmarshal sign response,%v", err)
		return nil, nil, err
	}
95 96 97 98 99 100
	decode, err := base64.StdEncoding.DecodeString(payload.Signature)
	if err != nil {
		glog.Errorf("failed to decode signature,%v", err)
		return nil, nil, err
	}
	return decode, []byte(payload.PublicKey), nil
S
stormgbs 已提交
101 102 103 104 105
}

func (c *pkcs1Client) GetStandard() SignStandard {
	return PKCS1
}