github.com/trustbloc/kms-go@v1.1.2/crypto/webkms/remotecrypto_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package webkms
     8  
     9  import (
    10  	"bytes"
    11  	"crypto/rand"
    12  	"crypto/tls"
    13  	"crypto/x509"
    14  	"encoding/json"
    15  	"encoding/pem"
    16  	"errors"
    17  	"fmt"
    18  	"io/ioutil"
    19  	"net"
    20  	"net/http"
    21  	"path/filepath"
    22  	"runtime"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/google/tink/go/aead"
    28  	aeadsubtle "github.com/google/tink/go/aead/subtle"
    29  	"github.com/google/tink/go/core/primitiveset"
    30  	"github.com/google/tink/go/keyset"
    31  	"github.com/google/tink/go/mac"
    32  	"github.com/google/tink/go/signature"
    33  	"github.com/google/tink/go/subtle/random"
    34  	"github.com/stretchr/testify/require"
    35  	"golang.org/x/crypto/chacha20poly1305"
    36  
    37  	cryptoapi "github.com/trustbloc/kms-go/spi/crypto"
    38  
    39  	"github.com/trustbloc/kms-go/crypto/tinkcrypto"
    40  	"github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/bbs"
    41  	"github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/composite/ecdh"
    42  	"github.com/trustbloc/kms-go/kms/localkms"
    43  	webkmsimpl "github.com/trustbloc/kms-go/kms/webkms"
    44  )
    45  
    46  const (
    47  	certPrefix        = "../../kms/webkms/testdata/"
    48  	clientTimeout     = 5 * time.Second
    49  	defaultKeyStoreID = "12345"
    50  	defaultKID        = "99999"
    51  )
    52  
    53  func TestEncryptDecrypt(t *testing.T) {
    54  	kh, err := keyset.NewHandle(aead.XChaCha20Poly1305KeyTemplate())
    55  	require.NoError(t, err)
    56  
    57  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    58  		err = processPOSTEncRequest(w, r, kh)
    59  		require.NoError(t, err)
    60  	})
    61  
    62  	server, url, client := CreateMockHTTPServerAndClient(t, hf)
    63  
    64  	defer func() {
    65  		e := server.Close()
    66  		require.NoError(t, e)
    67  	}()
    68  
    69  	defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
    70  		"{serverEndpoint}", url), defaultKeyStoreID)
    71  	defaultKeyURL := defaultKeystoreURL + "/keys/" + defaultKID
    72  	rCrypto := New(defaultKeystoreURL, client)
    73  	plaintext := []byte("lorem ipsum")
    74  	aad := []byte("dolor sit")
    75  
    76  	// test successful Encrypt/Decrypt
    77  	ciphertext, nonce, err := rCrypto.Encrypt(plaintext, aad, defaultKeyURL)
    78  	require.NoError(t, err)
    79  
    80  	decrypted, err := rCrypto.Decrypt(ciphertext, aad, nonce, defaultKeyURL)
    81  	require.NoError(t, err)
    82  	require.EqualValues(t, plaintext, decrypted)
    83  
    84  	t.Run("Encrypt Post request failure", func(t *testing.T) {
    85  		blankClient := &http.Client{}
    86  		tmpCrypto := New(defaultKeystoreURL, blankClient)
    87  
    88  		_, _, err = tmpCrypto.Encrypt(plaintext, aad, defaultKeyURL)
    89  		require.Contains(t, err.Error(), fmt.Sprintf("posting Encrypt plaintext failed [%s, Post \"%s\": %s",
    90  			defaultKeyURL+encryptURI, defaultKeyURL+encryptURI, getCertsErrorSubText()))
    91  
    92  		badURL := "``#$%"
    93  		_, _, err = tmpCrypto.Encrypt(plaintext, aad, badURL)
    94  		require.Contains(t, err.Error(), "posting Encrypt plaintext failed")
    95  		require.EqualError(t, err, fmt.Errorf("posting Encrypt plaintext failed [%s, build request error:"+
    96  			" parse \"%s\": invalid URL escape \"%s\"]", badURL+encryptURI, badURL+encryptURI, "%/e").Error())
    97  	})
    98  
    99  	t.Run("Decrypt Post request failure", func(t *testing.T) {
   100  		blankClient := &http.Client{}
   101  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   102  
   103  		_, err = tmpCrypto.Decrypt(nil, aad, nil, defaultKeyURL)
   104  		require.Contains(t, err.Error(), fmt.Sprintf("posting Decrypt ciphertext failed [%s, Post \"%s\": %s",
   105  			defaultKeyURL+decryptURI, defaultKeyURL+decryptURI, getCertsErrorSubText()))
   106  	})
   107  
   108  	t.Run("Encrypt json marshal failure", func(t *testing.T) {
   109  		remoteCrypto2 := New(defaultKeystoreURL, client)
   110  
   111  		remoteCrypto2.marshalFunc = failingMarshal
   112  		_, _, err = remoteCrypto2.Encrypt(plaintext, aad, defaultKeyURL)
   113  		require.EqualError(t, err, fmt.Errorf("marshal encryption request for Encrypt failed [%s, %w]",
   114  			defaultKeyURL+encryptURI, errFailingMarshal).Error())
   115  	})
   116  
   117  	t.Run("Encrypt json unmarshal failure", func(t *testing.T) {
   118  		remoteCrypto2 := New(defaultKeystoreURL, client)
   119  
   120  		remoteCrypto2.unmarshalFunc = failingUnmarshal
   121  		_, _, err = remoteCrypto2.Encrypt(plaintext, aad, defaultKeyURL)
   122  		require.EqualError(t, err, fmt.Errorf("unmarshal encryption for Encrypt failed [%s, %w]",
   123  			defaultKeyURL+encryptURI, errFailingUnmarshal).Error())
   124  	})
   125  
   126  	t.Run("Decrypt json marshal failure", func(t *testing.T) {
   127  		remoteCrypto2 := New(defaultKeystoreURL, client)
   128  
   129  		remoteCrypto2.marshalFunc = failingMarshal
   130  		_, err = remoteCrypto2.Decrypt(ciphertext, aad, nonce, defaultKeyURL)
   131  		require.EqualError(t, err, fmt.Errorf("marshal decryption request for Decrypt failed [%s, %w]",
   132  			defaultKeyURL+decryptURI, errFailingMarshal).Error())
   133  	})
   134  
   135  	t.Run("Decrypt json unmarshal failure", func(t *testing.T) {
   136  		remoteCrypto2 := New(defaultKeystoreURL, client)
   137  
   138  		remoteCrypto2.unmarshalFunc = failingUnmarshal
   139  		_, err = remoteCrypto2.Decrypt(ciphertext, aad, nonce, defaultKeyURL)
   140  		require.EqualError(t, err, fmt.Errorf("unmarshal decryption for Decrypt failed [%s, %w]",
   141  			defaultKeyURL+decryptURI, errFailingUnmarshal).Error())
   142  	})
   143  }
   144  
   145  func processPOSTEncRequest(w http.ResponseWriter, r *http.Request, encKH *keyset.Handle) error {
   146  	if valid := validateHTTPMethod(w, r); !valid {
   147  		return errors.New("http method invalid")
   148  	}
   149  
   150  	if valid := validatePostPayload(r, w); !valid {
   151  		return errors.New("http request body invalid")
   152  	}
   153  
   154  	reqBody, err := ioutil.ReadAll(r.Body)
   155  	if err != nil {
   156  		return err
   157  	}
   158  
   159  	if matchPath(r, encryptURI) {
   160  		err = encryptPOSTHandle(w, reqBody, encKH)
   161  		if err != nil {
   162  			return err
   163  		}
   164  	}
   165  
   166  	if matchPath(r, decryptURI) {
   167  		err = decryptPOSTHandle(w, reqBody, encKH)
   168  		if err != nil {
   169  			return err
   170  		}
   171  	}
   172  
   173  	return nil
   174  }
   175  
   176  func encryptPOSTHandle(w http.ResponseWriter, reqBody []byte, encKH *keyset.Handle) error {
   177  	encReq := &encryptReq{}
   178  
   179  	err := json.Unmarshal(reqBody, encReq)
   180  	if err != nil {
   181  		return err
   182  	}
   183  
   184  	ps, err := encKH.Primitives()
   185  	if err != nil {
   186  		return err
   187  	}
   188  
   189  	a, err := aead.New(encKH)
   190  	if err != nil {
   191  		return err
   192  	}
   193  
   194  	ct, err := a.Encrypt(encReq.Message, encReq.AssociatedData)
   195  	if err != nil {
   196  		return fmt.Errorf("encrypt msg: %w", err)
   197  	}
   198  
   199  	ivSize := nonceSize(ps)
   200  	prefixLength := len(ps.Primary.Prefix)
   201  	cipherText := ct[prefixLength+ivSize:]
   202  	nonce := ct[prefixLength : prefixLength+ivSize]
   203  
   204  	resp := &encryptResp{
   205  		Ciphertext: cipherText,
   206  		Nonce:      nonce,
   207  	}
   208  
   209  	mResp, err := json.Marshal(resp)
   210  	if err != nil {
   211  		return err
   212  	}
   213  
   214  	_, err = w.Write(mResp)
   215  	if err != nil {
   216  		return err
   217  	}
   218  
   219  	return nil
   220  }
   221  
   222  func decryptPOSTHandle(w http.ResponseWriter, reqBody []byte, encKH *keyset.Handle) error {
   223  	decReq := &decryptReq{}
   224  
   225  	err := json.Unmarshal(reqBody, decReq)
   226  	if err != nil {
   227  		return err
   228  	}
   229  
   230  	ps, err := encKH.Primitives()
   231  	if err != nil {
   232  		return err
   233  	}
   234  
   235  	a, err := aead.New(encKH)
   236  	if err != nil {
   237  		return err
   238  	}
   239  
   240  	cipher := decReq.Ciphertext
   241  	nonce := decReq.Nonce
   242  
   243  	ct := make([]byte, 0, len(ps.Primary.Prefix)+len(nonce)+len(cipher))
   244  	ct = append(ct, ps.Primary.Prefix...)
   245  	ct = append(ct, nonce...)
   246  	ct = append(ct, cipher...)
   247  
   248  	plaintext, err := a.Decrypt(ct, decReq.AssociatedData)
   249  	if err != nil {
   250  		return fmt.Errorf("decrypt cipher: %w", err)
   251  	}
   252  
   253  	resp := &decryptResp{
   254  		Plaintext: plaintext,
   255  	}
   256  
   257  	mResp, err := json.Marshal(resp)
   258  	if err != nil {
   259  		return err
   260  	}
   261  
   262  	_, err = w.Write(mResp)
   263  	if err != nil {
   264  		return err
   265  	}
   266  
   267  	return nil
   268  }
   269  
   270  func TestSignVerify(t *testing.T) {
   271  	kh, err := keyset.NewHandle(signature.ECDSAP384KeyTemplate())
   272  	require.NoError(t, err)
   273  
   274  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   275  		err = processPOSTSigRequest(w, r, kh)
   276  		require.NoError(t, err)
   277  	})
   278  
   279  	server, url, client := CreateMockHTTPServerAndClient(t, hf)
   280  
   281  	defer func() {
   282  		e := server.Close()
   283  		require.NoError(t, e)
   284  	}()
   285  
   286  	defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
   287  		"{serverEndpoint}", url), defaultKeyStoreID)
   288  	defaultKeyURL := defaultKeystoreURL + "/keys/" + defaultKID
   289  	rCrypto := New(defaultKeystoreURL, client)
   290  	msg := []byte("lorem ipsum")
   291  
   292  	// test successful Sign/Verify
   293  	sig, err := rCrypto.Sign(msg, defaultKeyURL)
   294  	require.NoError(t, err)
   295  
   296  	err = rCrypto.Verify(sig, msg, defaultKeyURL)
   297  	require.NoError(t, err)
   298  
   299  	t.Run("Sign Post request failure", func(t *testing.T) {
   300  		blankClient := &http.Client{}
   301  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   302  
   303  		_, err = tmpCrypto.Sign(nil, defaultKeyURL)
   304  		require.Contains(t, err.Error(), fmt.Sprintf("posting Sign message failed [%s, Post \"%s\": %s",
   305  			defaultKeyURL+signURI, defaultKeyURL+signURI, getCertsErrorSubText()))
   306  	})
   307  
   308  	t.Run("Verify Post request failure", func(t *testing.T) {
   309  		blankClient := &http.Client{}
   310  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   311  
   312  		err = tmpCrypto.Verify(nil, nil, defaultKeyURL)
   313  		require.Contains(t, err.Error(), fmt.Sprintf("posting Verify signature failed [%s, Post \"%s\": %s",
   314  			defaultKeyURL+verifyURI, defaultKeyURL+verifyURI, getCertsErrorSubText()))
   315  	})
   316  
   317  	t.Run("Sign json marshal failure", func(t *testing.T) {
   318  		remoteCrypto2 := New(defaultKeystoreURL, client)
   319  
   320  		remoteCrypto2.marshalFunc = failingMarshal
   321  		_, err = remoteCrypto2.Sign(msg, defaultKeyURL)
   322  		require.EqualError(t, err, fmt.Errorf("marshal signature request for Sign failed [%s, %w]",
   323  			defaultKeyURL+signURI, errFailingMarshal).Error())
   324  	})
   325  
   326  	t.Run("Sign json unmarshal failure", func(t *testing.T) {
   327  		remoteCrypto2 := New(defaultKeystoreURL, client)
   328  
   329  		remoteCrypto2.unmarshalFunc = failingUnmarshal
   330  		_, err = remoteCrypto2.Sign(msg, defaultKeyURL)
   331  		require.EqualError(t, err, fmt.Errorf("unmarshal signature for Sign failed [%s, %w]",
   332  			defaultKeyURL+signURI, errFailingUnmarshal).Error())
   333  	})
   334  
   335  	t.Run("Verify json marshal failure", func(t *testing.T) {
   336  		remoteCrypto2 := New(defaultKeystoreURL, client)
   337  
   338  		remoteCrypto2.marshalFunc = failingMarshal
   339  		err = remoteCrypto2.Verify(sig, msg, defaultKeyURL)
   340  		require.EqualError(t, err, fmt.Errorf("marshal verify request for Verify failed [%s, %w]",
   341  			defaultKeyURL+verifyURI, errFailingMarshal).Error())
   342  	})
   343  }
   344  
   345  func processPOSTSigRequest(w http.ResponseWriter, r *http.Request, sigKH *keyset.Handle) error {
   346  	if valid := validateHTTPMethod(w, r); !valid {
   347  		return errors.New("http method invalid")
   348  	}
   349  
   350  	if valid := validatePostPayload(r, w); !valid {
   351  		return errors.New("http request body invalid")
   352  	}
   353  
   354  	reqBody, err := ioutil.ReadAll(r.Body)
   355  	if err != nil {
   356  		return err
   357  	}
   358  
   359  	if matchPath(r, signURI) {
   360  		err = signPOSTHandle(w, reqBody, sigKH)
   361  		if err != nil {
   362  			return err
   363  		}
   364  	}
   365  
   366  	if matchPath(r, verifyURI) {
   367  		err = verifyPOSTHandle(reqBody, sigKH)
   368  		if err != nil {
   369  			return err
   370  		}
   371  	}
   372  
   373  	return nil
   374  }
   375  
   376  func signPOSTHandle(w http.ResponseWriter, reqBody []byte, sigKH *keyset.Handle) error {
   377  	sigReq := &signReq{}
   378  
   379  	err := json.Unmarshal(reqBody, sigReq)
   380  	if err != nil {
   381  		return err
   382  	}
   383  
   384  	signer, err := signature.NewSigner(sigKH)
   385  	if err != nil {
   386  		return fmt.Errorf("create new signer: %w", err)
   387  	}
   388  
   389  	s, err := signer.Sign(sigReq.Message)
   390  	if err != nil {
   391  		return fmt.Errorf("sign msg: %w", err)
   392  	}
   393  
   394  	resp := &signResp{
   395  		Signature: s,
   396  	}
   397  
   398  	mResp, err := json.Marshal(resp)
   399  	if err != nil {
   400  		return err
   401  	}
   402  
   403  	_, err = w.Write(mResp)
   404  	if err != nil {
   405  		return err
   406  	}
   407  
   408  	return nil
   409  }
   410  
   411  func verifyPOSTHandle(reqBody []byte, sigKH *keyset.Handle) error {
   412  	verReq := &verifyReq{}
   413  
   414  	err := json.Unmarshal(reqBody, verReq)
   415  	if err != nil {
   416  		return err
   417  	}
   418  
   419  	pubKH, err := sigKH.Public()
   420  	if err != nil {
   421  		return err
   422  	}
   423  
   424  	verifier, err := signature.NewVerifier(pubKH)
   425  	if err != nil {
   426  		return fmt.Errorf("create new verifier: %w", err)
   427  	}
   428  
   429  	err = verifier.Verify(verReq.Signature, verReq.Message)
   430  	if err != nil {
   431  		return fmt.Errorf("verify msg: %w", err)
   432  	}
   433  
   434  	return nil
   435  }
   436  
   437  func TestComputeVerifyMAC(t *testing.T) {
   438  	kh, err := keyset.NewHandle(mac.HMACSHA256Tag256KeyTemplate())
   439  	require.NoError(t, err)
   440  
   441  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   442  		err = processPOSTMACRequest(w, r, kh)
   443  		require.NoError(t, err)
   444  	})
   445  
   446  	server, url, client := CreateMockHTTPServerAndClient(t, hf)
   447  
   448  	defer func() {
   449  		e := server.Close()
   450  		require.NoError(t, e)
   451  	}()
   452  
   453  	defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
   454  		"{serverEndpoint}", url), defaultKeyStoreID)
   455  	defaultKeyURL := defaultKeystoreURL + "/keys/" + defaultKID
   456  	rCrypto := New(defaultKeystoreURL, client, webkmsimpl.WithCache(2))
   457  	data := []byte("lorem ipsum")
   458  
   459  	// test successful ComputeMAC/VerifyMAC
   460  	dataMAC, err := rCrypto.ComputeMAC(data, defaultKeyURL)
   461  	require.NoError(t, err)
   462  
   463  	err = rCrypto.VerifyMAC(dataMAC, data, defaultKeyURL)
   464  	require.NoError(t, err)
   465  
   466  	dataMAC, err = rCrypto.ComputeMAC(data, defaultKeyURL)
   467  	require.NoError(t, err)
   468  
   469  	err = rCrypto.VerifyMAC(dataMAC, data, defaultKeyURL)
   470  	require.NoError(t, err)
   471  
   472  	t.Run("ComputeMAC Post request failure", func(t *testing.T) {
   473  		blankClient := &http.Client{}
   474  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   475  
   476  		_, err = tmpCrypto.ComputeMAC(nil, defaultKeyURL)
   477  		require.Contains(t, err.Error(), fmt.Sprintf("posting ComputeMAC request failed [%s, Post \"%s\": %s",
   478  			defaultKeyURL+computeMACURI, defaultKeyURL+computeMACURI, getCertsErrorSubText()))
   479  	})
   480  
   481  	t.Run("VerifyMAC Post request failure", func(t *testing.T) {
   482  		blankClient := &http.Client{}
   483  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   484  
   485  		err = tmpCrypto.VerifyMAC(nil, nil, defaultKeyURL)
   486  		require.Contains(t, err.Error(), fmt.Sprintf("posting VerifyMAC request failed [%s, Post \"%s\": %s",
   487  			defaultKeyURL+verifyMACURI, defaultKeyURL+verifyMACURI, getCertsErrorSubText()))
   488  	})
   489  
   490  	t.Run("ComputeMAC json marshal failure", func(t *testing.T) {
   491  		remoteCrypto2 := New(defaultKeystoreURL, client)
   492  
   493  		remoteCrypto2.marshalFunc = failingMarshal
   494  		_, err = remoteCrypto2.ComputeMAC(data, defaultKeyURL)
   495  		require.EqualError(t, err, fmt.Errorf("marshal request for ComputeMAC failed [%s, %w]",
   496  			defaultKeyURL+computeMACURI, errFailingMarshal).Error())
   497  	})
   498  
   499  	t.Run("ComputeMAC json unmarshal failure", func(t *testing.T) {
   500  		remoteCrypto2 := New(defaultKeystoreURL, client)
   501  
   502  		remoteCrypto2.unmarshalFunc = failingUnmarshal
   503  		_, err = remoteCrypto2.ComputeMAC(data, defaultKeyURL)
   504  		require.EqualError(t, err, fmt.Errorf("unmarshal ComputeMAC response failed [%s, %w]",
   505  			defaultKeyURL+computeMACURI, errFailingUnmarshal).Error())
   506  	})
   507  
   508  	t.Run("VerifyMAC json marshal failure", func(t *testing.T) {
   509  		remoteCrypto2 := New(defaultKeystoreURL, client)
   510  
   511  		remoteCrypto2.marshalFunc = failingMarshal
   512  		err = remoteCrypto2.VerifyMAC(dataMAC, data, defaultKeyURL)
   513  		require.EqualError(t, err, fmt.Errorf("marshal request for VerifyMAC failed [%s, %w]",
   514  			defaultKeyURL+verifyMACURI, errFailingMarshal).Error())
   515  	})
   516  }
   517  
   518  func processPOSTMACRequest(w http.ResponseWriter, r *http.Request, macKH *keyset.Handle) error {
   519  	if valid := validateHTTPMethod(w, r); !valid {
   520  		return errors.New("http method invalid")
   521  	}
   522  
   523  	if valid := validatePostPayload(r, w); !valid {
   524  		return errors.New("http request body invalid")
   525  	}
   526  
   527  	reqBody, err := ioutil.ReadAll(r.Body)
   528  	if err != nil {
   529  		return err
   530  	}
   531  
   532  	if matchPath(r, computeMACURI) {
   533  		err = computeMACPOSTHandle(w, reqBody, macKH)
   534  		if err != nil {
   535  			return err
   536  		}
   537  	}
   538  
   539  	if matchPath(r, verifyMACURI) {
   540  		err = verifyMACPOSTHandle(reqBody, macKH)
   541  		if err != nil {
   542  			return err
   543  		}
   544  	}
   545  
   546  	return nil
   547  }
   548  
   549  func computeMACPOSTHandle(w http.ResponseWriter, reqBody []byte, macKH *keyset.Handle) error {
   550  	macReq := &computeMACReq{}
   551  
   552  	err := json.Unmarshal(reqBody, macReq)
   553  	if err != nil {
   554  		return err
   555  	}
   556  
   557  	macPrimitive, err := mac.New(macKH)
   558  	if err != nil {
   559  		return err
   560  	}
   561  
   562  	dataMAC, err := macPrimitive.ComputeMAC(macReq.Data)
   563  	if err != nil {
   564  		return err
   565  	}
   566  
   567  	resp := &computeMACResp{
   568  		MAC: dataMAC,
   569  	}
   570  
   571  	mResp, err := json.Marshal(resp)
   572  	if err != nil {
   573  		return err
   574  	}
   575  
   576  	_, err = w.Write(mResp)
   577  	if err != nil {
   578  		return err
   579  	}
   580  
   581  	return nil
   582  }
   583  
   584  func verifyMACPOSTHandle(reqBody []byte, macKH *keyset.Handle) error {
   585  	verReq := &verifyMACReq{}
   586  
   587  	err := json.Unmarshal(reqBody, verReq)
   588  	if err != nil {
   589  		return err
   590  	}
   591  
   592  	macPrimitive, err := mac.New(macKH)
   593  	if err != nil {
   594  		return err
   595  	}
   596  
   597  	err = macPrimitive.VerifyMAC(verReq.MAC, verReq.Data)
   598  	if err != nil {
   599  		return fmt.Errorf("verify mac: %w", err)
   600  	}
   601  
   602  	return nil
   603  }
   604  
   605  func TestWrapUnWrapKey(t *testing.T) {
   606  	senderKID := "11111"
   607  
   608  	recipientKH, err := keyset.NewHandle(ecdh.NISTP256ECDHKWKeyTemplate())
   609  	require.NoError(t, err)
   610  
   611  	recipentPubKey, err := exportPubKey(recipientKH)
   612  	require.NoError(t, err)
   613  
   614  	senderKH, err := keyset.NewHandle(ecdh.NISTP256ECDHKWKeyTemplate())
   615  	require.NoError(t, err)
   616  
   617  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   618  		err = processPOSTWrapRequest(w, r, senderKH, recipientKH)
   619  		require.NoError(t, err)
   620  	})
   621  
   622  	server, url, client := CreateMockHTTPServerAndClient(t, hf)
   623  
   624  	defer func() {
   625  		e := server.Close()
   626  		require.NoError(t, e)
   627  	}()
   628  
   629  	defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
   630  		"{serverEndpoint}", url), defaultKeyStoreID)
   631  	defaultKeyURL := defaultKeystoreURL + "/keys/" + defaultKID
   632  	rCrypto := New(defaultKeystoreURL, client)
   633  	cek := random.GetRandomBytes(uint32(32))
   634  	apu := []byte("bob")
   635  	apv := []byte("alice")
   636  
   637  	// Test successful WrapKey/UnwrapKey
   638  	wKey, err := rCrypto.WrapKey(cek, apu, apv, recipentPubKey)
   639  	require.NoError(t, err)
   640  
   641  	decryptedCEK, err := rCrypto.UnwrapKey(wKey, defaultKeyURL)
   642  	require.NoError(t, err)
   643  	require.EqualValues(t, cek, decryptedCEK)
   644  
   645  	t.Run("WrapKey Post request failure", func(t *testing.T) {
   646  		blankClient := &http.Client{}
   647  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   648  
   649  		_, err = tmpCrypto.WrapKey(cek, apu, apv, recipentPubKey)
   650  		require.Contains(t, err.Error(), fmt.Sprintf("posting WrapKey failed [%s, Post \"%s\": %s",
   651  			defaultKeystoreURL+wrapURI, defaultKeystoreURL+wrapURI, getCertsErrorSubText()))
   652  	})
   653  
   654  	t.Run("UnwrapKey Post request failure", func(t *testing.T) {
   655  		blankClient := &http.Client{}
   656  		tmpCrypto := New(defaultKeystoreURL, blankClient)
   657  
   658  		_, err = tmpCrypto.UnwrapKey(wKey, defaultKeyURL)
   659  		require.Contains(t, err.Error(), fmt.Sprintf("posting UnwrapKey failed [%s, Post \"%s\": %s",
   660  			defaultKeyURL+unwrapURI, defaultKeyURL+unwrapURI, getCertsErrorSubText()))
   661  	})
   662  
   663  	t.Run("WrapKey json marshal failure", func(t *testing.T) {
   664  		remoteCrypto2 := New(defaultKeystoreURL, client)
   665  
   666  		remoteCrypto2.marshalFunc = failingMarshal
   667  		_, err = remoteCrypto2.WrapKey(cek, apu, apv, recipentPubKey)
   668  		require.EqualError(t, err, fmt.Errorf("marshal wrapKeyReq for WrapKey failed [%s, %w]",
   669  			defaultKeystoreURL+wrapURI, errFailingMarshal).Error())
   670  	})
   671  
   672  	t.Run("WrapKey json unmarshal failure", func(t *testing.T) {
   673  		remoteCrypto2 := New(defaultKeystoreURL, client)
   674  
   675  		remoteCrypto2.unmarshalFunc = failingUnmarshal
   676  		_, err = remoteCrypto2.WrapKey(cek, apu, apv, recipentPubKey)
   677  		require.EqualError(t, err, fmt.Errorf("unmarshal wrapKeyResp for WrapKey failed [%s, %w]",
   678  			defaultKeystoreURL+wrapURI, errFailingUnmarshal).Error())
   679  	})
   680  
   681  	t.Run("UnwrapKey json unmarshal failure", func(t *testing.T) {
   682  		remoteCrypto2 := New(defaultKeystoreURL, client)
   683  
   684  		remoteCrypto2.unmarshalFunc = failingUnmarshal
   685  		_, err = remoteCrypto2.UnwrapKey(wKey, defaultKeyURL)
   686  		require.EqualError(t, err, fmt.Errorf("unmarshal unwrapKeyResp for UnwrapKey failed [%s, %w]",
   687  			defaultKeyURL+unwrapURI, errFailingUnmarshal).Error())
   688  	})
   689  
   690  	t.Run("Unwrap json marshal failure", func(t *testing.T) {
   691  		remoteCrypto2 := New(defaultKeystoreURL, client)
   692  
   693  		remoteCrypto2.marshalFunc = failingMarshal
   694  		_, err = remoteCrypto2.UnwrapKey(wKey, defaultKeyURL)
   695  		require.EqualError(t, err, fmt.Errorf("marshal unwrapKeyReq for UnwrapKey failed [%s, %w]",
   696  			defaultKeyURL+unwrapURI, errFailingMarshal).Error())
   697  	})
   698  
   699  	t.Run("Wrap/Unwrap successful with Sender key (authcrypt)", func(t *testing.T) {
   700  		wrappedKey, err := rCrypto.WrapKey(cek, apu, apv, recipentPubKey, cryptoapi.WithSender(senderKID))
   701  		require.NoError(t, err)
   702  
   703  		dCEK, err := rCrypto.UnwrapKey(wrappedKey, defaultKeyURL, cryptoapi.WithSender(&cryptoapi.PublicKey{}))
   704  		require.NoError(t, err)
   705  		require.EqualValues(t, cek, dCEK)
   706  	})
   707  
   708  	t.Run("Wrap/Unwrap with Sender key option containing empty key", func(t *testing.T) {
   709  		wrappedKey, err := rCrypto.WrapKey(cek, apu, apv, recipentPubKey, cryptoapi.WithSender(""))
   710  		require.NoError(t, err)
   711  
   712  		dCEK, err := rCrypto.UnwrapKey(wrappedKey, defaultKeyURL)
   713  		require.NoError(t, err)
   714  		require.EqualValues(t, cek, dCEK)
   715  	})
   716  
   717  	t.Run("Wrap/Unwrap with Sender key option containing nil key", func(t *testing.T) {
   718  		wrappedKey, err := rCrypto.WrapKey(cek, apu, apv, recipentPubKey, cryptoapi.WithSender(nil))
   719  		require.NoError(t, err)
   720  
   721  		dCEK, err := rCrypto.UnwrapKey(wrappedKey, defaultKeyURL, cryptoapi.WithSender(nil))
   722  		require.NoError(t, err)
   723  		require.EqualValues(t, cek, dCEK)
   724  	})
   725  }
   726  
   727  func TestRemoteCryptoWithHeadersFunc(t *testing.T) {
   728  	recipientKH, err := keyset.NewHandle(ecdh.NISTP256ECDHKWKeyTemplate())
   729  	require.NoError(t, err)
   730  
   731  	recipentPubKey, err := exportPubKey(recipientKH)
   732  	require.NoError(t, err)
   733  
   734  	senderKH, err := keyset.NewHandle(ecdh.NISTP256ECDHKWKeyTemplate())
   735  	require.NoError(t, err)
   736  
   737  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   738  		err = processPOSTWrapRequest(w, r, senderKH, recipientKH)
   739  		require.NoError(t, err)
   740  	})
   741  
   742  	server, url, client := CreateMockHTTPServerAndClient(t, hf)
   743  
   744  	defer func() {
   745  		e := server.Close()
   746  		require.NoError(t, e)
   747  	}()
   748  
   749  	defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
   750  		"{serverEndpoint}", url), defaultKeyStoreID)
   751  	defaultKeyURL := defaultKeystoreURL + "/keys/" + defaultKID
   752  
   753  	t.Run("New remote crypto using WithHeaders with success function", func(t *testing.T) {
   754  		rCrypto := New(defaultKeystoreURL, client, webkmsimpl.WithHeaders(mockAddHeadersFuncSuccess))
   755  		cek := random.GetRandomBytes(uint32(32))
   756  		apu := []byte("bob")
   757  		apv := []byte("alice")
   758  
   759  		// Test successful WrapKey/UnwrapKey
   760  		wKey, e := rCrypto.WrapKey(cek, apu, apv, recipentPubKey)
   761  		require.NoError(t, e)
   762  
   763  		decryptedCEK, e := rCrypto.UnwrapKey(wKey, defaultKeyURL)
   764  		require.NoError(t, e)
   765  		require.EqualValues(t, cek, decryptedCEK)
   766  	})
   767  
   768  	t.Run("New remote crypto using WithHeaders with error function", func(t *testing.T) {
   769  		rCrypto := New(defaultKeystoreURL, client, webkmsimpl.WithHeaders(mockAddHeadersFuncError))
   770  		cek := random.GetRandomBytes(uint32(32))
   771  		apu := []byte("bob")
   772  		apv := []byte("alice")
   773  
   774  		// Test successful WrapKey/UnwrapKey
   775  		_, err = rCrypto.WrapKey(cek, apu, apv, recipentPubKey)
   776  		require.EqualError(t, err, fmt.Errorf("posting WrapKey failed [%s%s, add optional request "+
   777  			"headers error: %w]", defaultKeystoreURL, wrapURI, errAddHeadersFunc).Error())
   778  
   779  		wKey := &cryptoapi.RecipientWrappedKey{
   780  			KID:          "1",
   781  			EncryptedCEK: []byte("111"),
   782  			EPK:          cryptoapi.PublicKey{},
   783  			Alg:          "zlg",
   784  			APU:          []byte("bob"),
   785  			APV:          []byte("Alice"),
   786  		}
   787  
   788  		_, err = rCrypto.UnwrapKey(wKey, defaultKeyURL)
   789  		require.EqualError(t, err, fmt.Errorf("posting UnwrapKey failed [%s%s, add optional request "+
   790  			"headers error: %w]", defaultKeyURL, unwrapURI, errAddHeadersFunc).Error())
   791  	})
   792  }
   793  
   794  func exportPubKey(kh *keyset.Handle) (*cryptoapi.PublicKey, error) {
   795  	pubKH, err := kh.Public()
   796  	if err != nil {
   797  		return nil, fmt.Errorf("exportPubKey: failed to get public keyset handle: %w", err)
   798  	}
   799  
   800  	buf := new(bytes.Buffer)
   801  	pubKeyWriter := localkms.NewWriter(buf)
   802  
   803  	err = pubKH.WriteWithNoSecrets(pubKeyWriter)
   804  	if err != nil {
   805  		return nil, fmt.Errorf("exportPubKey: failed to create keyset with no secrets (public "+
   806  			"key material): %w", err)
   807  	}
   808  
   809  	recPubKey := &cryptoapi.PublicKey{}
   810  
   811  	err = json.Unmarshal(buf.Bytes(), recPubKey)
   812  	if err != nil {
   813  		return nil, fmt.Errorf("exportPubKey: failed to unmarshal public key: %w", err)
   814  	}
   815  
   816  	return recPubKey, nil
   817  }
   818  
   819  func processPOSTWrapRequest(w http.ResponseWriter, r *http.Request, senderKH, recKH *keyset.Handle) error {
   820  	if valid := validateHTTPMethod(w, r); !valid {
   821  		return errors.New("http method invalid")
   822  	}
   823  
   824  	if valid := validatePostPayload(r, w); !valid {
   825  		return errors.New("http request body invalid")
   826  	}
   827  
   828  	reqBody, err := ioutil.ReadAll(r.Body)
   829  	if err != nil {
   830  		return err
   831  	}
   832  
   833  	cr, err := tinkcrypto.New()
   834  	if err != nil {
   835  		return err
   836  	}
   837  
   838  	if matchPath(r, wrapURI) {
   839  		if strings.Contains(r.URL.Path, keysURI+"/") {
   840  			// URL contains sender key id and has form "keystorepath/keys/{senderKeyId}/wrap"
   841  			err = wrapKeyPostHandle(w, reqBody, senderKH, cr)
   842  		} else {
   843  			err = wrapKeyPostHandle(w, reqBody, nil, cr)
   844  		}
   845  
   846  		if err != nil {
   847  			return err
   848  		}
   849  	}
   850  
   851  	if matchPath(r, unwrapURI) {
   852  		err = unwrapKeyPostHandle(w, reqBody, senderKH, recKH, cr)
   853  		if err != nil {
   854  			return err
   855  		}
   856  	}
   857  
   858  	return nil
   859  }
   860  
   861  func wrapKeyPostHandle(w http.ResponseWriter, reqBody []byte, senderKH *keyset.Handle, cr cryptoapi.Crypto) error {
   862  	wrapReq := &wrapKeyReq{}
   863  
   864  	err := json.Unmarshal(reqBody, wrapReq)
   865  	if err != nil {
   866  		return err
   867  	}
   868  
   869  	wk, err := buildRecipientWK(wrapReq.CEK, wrapReq.APU, wrapReq.APV, senderKH, wrapReq, cr)
   870  	if err != nil {
   871  		return err
   872  	}
   873  
   874  	resp := &wrapKeyResp{
   875  		RecipientWrappedKey: *wk,
   876  	}
   877  
   878  	mResp, err := json.Marshal(resp)
   879  	if err != nil {
   880  		return err
   881  	}
   882  
   883  	_, err = w.Write(mResp)
   884  	if err != nil {
   885  		return err
   886  	}
   887  
   888  	return nil
   889  }
   890  
   891  func buildRecipientWK(cek, apu, apv []byte, senderKH *keyset.Handle, wrapReq *wrapKeyReq,
   892  	cr cryptoapi.Crypto) (*cryptoapi.RecipientWrappedKey, error) {
   893  	var (
   894  		wk  *cryptoapi.RecipientWrappedKey
   895  		opt cryptoapi.WrapKeyOpts
   896  		err error
   897  	)
   898  
   899  	if senderKH != nil {
   900  		opt = cryptoapi.WithSender(senderKH)
   901  
   902  		wk, err = cr.WrapKey(cek, apu, apv, wrapReq.RecipientPubKey, opt)
   903  		if err != nil {
   904  			return nil, err
   905  		}
   906  	} else {
   907  		wk, err = cr.WrapKey(cek, apu, apv, wrapReq.RecipientPubKey)
   908  		if err != nil {
   909  			return nil, err
   910  		}
   911  	}
   912  
   913  	return wk, nil
   914  }
   915  
   916  func unwrapKeyPostHandle(w http.ResponseWriter, reqBody []byte, senderKH, recKH *keyset.Handle,
   917  	cr cryptoapi.Crypto) error {
   918  	unwrapReq := &unwrapKeyReq{}
   919  
   920  	err := json.Unmarshal(reqBody, unwrapReq)
   921  	if err != nil {
   922  		return err
   923  	}
   924  
   925  	var opt cryptoapi.WrapKeyOpts
   926  
   927  	var cek []byte
   928  
   929  	if unwrapReq.SenderPubKey != nil {
   930  		opt = cryptoapi.WithSender(senderKH)
   931  
   932  		cek, err = cr.UnwrapKey(&unwrapReq.WrappedKey, recKH, opt)
   933  		if err != nil {
   934  			return err
   935  		}
   936  	} else {
   937  		cek, err = cr.UnwrapKey(&unwrapReq.WrappedKey, recKH)
   938  		if err != nil {
   939  			return err
   940  		}
   941  	}
   942  
   943  	resp := &unwrapKeyResp{
   944  		Key: cek,
   945  	}
   946  
   947  	mResp, err := json.Marshal(resp)
   948  	if err != nil {
   949  		return err
   950  	}
   951  
   952  	_, err = w.Write(mResp)
   953  	if err != nil {
   954  		return err
   955  	}
   956  
   957  	return nil
   958  }
   959  
   960  func TestBBSSignVerify_DeriveProofVerifyProof(t *testing.T) {
   961  	kh, err := keyset.NewHandle(bbs.BLS12381G2KeyTemplate())
   962  	require.NoError(t, err)
   963  
   964  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   965  		err = processBBSPOSTRequest(w, r, kh)
   966  		require.NoError(t, err)
   967  	})
   968  
   969  	server, url, client := CreateMockHTTPServerAndClient(t, hf)
   970  
   971  	defer func() {
   972  		e := server.Close()
   973  		require.NoError(t, e)
   974  	}()
   975  
   976  	defaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
   977  		"{serverEndpoint}", url), defaultKeyStoreID)
   978  	defaultKeyURL := defaultKeystoreURL + "/keys/" + defaultKID
   979  	rCrypto := New(defaultKeystoreURL, client)
   980  	msg := [][]byte{[]byte("lorem ipsum"), []byte("dolor sit amet,"), []byte("consectetur adipiscing elit,")}
   981  
   982  	nonce := make([]byte, 32)
   983  
   984  	_, err = rand.Read(nonce)
   985  	require.NoError(t, err)
   986  
   987  	// test successful BBS+ Sign/Verify/DeriveProof/VerifyProof
   988  	sig, err := rCrypto.SignMulti(msg, defaultKeyURL)
   989  	require.NoError(t, err)
   990  
   991  	err = rCrypto.VerifyMulti(msg, sig, defaultKeyURL)
   992  	require.NoError(t, err)
   993  
   994  	proof, err := rCrypto.DeriveProof(msg, sig, nonce, []int{1, 2}, defaultKeyURL)
   995  	require.NoError(t, err)
   996  
   997  	err = rCrypto.VerifyProof([][]byte{msg[1], msg[2]}, proof, nonce, defaultKeyURL)
   998  	require.NoError(t, err)
   999  
  1000  	t.Run("BBS+ Sign Post request failure", func(t *testing.T) {
  1001  		blankClient := &http.Client{}
  1002  		tmpCrypto := New(defaultKeystoreURL, blankClient)
  1003  
  1004  		_, err = tmpCrypto.SignMulti(nil, defaultKeyURL)
  1005  		require.Contains(t, err.Error(), fmt.Sprintf("posting BBS+ Sign message failed [%s, Post \"%s\": %s",
  1006  			defaultKeyURL+signMultiURI, defaultKeyURL+signMultiURI, getCertsErrorSubText()))
  1007  	})
  1008  
  1009  	t.Run("BBS+ Verify Post request failure", func(t *testing.T) {
  1010  		blankClient := &http.Client{}
  1011  		tmpCrypto := New(defaultKeystoreURL, blankClient)
  1012  
  1013  		err = tmpCrypto.VerifyMulti(nil, nil, defaultKeyURL)
  1014  		require.Contains(t, err.Error(), fmt.Sprintf("posting BBS+ Verify signature failed [%s, Post \"%s\": %s",
  1015  			defaultKeyURL+verifyMultiURI, defaultKeyURL+verifyMultiURI, getCertsErrorSubText()))
  1016  	})
  1017  
  1018  	t.Run("BBS+ Derive Proof Post request failure", func(t *testing.T) {
  1019  		blankClient := &http.Client{}
  1020  		tmpCrypto := New(defaultKeystoreURL, blankClient)
  1021  
  1022  		_, err = tmpCrypto.DeriveProof(nil, nil, nil, nil, defaultKeyURL)
  1023  		require.Contains(t, err.Error(), fmt.Sprintf("posting BBS+ Derive proof message failed [%s, Post \"%s\": %s",
  1024  			defaultKeyURL+deriveProofURI, defaultKeyURL+deriveProofURI, getCertsErrorSubText()))
  1025  	})
  1026  
  1027  	t.Run("BBS+ Verify Proof Post request failure", func(t *testing.T) {
  1028  		blankClient := &http.Client{}
  1029  		tmpCrypto := New(defaultKeystoreURL, blankClient)
  1030  
  1031  		err = tmpCrypto.VerifyProof(nil, nil, nil, defaultKeyURL)
  1032  		require.Contains(t, err.Error(), fmt.Sprintf("posting BBS+ Verify proof failed [%s, Post \"%s\": %s",
  1033  			defaultKeyURL+verifyProofURI, defaultKeyURL+verifyProofURI, getCertsErrorSubText()))
  1034  	})
  1035  
  1036  	t.Run("BBS+ Sign json marshal failure", func(t *testing.T) {
  1037  		remoteCrypto2 := New(defaultKeystoreURL, client)
  1038  
  1039  		remoteCrypto2.marshalFunc = failingMarshal
  1040  		_, err = remoteCrypto2.SignMulti(msg, defaultKeyURL)
  1041  		require.EqualError(t, err, fmt.Errorf("marshal signature request for BBS+ Sign failed [%s, %w]",
  1042  			defaultKeyURL+signMultiURI, errFailingMarshal).Error())
  1043  	})
  1044  
  1045  	t.Run("BBS+ Sign json unmarshal failure", func(t *testing.T) {
  1046  		remoteCrypto2 := New(defaultKeystoreURL, client)
  1047  
  1048  		remoteCrypto2.unmarshalFunc = failingUnmarshal
  1049  		_, err = remoteCrypto2.SignMulti(msg, defaultKeyURL)
  1050  		require.EqualError(t, err, fmt.Errorf("unmarshal signature for BBS+ Sign failed [%s, %w]",
  1051  			defaultKeyURL+signMultiURI, errFailingUnmarshal).Error())
  1052  	})
  1053  
  1054  	t.Run("BBS+ Verify json marshal failure", func(t *testing.T) {
  1055  		remoteCrypto2 := New(defaultKeystoreURL, client)
  1056  
  1057  		remoteCrypto2.marshalFunc = failingMarshal
  1058  		err = remoteCrypto2.VerifyMulti(msg, sig, defaultKeyURL)
  1059  		require.EqualError(t, err, fmt.Errorf("marshal verify request for BBS+ Verify failed [%s, %w]",
  1060  			defaultKeyURL+verifyMultiURI, errFailingMarshal).Error())
  1061  	})
  1062  
  1063  	t.Run("BBS+ Derive Proof json marshal failure", func(t *testing.T) {
  1064  		remoteCrypto2 := New(defaultKeystoreURL, client)
  1065  
  1066  		remoteCrypto2.marshalFunc = failingMarshal
  1067  		_, err = remoteCrypto2.DeriveProof(msg, sig, nonce, []int{0}, defaultKeyURL)
  1068  		require.EqualError(t, err, fmt.Errorf("marshal request for BBS+ Derive proof failed [%s, %w]",
  1069  			defaultKeyURL+deriveProofURI, errFailingMarshal).Error())
  1070  	})
  1071  
  1072  	t.Run("BBS+ Derive Proof json unmarshal failure", func(t *testing.T) {
  1073  		remoteCrypto2 := New(defaultKeystoreURL, client)
  1074  
  1075  		remoteCrypto2.unmarshalFunc = failingUnmarshal
  1076  		_, err = remoteCrypto2.DeriveProof(msg, sig, nonce, []int{0}, defaultKeyURL)
  1077  		require.EqualError(t, err, fmt.Errorf("unmarshal request for BBS+ Derive proof failed [%s, %w]",
  1078  			defaultKeyURL+deriveProofURI, errFailingUnmarshal).Error())
  1079  	})
  1080  
  1081  	t.Run("BBS+ Verify Proof json marshal failure", func(t *testing.T) {
  1082  		remoteCrypto2 := New(defaultKeystoreURL, client)
  1083  
  1084  		remoteCrypto2.marshalFunc = failingMarshal
  1085  		err = remoteCrypto2.VerifyProof([][]byte{msg[1], msg[2]}, proof, nonce, defaultKeyURL)
  1086  		require.EqualError(t, err, fmt.Errorf("marshal request for BBS+ Verify proof failed [%s, %w]",
  1087  			defaultKeyURL+verifyProofURI, errFailingMarshal).Error())
  1088  	})
  1089  }
  1090  
  1091  func TestNonOKStatusCode(t *testing.T) {
  1092  	aad := []byte("dolor sit")
  1093  
  1094  	nonOKServer, nonOkURL, nonOKClient := CreateMockHTTPServerAndClientNotOKStatusCode(t)
  1095  
  1096  	defer func() {
  1097  		e := nonOKServer.Close()
  1098  		require.NoError(t, e)
  1099  	}()
  1100  
  1101  	nonOKDefaultKeystoreURL := fmt.Sprintf("%s/%s", strings.ReplaceAll(webkmsimpl.KeystoreEndpoint,
  1102  		"{serverEndpoint}", nonOkURL), defaultKeyStoreID)
  1103  	nonOKDefaultKeyURL := nonOKDefaultKeystoreURL + "/keys/" + defaultKID
  1104  
  1105  	t.Run("Encrypt Post request failure 501", func(t *testing.T) {
  1106  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1107  
  1108  		_, _, err := tmpCrypto.Encrypt(nil, aad, nonOKDefaultKeyURL)
  1109  		require.Contains(t, err.Error(), "501")
  1110  	})
  1111  
  1112  	t.Run("Decrypt Post request failure 501", func(t *testing.T) {
  1113  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1114  
  1115  		_, err := tmpCrypto.Decrypt(nil, aad, nil, nonOKDefaultKeyURL)
  1116  		require.Contains(t, err.Error(), "501")
  1117  	})
  1118  
  1119  	t.Run("Sign Post request failure 501", func(t *testing.T) {
  1120  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1121  
  1122  		_, err := tmpCrypto.Sign([]byte("Test message"), nonOKDefaultKeyURL)
  1123  		require.Contains(t, err.Error(), "501")
  1124  	})
  1125  
  1126  	t.Run("Verify Post request failure 501", func(t *testing.T) {
  1127  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1128  
  1129  		err := tmpCrypto.Verify([]byte{}, []byte("Test message"), nonOKDefaultKeyURL)
  1130  		require.Contains(t, err.Error(), "501")
  1131  	})
  1132  
  1133  	t.Run("ComputeMAC Post request failure 501", func(t *testing.T) {
  1134  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1135  
  1136  		_, err := tmpCrypto.ComputeMAC([]byte("Test message"), nonOKDefaultKeyURL)
  1137  		require.Contains(t, err.Error(), "501")
  1138  	})
  1139  
  1140  	t.Run("VerifyMAC Post request failure 501", func(t *testing.T) {
  1141  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1142  
  1143  		err := tmpCrypto.VerifyMAC([]byte{}, []byte("Test message"), nonOKDefaultKeyURL)
  1144  		require.Contains(t, err.Error(), "501")
  1145  	})
  1146  
  1147  	t.Run("SignMulti Post request failure 501", func(t *testing.T) {
  1148  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1149  
  1150  		_, err := tmpCrypto.SignMulti([][]byte{
  1151  			[]byte("Test message 1"),
  1152  			[]byte("Test message 2"),
  1153  		}, nonOKDefaultKeyURL)
  1154  		require.Contains(t, err.Error(), "501")
  1155  	})
  1156  
  1157  	t.Run("VerifyMAC Post request failure 501", func(t *testing.T) {
  1158  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1159  
  1160  		err := tmpCrypto.VerifyMulti([][]byte{
  1161  			[]byte("Test message 1"),
  1162  			[]byte("Test message 2"),
  1163  		}, []byte{}, nonOKDefaultKeyURL)
  1164  		require.Contains(t, err.Error(), "501")
  1165  	})
  1166  
  1167  	t.Run("WrapKey Post request failure 501", func(t *testing.T) {
  1168  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1169  
  1170  		_, err := tmpCrypto.WrapKey([]byte{}, []byte{}, []byte{}, nil)
  1171  		require.Contains(t, err.Error(), "501")
  1172  	})
  1173  
  1174  	t.Run("UnwrapKey Post request failure 501", func(t *testing.T) {
  1175  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1176  
  1177  		_, err := tmpCrypto.UnwrapKey(&cryptoapi.RecipientWrappedKey{}, nonOKDefaultKeyURL)
  1178  		require.Contains(t, err.Error(), "501")
  1179  	})
  1180  
  1181  	t.Run("DeriveProof Post request failure 501", func(t *testing.T) {
  1182  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1183  
  1184  		_, err := tmpCrypto.DeriveProof([][]byte{
  1185  			[]byte("Test message 1"),
  1186  			[]byte("Test message 2"),
  1187  		}, []byte{}, []byte{}, []int{}, nonOKDefaultKeyURL)
  1188  		require.Contains(t, err.Error(), "501")
  1189  	})
  1190  
  1191  	t.Run("VerifyProof Post request failure 501", func(t *testing.T) {
  1192  		tmpCrypto := New(nonOKDefaultKeyURL, nonOKClient)
  1193  
  1194  		err := tmpCrypto.VerifyProof([][]byte{
  1195  			[]byte("Test message 1"),
  1196  			[]byte("Test message 2"),
  1197  		}, []byte{}, []byte{}, nonOKDefaultKeyURL)
  1198  		require.Contains(t, err.Error(), "501")
  1199  	})
  1200  }
  1201  
  1202  // nolint:gocyclo
  1203  func processBBSPOSTRequest(w http.ResponseWriter, r *http.Request, sigKH *keyset.Handle) error {
  1204  	if valid := validateHTTPMethod(w, r); !valid {
  1205  		return errors.New("http method invalid")
  1206  	}
  1207  
  1208  	if valid := validatePostPayload(r, w); !valid {
  1209  		return errors.New("http request body invalid")
  1210  	}
  1211  
  1212  	reqBody, err := ioutil.ReadAll(r.Body)
  1213  	if err != nil {
  1214  		return err
  1215  	}
  1216  
  1217  	if matchPath(r, signMultiURI) {
  1218  		err = bbsSignPOSTHandle(w, reqBody, sigKH)
  1219  		if err != nil {
  1220  			return err
  1221  		}
  1222  	}
  1223  
  1224  	if matchPath(r, verifyMultiURI) {
  1225  		err = bbsVerifyPOSTHandle(reqBody, sigKH)
  1226  		if err != nil {
  1227  			return err
  1228  		}
  1229  	}
  1230  
  1231  	if matchPath(r, deriveProofURI) {
  1232  		err = bbsDeriveProofPOSTHandle(w, reqBody, sigKH)
  1233  		if err != nil {
  1234  			return err
  1235  		}
  1236  	}
  1237  
  1238  	if matchPath(r, verifyProofURI) {
  1239  		err = bbsVerifyProofPOSTHandle(reqBody, sigKH)
  1240  		if err != nil {
  1241  			return err
  1242  		}
  1243  	}
  1244  
  1245  	return nil
  1246  }
  1247  
  1248  func bbsSignPOSTHandle(w http.ResponseWriter, reqBody []byte, sigKH *keyset.Handle) error {
  1249  	sigReq := &signMultiReq{}
  1250  
  1251  	err := json.Unmarshal(reqBody, sigReq)
  1252  	if err != nil {
  1253  		return err
  1254  	}
  1255  
  1256  	signer, err := bbs.NewSigner(sigKH)
  1257  	if err != nil {
  1258  		return fmt.Errorf("create new signer: %w", err)
  1259  	}
  1260  
  1261  	s, err := signer.Sign(sigReq.Messages)
  1262  	if err != nil {
  1263  		return fmt.Errorf("sign msg: %w", err)
  1264  	}
  1265  
  1266  	resp := &signResp{
  1267  		Signature: s,
  1268  	}
  1269  
  1270  	mResp, err := json.Marshal(resp)
  1271  	if err != nil {
  1272  		return err
  1273  	}
  1274  
  1275  	_, err = w.Write(mResp)
  1276  	if err != nil {
  1277  		return err
  1278  	}
  1279  
  1280  	return nil
  1281  }
  1282  
  1283  func bbsVerifyPOSTHandle(reqBody []byte, sigKH *keyset.Handle) error {
  1284  	verReq := &verifyMultiReq{}
  1285  
  1286  	err := json.Unmarshal(reqBody, verReq)
  1287  	if err != nil {
  1288  		return err
  1289  	}
  1290  
  1291  	pubKH, err := sigKH.Public()
  1292  	if err != nil {
  1293  		return err
  1294  	}
  1295  
  1296  	verifier, err := bbs.NewVerifier(pubKH)
  1297  	if err != nil {
  1298  		return fmt.Errorf("create new BBS+ verifier: %w", err)
  1299  	}
  1300  
  1301  	err = verifier.Verify(verReq.Messages, verReq.Signature)
  1302  	if err != nil {
  1303  		return fmt.Errorf("BBS+ verify msg: %w", err)
  1304  	}
  1305  
  1306  	return nil
  1307  }
  1308  
  1309  func bbsDeriveProofPOSTHandle(w http.ResponseWriter, reqBody []byte, sigKH *keyset.Handle) error {
  1310  	deriveProofReq := &deriveProofReq{}
  1311  
  1312  	err := json.Unmarshal(reqBody, deriveProofReq)
  1313  	if err != nil {
  1314  		return err
  1315  	}
  1316  
  1317  	pubKH, err := sigKH.Public()
  1318  	if err != nil {
  1319  		return err
  1320  	}
  1321  
  1322  	verifier, err := bbs.NewVerifier(pubKH)
  1323  	if err != nil {
  1324  		return fmt.Errorf("create new BBS+ verifier: %w", err)
  1325  	}
  1326  
  1327  	proof, err := verifier.DeriveProof(deriveProofReq.Messages,
  1328  		deriveProofReq.Signature,
  1329  		deriveProofReq.Nonce,
  1330  		deriveProofReq.RevealedIndexes)
  1331  	if err != nil {
  1332  		return fmt.Errorf("BBS+ derive proof msg: %w", err)
  1333  	}
  1334  
  1335  	resp := &deriveProofResp{
  1336  		Proof: proof,
  1337  	}
  1338  
  1339  	mResp, err := json.Marshal(resp)
  1340  	if err != nil {
  1341  		return err
  1342  	}
  1343  
  1344  	_, err = w.Write(mResp)
  1345  	if err != nil {
  1346  		return err
  1347  	}
  1348  
  1349  	return nil
  1350  }
  1351  
  1352  func bbsVerifyProofPOSTHandle(reqBody []byte, sigKH *keyset.Handle) error {
  1353  	verifyProofReq := &verifyProofReq{}
  1354  
  1355  	err := json.Unmarshal(reqBody, verifyProofReq)
  1356  	if err != nil {
  1357  		return err
  1358  	}
  1359  
  1360  	pubKH, err := sigKH.Public()
  1361  	if err != nil {
  1362  		return err
  1363  	}
  1364  
  1365  	verifier, err := bbs.NewVerifier(pubKH)
  1366  	if err != nil {
  1367  		return fmt.Errorf("create new BBS+ verifier: %w", err)
  1368  	}
  1369  
  1370  	err = verifier.VerifyProof(verifyProofReq.Messages, verifyProofReq.Proof, verifyProofReq.Nonce)
  1371  	if err != nil {
  1372  		return fmt.Errorf("BBS+ verify proof msg: %w", err)
  1373  	}
  1374  
  1375  	return nil
  1376  }
  1377  
  1378  func TestCloseResponseBody(t *testing.T) {
  1379  	closeResponseBody(&errFailingCloser{}, "testing close fail should log: errFailingCloser always fails")
  1380  }
  1381  
  1382  func nonceSize(ps *primitiveset.PrimitiveSet) int {
  1383  	var ivSize int
  1384  	// AES256GCM and XChacha20Poly1305 nonce sizes supported only for now
  1385  	switch ps.Primary.Primitive.(type) {
  1386  	case *aeadsubtle.XChaCha20Poly1305:
  1387  		ivSize = chacha20poly1305.NonceSizeX
  1388  	case *aeadsubtle.AESGCM:
  1389  		ivSize = aeadsubtle.AESGCMIVSize
  1390  	default:
  1391  		ivSize = aeadsubtle.AESGCMIVSize
  1392  	}
  1393  
  1394  	return ivSize
  1395  }
  1396  
  1397  // validateHTTPMethod validate HTTP method and content-type.
  1398  func validateHTTPMethod(w http.ResponseWriter, r *http.Request) bool {
  1399  	switch r.Method {
  1400  	case http.MethodPost, http.MethodGet:
  1401  	default:
  1402  		http.Error(w, "HTTP Method not allowed", http.StatusMethodNotAllowed)
  1403  		return false
  1404  	}
  1405  
  1406  	ct := r.Header.Get("Content-type")
  1407  	if ct != webkmsimpl.ContentType && r.Method == http.MethodPost {
  1408  		http.Error(w, fmt.Sprintf("Unsupported Content-type \"%s\"", ct), http.StatusUnsupportedMediaType)
  1409  		return false
  1410  	}
  1411  
  1412  	return true
  1413  }
  1414  
  1415  // validatePayload validate and get the payload from the request.
  1416  func validatePostPayload(r *http.Request, w http.ResponseWriter) bool {
  1417  	if r.ContentLength == 0 && r.Method == http.MethodPost { // empty payload should not be accepted for POST request
  1418  		http.Error(w, "Empty payload", http.StatusBadRequest)
  1419  		return false
  1420  	}
  1421  
  1422  	return true
  1423  }
  1424  
  1425  // CreateMockHTTPServerAndClient creates mock http server and client using tls and returns them.
  1426  func CreateMockHTTPServerAndClient(t *testing.T, inHandler http.Handler) (net.Listener, string, *http.Client) {
  1427  	server := startMockServer(inHandler)
  1428  	port := getServerPort(server)
  1429  	serverURL := fmt.Sprintf("https://localhost:%d", port)
  1430  
  1431  	// build a mock cert pool
  1432  	cp := x509.NewCertPool()
  1433  	err := addCertsToCertPool(cp)
  1434  	require.NoError(t, err)
  1435  
  1436  	// build a tls.Config instance to be used by the outbound transport
  1437  	tlsConfig := &tls.Config{ //nolint:gosec
  1438  		RootCAs:      cp,
  1439  		Certificates: nil,
  1440  	}
  1441  
  1442  	// create an http client to communicate with the server that has our inbound handlers set above
  1443  	client := &http.Client{
  1444  		Timeout: clientTimeout,
  1445  		Transport: &http.Transport{
  1446  			TLSClientConfig: tlsConfig,
  1447  		},
  1448  	}
  1449  
  1450  	return server, serverURL, client
  1451  }
  1452  
  1453  func CreateMockHTTPServerAndClientNotOKStatusCode(t *testing.T) (net.Listener, string, *http.Client) {
  1454  	hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1455  		w.WriteHeader(501)
  1456  	})
  1457  
  1458  	return CreateMockHTTPServerAndClient(t, hf)
  1459  }
  1460  
  1461  func startMockServer(handler http.Handler) net.Listener {
  1462  	// ":0" will make the listener auto assign a free port
  1463  	listener, err := net.Listen("tcp", "127.0.0.1:0")
  1464  	if err != nil {
  1465  		errorLogger.Fatalf("HTTP listener failed to start: %s", err)
  1466  	}
  1467  
  1468  	go func() {
  1469  		err := http.ServeTLS(listener, handler, certPrefix+"ec-pubCert1.pem", certPrefix+"ec-key1.pem")
  1470  		if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
  1471  			errorLogger.Fatalf("HTTP server failed to start: %s", err)
  1472  		}
  1473  	}()
  1474  
  1475  	return listener
  1476  }
  1477  
  1478  func getServerPort(server net.Listener) int {
  1479  	// read dynamic port assigned to the server to be used by the client
  1480  	return server.Addr().(*net.TCPAddr).Port
  1481  }
  1482  
  1483  func addCertsToCertPool(pool *x509.CertPool) error {
  1484  	var rawCerts []string
  1485  
  1486  	// add contents of ec-pubCert(1, 2 and 3).pem to rawCerts
  1487  	for i := 1; i <= 3; i++ {
  1488  		certPath := fmt.Sprintf("%sec-pubCert%d.pem", certPrefix, i)
  1489  		// Create a pool with server certificates
  1490  
  1491  		path := filepath.Clean(certPath)
  1492  
  1493  		cert, e := ioutil.ReadFile(path)
  1494  		if e != nil {
  1495  			return fmt.Errorf("reading certificate failed: %w", e)
  1496  		}
  1497  
  1498  		rawCerts = append(rawCerts, string(cert))
  1499  	}
  1500  
  1501  	certs := decodeCerts(rawCerts)
  1502  	for i := range certs {
  1503  		pool.AddCert(certs[i])
  1504  	}
  1505  
  1506  	return nil
  1507  }
  1508  
  1509  // decodeCerts will decode a list of pemCertsList (string) into a list of x509 certificates.
  1510  func decodeCerts(pemCertsList []string) []*x509.Certificate {
  1511  	var certs []*x509.Certificate
  1512  
  1513  	for _, pemCertsString := range pemCertsList {
  1514  		pemCerts := []byte(pemCertsString)
  1515  		for len(pemCerts) > 0 {
  1516  			var block *pem.Block
  1517  
  1518  			block, pemCerts = pem.Decode(pemCerts)
  1519  			if block == nil {
  1520  				break
  1521  			}
  1522  
  1523  			if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
  1524  				continue
  1525  			}
  1526  
  1527  			cert, err := x509.ParseCertificate(block.Bytes)
  1528  			if err != nil {
  1529  				continue
  1530  			}
  1531  
  1532  			certs = append(certs, cert)
  1533  		}
  1534  	}
  1535  
  1536  	return certs
  1537  }
  1538  
  1539  var errFailingMarshal = errors.New("failingMarshal always fails")
  1540  
  1541  func failingMarshal(interface{}) ([]byte, error) {
  1542  	return nil, errFailingMarshal
  1543  }
  1544  
  1545  var errFailingUnmarshal = errors.New("failingUnmarshal always fails")
  1546  
  1547  func failingUnmarshal([]byte, interface{}) error {
  1548  	return errFailingUnmarshal
  1549  }
  1550  
  1551  type errFailingCloser struct{}
  1552  
  1553  func (c *errFailingCloser) Close() error {
  1554  	return errors.New("errFailingCloser always fails")
  1555  }
  1556  
  1557  func mockAddHeadersFuncSuccess(req *http.Request) (*http.Header, error) {
  1558  	// mocking a call to an auth server to get necessary credentials.
  1559  	// It only sets mock http.Header entries for testing purposes.
  1560  	req.Header.Set("controller", "mockController")
  1561  	req.Header.Set("authServerURL", "mockAuthServerURL")
  1562  	req.Header.Set("secret", "mockSecret")
  1563  
  1564  	return &req.Header, nil
  1565  }
  1566  
  1567  var errAddHeadersFunc = errors.New("mockAddHeadersFuncError always fails")
  1568  
  1569  func mockAddHeadersFuncError(_ *http.Request) (*http.Header, error) {
  1570  	return nil, errAddHeadersFunc
  1571  }
  1572  
  1573  func matchPath(r *http.Request, uri string) bool {
  1574  	return strings.LastIndex(r.URL.Path, uri) == len(r.URL.Path)-len(uri)
  1575  }
  1576  
  1577  func getCertsErrorSubText() string {
  1578  	sharedPrefix := "tls: failed to verify certificate: "
  1579  
  1580  	if runtime.GOOS == "darwin" {
  1581  		return sharedPrefix + "x509: “*.example.com” certificate is not trusted"
  1582  	}
  1583  
  1584  	return sharedPrefix + "x509: certificate signed by unknown authority"
  1585  }