...

Source file src/github.com/sassoftware/relic/token/worker/client.go

Documentation: github.com/sassoftware/relic/token/worker

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package worker
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"crypto"
    23  	"crypto/rsa"
    24  	"crypto/x509"
    25  	"encoding/json"
    26  	"errors"
    27  	"io"
    28  	"io/ioutil"
    29  	"net/http"
    30  	"net/url"
    31  	"time"
    32  
    33  	"github.com/sassoftware/relic/config"
    34  	"github.com/sassoftware/relic/internal/workerrpc"
    35  	"github.com/sassoftware/relic/token"
    36  )
    37  
    38  const (
    39  	defaultRetries = 5
    40  	defaultTimeout = 60 * time.Second
    41  )
    42  
    43  func (t *WorkerToken) request(ctx context.Context, path string, rr workerrpc.Request) (*workerrpc.Response, error) {
    44  	req := &http.Request{
    45  		Method: http.MethodPost,
    46  		URL:    &url.URL{Scheme: "http", Host: t.addr, Path: path},
    47  		Header: http.Header{"Auth-Cookie": []string{t.cookie}},
    48  	}
    49  	blob, err := json.Marshal(rr)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	req.GetBody = func() (io.ReadCloser, error) {
    54  		return ioutil.NopCloser(bytes.NewReader(blob)), nil
    55  	}
    56  	return t.doRetry(req.WithContext(ctx))
    57  }
    58  
    59  func (t *WorkerToken) Ping() error {
    60  	return t.PingContext(context.Background())
    61  }
    62  
    63  func (t *WorkerToken) PingContext(ctx context.Context) error {
    64  	_, err := t.request(ctx, workerrpc.Ping, workerrpc.Request{})
    65  	return err
    66  }
    67  
    68  func (t *WorkerToken) Config() *config.TokenConfig {
    69  	return t.tconf
    70  }
    71  
    72  func (t *WorkerToken) GetKey(keyName string) (token.Key, error) {
    73  	return t.GetKeyContext(context.Background(), keyName)
    74  }
    75  
    76  func (t *WorkerToken) GetKeyContext(ctx context.Context, keyName string) (token.Key, error) {
    77  	kconf, err := t.config.GetKey(keyName)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	res, err := t.request(ctx, workerrpc.GetKey, workerrpc.Request{KeyName: kconf.Name()})
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	pub, err := x509.ParsePKIXPublicKey(res.Value)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	return &workerKey{
    90  		token:  t,
    91  		kconf:  kconf,
    92  		public: pub,
    93  		id:     res.ID,
    94  	}, nil
    95  }
    96  
    97  func (t *WorkerToken) Import(keyName string, privKey crypto.PrivateKey) (token.Key, error) {
    98  	return nil, errors.New("function not implemented for worker token")
    99  }
   100  
   101  func (t *WorkerToken) ImportCertificate(cert *x509.Certificate, labelBase string) error {
   102  	return errors.New("function not implemented for worker token")
   103  }
   104  
   105  func (t *WorkerToken) Generate(keyName string, keyType token.KeyType, bits uint) (token.Key, error) {
   106  	return nil, errors.New("function not implemented for worker token")
   107  }
   108  
   109  func (t *WorkerToken) ListKeys(opts token.ListOptions) error {
   110  	return errors.New("function not implemented for worker token")
   111  }
   112  
   113  type workerKey struct {
   114  	token  *WorkerToken
   115  	kconf  *config.KeyConfig
   116  	public crypto.PublicKey
   117  	id     []byte
   118  }
   119  
   120  func (k *workerKey) Config() *config.KeyConfig {
   121  	return k.kconf
   122  }
   123  
   124  func (k *workerKey) Public() crypto.PublicKey {
   125  	return k.public
   126  }
   127  
   128  func (k *workerKey) GetID() []byte {
   129  	return k.id
   130  }
   131  
   132  func (k *workerKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
   133  	return k.SignContext(context.Background(), digest, opts)
   134  }
   135  
   136  func (k *workerKey) SignContext(ctx context.Context, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
   137  	rr := workerrpc.Request{
   138  		KeyName: k.kconf.Name(),
   139  		Digest:  digest,
   140  	}
   141  	if opts != nil {
   142  		rr.Hash = uint(opts.HashFunc())
   143  		if o, ok := opts.(*rsa.PSSOptions); ok {
   144  			rr.SaltLength = &o.SaltLength
   145  		}
   146  	}
   147  	res, err := k.token.request(ctx, workerrpc.Sign, rr)
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  	return res.Value, nil
   152  }
   153  
   154  func (k *workerKey) ImportCertificate(cert *x509.Certificate) error {
   155  	return errors.New("function not implemented for worker token")
   156  }
   157  

View as plain text