github.com/trustbloc/kms-go@v1.1.2/doc/jose/jwk/jwksupport/jwk_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package jwksupport
     8  
     9  import (
    10  	"crypto/ecdsa"
    11  	"crypto/ed25519"
    12  	"crypto/elliptic"
    13  	"crypto/rand"
    14  	"crypto/rsa"
    15  	"crypto/sha256"
    16  	"crypto/x509"
    17  	"crypto/x509/pkix"
    18  	"encoding/asn1"
    19  	"encoding/base64"
    20  	"encoding/json"
    21  	"fmt"
    22  	"strings"
    23  	"testing"
    24  
    25  	"github.com/btcsuite/btcd/btcec/v2"
    26  	"github.com/go-jose/go-jose/v3"
    27  	"github.com/stretchr/testify/require"
    28  	"github.com/trustbloc/bbs-signature-go/bbs12381g2pub"
    29  
    30  	"github.com/trustbloc/kms-go/doc/jose/jwk"
    31  	cryptoapi "github.com/trustbloc/kms-go/spi/crypto"
    32  	"github.com/trustbloc/kms-go/spi/kms"
    33  	"github.com/trustbloc/kms-go/util/cryptoutil"
    34  )
    35  
    36  func TestDecodeJWK(t *testing.T) {
    37  	t.Run("Test decode public key success", func(t *testing.T) {
    38  		tests := []struct {
    39  			name    string
    40  			jwkJSON string
    41  		}{
    42  			{
    43  				name: "get public key bytes Ed25519 JWK",
    44  				jwkJSON: `{
    45  							"kty": "OKP",
    46  							"use": "enc",
    47  							"crv": "Ed25519",
    48  							"kid": "sample@sample.id",
    49  							"x": "sEHL6KXs8bUz9Ss2qSWWjhhRMHVjrog0lzFENM132R8",
    50  							"alg": "EdDSA"
    51  						}`,
    52  			},
    53  			{
    54  				name: "get public key bytes X25519 JWK",
    55  				jwkJSON: `{
    56  							"kty": "OKP",
    57  							"use": "enc",
    58  							"crv": "X25519",
    59  							"kid": "sample@sample.id",
    60  							"x": "sEHL6KXs8bUz9Ss2qSWWjhhRMHVjrog0lzFENM132R8"
    61  						}`,
    62  			},
    63  			{
    64  				name: "get public key bytes BBS+ JWK",
    65  				//nolint:lll
    66  				jwkJSON: `{
    67  							"kty": "EC",
    68  							"use": "enc",
    69  							"crv": "BLS12381_G2",
    70  							"kid": "sample@sample.id",
    71  							"x": "tKWJu0SOY7onl4tEyOOH11XBriQN2JgzV-UmjgBMSsNkcAx3_l97SVYViSDBouTVBkBfrLh33C5icDD-4UEDxNO3Wn1ijMHvn2N63DU4pkezA3kGN81jGbwbrsMPpiOF"
    72  						}`,
    73  			},
    74  			{
    75  				name: "get public key bytes RSA JWK",
    76  				jwkJSON: `{
    77  							"kty": "RSA",
    78  							"e": "AQAB",
    79  							"use": "enc",
    80  							"kid": "sample@sample.id",
    81  							"alg": "RS256",
    82  							"n": "1hOl09BUnwY7jFBqoZKa4XDmIuc0YFb4y_5ThiHhLRW68aNG5Vo23n3ugND2GK3PsguZqJ_HrWCGVuVlKTmFg` +
    83  					`JWQD9ZnVcYqScgHpQRhxMBi86PIvXR01D_PWXZZjvTRakpvQxUT5bVBdWnaBHQoxDBt0YIVi5a7x-gXB1aDlts4RTMpfS9BPmEjX` +
    84  					`4lciozwS6Ow_wTO3C2YGa_Our0ptIxr-x_3sMbPCN8Fe_iaBDezeDAm39xCNjFa1E735ipXA4eUW_6SzFJ5-bM2UKba2WE6xUaEa5G1` +
    85  					`MDDHCG5LKKd6Mhy7SSAzPOR2FTKYj89ch2asCPlbjHTu8jS6Iy8"
    86  						}`,
    87  			},
    88  			{
    89  				name: "get public key bytes EC P-256 JWK",
    90  				jwkJSON: `{
    91  							"kty": "EC",
    92  							"use": "enc",
    93  							"crv": "P-256",
    94  							"kid": "sample@sample.id",
    95  							"x": "JR7nhI47w7bxrNkp7Xt1nbmozNn-RB2Q-PWi7KHT8J0",
    96  							"y": "iXmKtH0caOgB1vV0CQwinwK999qdDvrssKhdbiAz9OI",
    97  							"alg": "ES256"
    98  						}`,
    99  			},
   100  			{
   101  				name: "get public key bytes EC P-384 JWK",
   102  				jwkJSON: `{
   103  							"kty": "EC",
   104  							"use": "enc",
   105  							"crv": "P-384",
   106  							"kid": "sample@sample.id",
   107  							"x": "GGFw14WnABx5S__MLwjy7WPgmPzCNbygbJikSqwx1nQ7APAiIyLeiAeZnAFQSr8C",
   108  							"y": "Bjev4lkaRbd4Ery0vnO8Ox4QgIDGbuflmFq0HhL-QHIe3KhqxrqZqbQYGlDNudEv",
   109  							"alg": "ES384"
   110  						}`,
   111  			},
   112  			{
   113  				name: "get public key bytes EC P-521 JWK",
   114  				jwkJSON: `{
   115  							"kty": "EC",
   116  							"use": "enc",
   117  							"crv": "P-521",
   118  							"kid": "sample@sample.id",
   119  							"x": "AZi-AxJkB09qw8dBnNrz53xM-wER0Y5IYXSEWSTtzI5Sdv_5XijQn9z-vGz1pMdww-C75GdpAzp2ghejZJSxbAd6",
   120  							"y": "AZzRvW8NBytGNbF3dyNOMHB0DHCOzGp8oYBv_ZCyJbQUUnq-TYX7j8-PlKe9Ce5acxZzrcUKVtJ4I8JgI5x9oXIW",
   121  							"alg": "ES521"
   122  						}`,
   123  			},
   124  			{
   125  				name: "get public key bytes EC SECP256K1 JWK",
   126  				jwkJSON: `{
   127      						"kty": "EC",
   128          					"use": "enc",
   129          					"crv": "secp256k1",
   130          					"kid": "sample@sample.id",
   131          					"x": "YRrvJocKf39GpdTnd-zBFE0msGDqawR-Cmtc6yKoFsM",
   132          					"y": "kE-dMH9S3mxnTXo0JFEhraCU_tVYFDfpu9tpP1LfVKQ",
   133          					"alg": "ES256K"
   134  						}`,
   135  			},
   136  			{
   137  				name: "get private key bytes EC SECP256K1 JWK",
   138  				jwkJSON: `{
   139  							"kty": "EC",
   140  							"d": "Lg5xrN8Usd_T-MfqBIs3bUWQCNsXY8hGU-Ru3Joom8E",
   141  							"use": "sig",
   142  							"crv": "secp256k1",
   143  							"kid": "sample@sample.id",
   144  							"x": "dv6X5DheBaFWR2H_yv9pUI2dcmL2XX8m7zgFc9Coaqg",
   145  							"y": "AUVSmytVWP350kV1RHhQ6AcCWaJj8AFt4aNLlDws7C4",
   146  							"alg": "ES256K"
   147  						}`,
   148  			},
   149  		}
   150  
   151  		t.Parallel()
   152  
   153  		for _, test := range tests {
   154  			tc := test
   155  			t.Run(tc.name, func(t *testing.T) {
   156  				var jwkKey jwk.JWK
   157  
   158  				err := json.Unmarshal([]byte(tc.jwkJSON), &jwkKey)
   159  				require.NoError(t, err)
   160  
   161  				pkBytes, err := jwkKey.PublicKeyBytes()
   162  				require.NoError(t, err)
   163  				require.NotEmpty(t, pkBytes)
   164  
   165  				jwkBytes, err := json.Marshal(&jwkKey)
   166  				require.NoError(t, err)
   167  				require.NotEmpty(t, jwkBytes)
   168  
   169  				switch tc.name {
   170  				case "get public key bytes X25519 JWK":
   171  					jwkKey1, err := JWKFromX25519Key(jwkKey.Key.([]byte))
   172  					require.NoError(t, err)
   173  					require.NotNil(t, jwkKey1)
   174  					require.Equal(t, x25519Crv, jwkKey1.Crv)
   175  					require.Equal(t, cryptoutil.Curve25519KeySize, len(jwkKey1.Key.([]byte)))
   176  					require.Equal(t, okpKty, jwkKey1.Kty)
   177  
   178  					newJWK, err := PubKeyBytesToJWK(jwkKey.Key.([]byte), kms.X25519ECDHKWType)
   179  					require.NoError(t, err)
   180  					require.Equal(t, x25519Crv, newJWK.Crv)
   181  					require.Equal(t, cryptoutil.Curve25519KeySize, len(newJWK.Key.([]byte)))
   182  					require.Equal(t, okpKty, newJWK.Kty)
   183  				case "get public key bytes BBS+ JWK":
   184  					jwkKey2, err := JWKFromKey(jwkKey.Key)
   185  					require.NoError(t, err)
   186  					require.NotNil(t, jwkKey2)
   187  					require.Equal(t, bls12381G2Crv, jwkKey2.Crv)
   188  					bbsPubKey, ok := jwkKey2.Key.(*bbs12381g2pub.PublicKey)
   189  					require.True(t, ok)
   190  					bbsPubKeyBytes, err := bbsPubKey.Marshal()
   191  					require.NoError(t, err)
   192  					require.Equal(t, bls12381G2Size, len(bbsPubKeyBytes))
   193  					require.Equal(t, ecKty, jwkKey2.Kty)
   194  
   195  					newJWK, err := PubKeyBytesToJWK(pkBytes, kms.BLS12381G2Type)
   196  					require.NoError(t, err)
   197  					require.NotNil(t, newJWK)
   198  					require.Equal(t, bls12381G2Crv, newJWK.Crv)
   199  					bbsPubKey, ok = newJWK.Key.(*bbs12381g2pub.PublicKey)
   200  					require.True(t, ok)
   201  					bbsPubKeyBytes, err = bbsPubKey.Marshal()
   202  					require.NoError(t, err)
   203  					require.Equal(t, bls12381G2Size, len(bbsPubKeyBytes))
   204  					require.Equal(t, ecKty, newJWK.Kty)
   205  				case "get public key bytes Ed25519 JWK":
   206  					jwkKey3, err := JWKFromKey(jwkKey.Key)
   207  					require.NoError(t, err)
   208  					require.NotNil(t, jwkKey3)
   209  					require.Equal(t, "Ed25519", jwkKey3.Crv)
   210  					require.Equal(t, ed25519.PublicKeySize, len(jwkKey3.Key.(ed25519.PublicKey)))
   211  					require.Equal(t, okpKty, jwkKey3.Kty)
   212  
   213  					newJWK, err := PubKeyBytesToJWK(pkBytes, kms.ED25519Type)
   214  					require.NoError(t, err)
   215  					require.NotNil(t, newJWK)
   216  					require.Equal(t, "Ed25519", newJWK.Crv)
   217  					require.Equal(t, ed25519.PublicKeySize, len(newJWK.Key.(ed25519.PublicKey)))
   218  					require.Equal(t, okpKty, newJWK.Kty)
   219  				case "get public key bytes EC SECP256K1 JWK":
   220  					jwkKey8, err := JWKFromKey(jwkKey.Key)
   221  					require.NoError(t, err)
   222  					require.NotNil(t, jwkKey8)
   223  					require.Equal(t, btcec.S256().Params().Name, jwkKey8.Crv)
   224  					require.Equal(t, "EC", jwkKey8.Kty)
   225  					ecKey, ok := jwkKey8.Key.(*ecdsa.PublicKey)
   226  					require.True(t, ok)
   227  					require.Equal(t, "YRrvJocKf39GpdTnd-zBFE0msGDqawR-Cmtc6yKoFsM",
   228  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   229  					require.Equal(t, "kE-dMH9S3mxnTXo0JFEhraCU_tVYFDfpu9tpP1LfVKQ",
   230  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   231  
   232  					newJWK, err := PubKeyBytesToJWK(pkBytes, kms.ECDSASecp256k1TypeIEEEP1363)
   233  					require.NoError(t, err)
   234  					require.NotNil(t, newJWK)
   235  					require.Equal(t, btcec.S256().Params().Name, newJWK.Crv)
   236  					require.Equal(t, "EC", newJWK.Kty)
   237  					ecKey, ok = newJWK.Key.(*ecdsa.PublicKey)
   238  					require.True(t, ok)
   239  					require.Equal(t, "YRrvJocKf39GpdTnd-zBFE0msGDqawR-Cmtc6yKoFsM",
   240  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   241  					require.Equal(t, "kE-dMH9S3mxnTXo0JFEhraCU_tVYFDfpu9tpP1LfVKQ",
   242  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   243  
   244  				case "get public key bytes EC P-256 JWK":
   245  					jwkKey4, err := JWKFromKey(jwkKey.Key)
   246  					require.NoError(t, err)
   247  					require.NotNil(t, jwkKey4)
   248  					require.Equal(t, elliptic.P256().Params().Name, jwkKey4.Crv)
   249  					require.Equal(t, "EC", jwkKey4.Kty)
   250  					ecKey, ok := jwkKey4.Key.(*ecdsa.PublicKey)
   251  					require.True(t, ok)
   252  					require.Equal(t, "JR7nhI47w7bxrNkp7Xt1nbmozNn-RB2Q-PWi7KHT8J0",
   253  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   254  					require.Equal(t, "iXmKtH0caOgB1vV0CQwinwK999qdDvrssKhdbiAz9OI",
   255  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   256  
   257  					newJWK, err := PubKeyBytesToJWK(pkBytes, kms.ECDSAP256TypeIEEEP1363)
   258  					require.NoError(t, err)
   259  					require.NotNil(t, newJWK)
   260  					require.Equal(t, elliptic.P256().Params().Name, newJWK.Crv)
   261  					require.Equal(t, "EC", newJWK.Kty)
   262  					ecKey, ok = newJWK.Key.(*ecdsa.PublicKey)
   263  					require.True(t, ok)
   264  					require.Equal(t, "JR7nhI47w7bxrNkp7Xt1nbmozNn-RB2Q-PWi7KHT8J0",
   265  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   266  					require.Equal(t, "iXmKtH0caOgB1vV0CQwinwK999qdDvrssKhdbiAz9OI",
   267  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   268  				case "get public key bytes EC P-384 JWK":
   269  					jwkKey5, err := JWKFromKey(jwkKey.Key)
   270  					require.NoError(t, err)
   271  					require.NotNil(t, jwkKey5)
   272  					require.Equal(t, elliptic.P384().Params().Name, jwkKey5.Crv)
   273  					require.Equal(t, "EC", jwkKey5.Kty)
   274  					ecKey, ok := jwkKey5.Key.(*ecdsa.PublicKey)
   275  					require.True(t, ok)
   276  					require.Equal(t, "GGFw14WnABx5S__MLwjy7WPgmPzCNbygbJikSqwx1nQ7APAiIyLeiAeZnAFQSr8C",
   277  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   278  					require.Equal(t, "Bjev4lkaRbd4Ery0vnO8Ox4QgIDGbuflmFq0HhL-QHIe3KhqxrqZqbQYGlDNudEv",
   279  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   280  
   281  					newJWK, err := PubKeyBytesToJWK(pkBytes, kms.ECDSAP384TypeIEEEP1363)
   282  					require.NoError(t, err)
   283  					require.NotNil(t, newJWK)
   284  					require.Equal(t, elliptic.P384().Params().Name, newJWK.Crv)
   285  					require.Equal(t, "EC", newJWK.Kty)
   286  					ecKey, ok = newJWK.Key.(*ecdsa.PublicKey)
   287  					require.True(t, ok)
   288  					require.Equal(t, "GGFw14WnABx5S__MLwjy7WPgmPzCNbygbJikSqwx1nQ7APAiIyLeiAeZnAFQSr8C",
   289  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   290  					require.Equal(t, "Bjev4lkaRbd4Ery0vnO8Ox4QgIDGbuflmFq0HhL-QHIe3KhqxrqZqbQYGlDNudEv",
   291  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   292  				case "get public key bytes EC P-521 JWK":
   293  					jwkKey6, err := JWKFromKey(jwkKey.Key)
   294  					require.NoError(t, err)
   295  					require.NotNil(t, jwkKey6)
   296  					require.Equal(t, elliptic.P521().Params().Name, jwkKey6.Crv)
   297  					require.Equal(t, "EC", jwkKey6.Kty)
   298  					ecKey, ok := jwkKey6.Key.(*ecdsa.PublicKey)
   299  					require.True(t, ok)
   300  					require.Equal(t, "AZi-AxJkB09qw8dBnNrz53xM-wER0Y5IYXSEWSTtzI5Sdv_5XijQn9z-vGz1pMdww-C75GdpAzp2ghejZJSxbAd6",
   301  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   302  					require.Equal(t, "AZzRvW8NBytGNbF3dyNOMHB0DHCOzGp8oYBv_ZCyJbQUUnq-TYX7j8-PlKe9Ce5acxZzrcUKVtJ4I8JgI5x9oXIW",
   303  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   304  
   305  					newJWK, err := PubKeyBytesToJWK(pkBytes, kms.ECDSAP521TypeIEEEP1363)
   306  					require.NoError(t, err)
   307  					require.NotNil(t, newJWK)
   308  					require.Equal(t, elliptic.P521().Params().Name, newJWK.Crv)
   309  					require.Equal(t, "EC", newJWK.Kty)
   310  					ecKey, ok = newJWK.Key.(*ecdsa.PublicKey)
   311  					require.True(t, ok)
   312  					require.Equal(t, "AZi-AxJkB09qw8dBnNrz53xM-wER0Y5IYXSEWSTtzI5Sdv_5XijQn9z-vGz1pMdww-C75GdpAzp2ghejZJSxbAd6",
   313  						base64.RawURLEncoding.EncodeToString(ecKey.X.Bytes()))
   314  					require.Equal(t, "AZzRvW8NBytGNbF3dyNOMHB0DHCOzGp8oYBv_ZCyJbQUUnq-TYX7j8-PlKe9Ce5acxZzrcUKVtJ4I8JgI5x9oXIW",
   315  						base64.RawURLEncoding.EncodeToString(ecKey.Y.Bytes()))
   316  				default:
   317  					jwkKey7, err := JWKFromKey(jwkKey.Key)
   318  					require.NoError(t, err)
   319  					require.NotNil(t, jwkKey7)
   320  				}
   321  			})
   322  		}
   323  	})
   324  }
   325  
   326  func TestJWKFromPublicKeyFailure(t *testing.T) {
   327  	key, err := JWKFromKey(nil)
   328  	require.Error(t, err)
   329  	require.Contains(t, err.Error(), "create JWK")
   330  	require.Nil(t, key)
   331  }
   332  
   333  func TestJWKFromX25519KeyFailure(t *testing.T) {
   334  	key, err := JWKFromX25519Key([]byte(strings.Repeat("a", 33))) // try to create a key larger than X25519
   335  	require.EqualError(t, err, "create JWK: marshalX25519: invalid key")
   336  	require.Nil(t, key)
   337  
   338  	key, err = JWKFromX25519Key(nil) // try to create a nil key
   339  	require.EqualError(t, err, "create JWK: marshalX25519: invalid key")
   340  	require.Nil(t, key)
   341  }
   342  
   343  func TestBBSJWK(t *testing.T) {
   344  	t.Run("test JWKFromKey() from BBS private key", func(t *testing.T) {
   345  		var jwk1 *jwk.JWK
   346  
   347  		_, privateKey, err := bbs12381g2pub.GenerateKeyPair(sha256.New, nil)
   348  		require.NoError(t, err)
   349  
   350  		jwkKey := &jwk.JWK{
   351  			JSONWebKey: jose.JSONWebKey{
   352  				Key: privateKey,
   353  			},
   354  			Kty: ecKty,
   355  			Crv: bls12381G2Crv,
   356  		}
   357  
   358  		jwk1, err = JWKFromKey(privateKey)
   359  		require.NoError(t, err)
   360  		require.EqualValues(t, jwkKey, jwk1)
   361  	})
   362  }
   363  
   364  func TestPubKeyBytesToKey(t *testing.T) {
   365  	tt := []struct {
   366  		keyTypes   []kms.KeyType
   367  		getKey     func(keyType kms.KeyType) ([]byte, error)
   368  		expectType interface{}
   369  	}{
   370  		{
   371  			keyTypes: []kms.KeyType{kms.ED25519Type},
   372  			getKey: func(kms.KeyType) ([]byte, error) {
   373  				pubKey, _, err := ed25519.GenerateKey(rand.Reader)
   374  				return pubKey, err
   375  			},
   376  			expectType: ed25519.PublicKey{},
   377  		},
   378  		{
   379  			keyTypes: []kms.KeyType{kms.X25519ECDHKWType},
   380  			getKey: func(kms.KeyType) ([]byte, error) {
   381  				pubKeyBytes := make([]byte, 32)
   382  				_, err := rand.Read(pubKeyBytes)
   383  
   384  				return pubKeyBytes, err
   385  			},
   386  			expectType: []byte{},
   387  		},
   388  		{
   389  			keyTypes: []kms.KeyType{kms.BLS12381G2Type},
   390  			getKey: func(kms.KeyType) ([]byte, error) {
   391  				pubKey, _, err := bbs12381g2pub.GenerateKeyPair(sha256.New, nil)
   392  				if err != nil {
   393  					return nil, err
   394  				}
   395  
   396  				keyBytes, err := pubKey.Marshal()
   397  				return keyBytes, err
   398  			},
   399  			expectType: &bbs12381g2pub.PublicKey{},
   400  		},
   401  		{
   402  			keyTypes: []kms.KeyType{
   403  				kms.ECDSAP256TypeIEEEP1363,
   404  				kms.ECDSAP384TypeIEEEP1363,
   405  				kms.ECDSAP521TypeIEEEP1363,
   406  				kms.ECDSASecp256k1TypeIEEEP1363,
   407  			},
   408  			getKey: func(keyType kms.KeyType) ([]byte, error) {
   409  				crv := getECDSACurve(keyType)
   410  				privKey, err := ecdsa.GenerateKey(crv, rand.Reader)
   411  				if err != nil {
   412  					return nil, err
   413  				}
   414  
   415  				keyBytes := elliptic.Marshal(crv, privKey.X, privKey.Y)
   416  				return keyBytes, nil
   417  			},
   418  			expectType: &ecdsa.PublicKey{},
   419  		},
   420  		{
   421  			keyTypes: []kms.KeyType{
   422  				kms.ECDSAP256TypeDER,
   423  				kms.ECDSAP384TypeDER,
   424  				kms.ECDSAP521TypeDER,
   425  			},
   426  			getKey: func(keyType kms.KeyType) ([]byte, error) {
   427  				crv := getECDSACurve(keyType)
   428  				privKey, err := ecdsa.GenerateKey(crv, rand.Reader)
   429  				if err != nil {
   430  					return nil, err
   431  				}
   432  
   433  				return x509.MarshalPKIXPublicKey(&privKey.PublicKey)
   434  			},
   435  			expectType: &ecdsa.PublicKey{},
   436  		},
   437  		{
   438  			keyTypes: []kms.KeyType{
   439  				kms.RSARS256,
   440  				kms.RSAPS256,
   441  			},
   442  			getKey: func(keyType kms.KeyType) ([]byte, error) {
   443  				key, err := rsa.GenerateKey(rand.Reader, 2048)
   444  				if err != nil {
   445  					return nil, err
   446  				}
   447  
   448  				return x509.MarshalPKIXPublicKey(&key.PublicKey)
   449  			},
   450  			expectType: &rsa.PublicKey{},
   451  		},
   452  		{
   453  			keyTypes: []kms.KeyType{
   454  				kms.ECDSASecp256k1TypeDER,
   455  			},
   456  			getKey: func(keyType kms.KeyType) ([]byte, error) {
   457  				priv, err := btcec.NewPrivateKey()
   458  				if err != nil {
   459  					return nil, err
   460  				}
   461  
   462  				pubKey := priv.PubKey()
   463  
   464  				return marshalSecp256k1DER(pubKey.ToECDSA())
   465  			},
   466  			expectType: &ecdsa.PublicKey{},
   467  		},
   468  		{
   469  			keyTypes: []kms.KeyType{
   470  				kms.NISTP256ECDHKWType,
   471  				kms.NISTP384ECDHKWType,
   472  				kms.NISTP521ECDHKWType,
   473  			},
   474  			getKey: func(keyType kms.KeyType) ([]byte, error) {
   475  				crv := getECDSACurve(keyType)
   476  				privKey, err := ecdsa.GenerateKey(crv, rand.Reader)
   477  				require.NoError(t, err)
   478  
   479  				pubKey := &cryptoapi.PublicKey{
   480  					X:     privKey.X.Bytes(),
   481  					Y:     privKey.Y.Bytes(),
   482  					Curve: crv.Params().Name,
   483  					Type:  "EC",
   484  				}
   485  
   486  				return json.Marshal(pubKey)
   487  			},
   488  			expectType: &ecdsa.PublicKey{},
   489  		},
   490  	}
   491  
   492  	for _, tc := range tt {
   493  		for _, keyType := range tc.keyTypes {
   494  			t.Run(string(keyType), func(t *testing.T) {
   495  				pkBytes, err := tc.getKey(keyType)
   496  				require.NoError(t, err)
   497  
   498  				pk, err := PubKeyBytesToKey(pkBytes, keyType)
   499  				require.NoError(t, err)
   500  
   501  				require.IsType(t, tc.expectType, pk)
   502  			})
   503  		}
   504  	}
   505  
   506  	t.Run("Secp256k1DER parse errors", func(t *testing.T) {
   507  		t.Run("asn.1 data invalid", func(t *testing.T) {
   508  			pkb := []byte("foo bar baz")
   509  
   510  			pk, err := PubKeyBytesToKey(pkb, kms.ECDSASecp256k1TypeDER)
   511  			require.Error(t, err)
   512  			require.Nil(t, pk)
   513  		})
   514  
   515  		t.Run("data invalid", func(t *testing.T) {
   516  			pkb := []byte("foo bar baz")
   517  
   518  			pk, err := PubKeyBytesToKey(pkb, kms.ECDSASecp256k1TypeIEEEP1363)
   519  			require.Error(t, err)
   520  			require.Nil(t, pk)
   521  		})
   522  
   523  		t.Run("asn.1 input has trailing data", func(t *testing.T) {
   524  			priv, err := btcec.NewPrivateKey()
   525  			require.NoError(t, err)
   526  
   527  			pubKey := priv.PubKey()
   528  
   529  			pkb, err := marshalSecp256k1DER(pubKey.ToECDSA())
   530  			require.NoError(t, err)
   531  
   532  			pkb = append(pkb, 0, 0, 1, 1)
   533  
   534  			pk, err := PubKeyBytesToKey(pkb, kms.ECDSASecp256k1TypeDER)
   535  			require.Error(t, err)
   536  			require.Nil(t, pk)
   537  		})
   538  
   539  		t.Run("not Secp256k1 key", func(t *testing.T) {
   540  			priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
   541  			require.NoError(t, err)
   542  
   543  			pubKey := priv.PublicKey
   544  
   545  			pkb, err := marshalSecp256k1DER(&pubKey)
   546  			require.NoError(t, err)
   547  
   548  			pkb = append(pkb, 0, 0, 1, 1)
   549  
   550  			pk, err := PubKeyBytesToKey(pkb, kms.ECDSASecp256k1TypeDER)
   551  			require.Error(t, err)
   552  			require.Nil(t, pk)
   553  		})
   554  	})
   555  
   556  	t.Run("invalid key type", func(t *testing.T) {
   557  		pkb := []byte("foo bar baz")
   558  
   559  		pk, err := PubKeyBytesToKey(pkb, "foo bar")
   560  		require.Error(t, err)
   561  		require.Contains(t, err.Error(), "invalid key type")
   562  		require.Nil(t, pk)
   563  	})
   564  }
   565  
   566  func TestPubKeyBytesToJWK(t *testing.T) {
   567  	tests := []struct {
   568  		name    string
   569  		keyType kms.KeyType
   570  	}{
   571  		{
   572  			name:    "P-256 IEEE1363 test",
   573  			keyType: kms.ECDSAP256TypeIEEEP1363,
   574  		},
   575  		{
   576  			name:    "P-384 IEEE1363 test",
   577  			keyType: kms.ECDSAP384TypeIEEEP1363,
   578  		},
   579  		{
   580  			name:    "P-521 IEEE1363 test",
   581  			keyType: kms.ECDSAP521TypeIEEEP1363,
   582  		},
   583  		{
   584  			name:    "P-256 DER test",
   585  			keyType: kms.ECDSAP256TypeDER,
   586  		},
   587  		{
   588  			name:    "P-384 DER test",
   589  			keyType: kms.ECDSAP384TypeDER,
   590  		},
   591  		{
   592  			name:    "P-521 DER test",
   593  			keyType: kms.ECDSAP521TypeDER,
   594  		},
   595  		{
   596  			name:    "Ed25519 test",
   597  			keyType: kms.ED25519Type,
   598  		},
   599  		{
   600  			name:    "BLS12381G2 test",
   601  			keyType: kms.BLS12381G2Type,
   602  		},
   603  		{
   604  			name:    "X25519 test",
   605  			keyType: kms.X25519ECDHKWType,
   606  		},
   607  		{
   608  			name:    "P-256 KW test",
   609  			keyType: kms.NISTP256ECDHKWType,
   610  		},
   611  		{
   612  			name:    "P-384 KW test",
   613  			keyType: kms.NISTP384ECDHKWType,
   614  		},
   615  		{
   616  			name:    "P-521 KW test",
   617  			keyType: kms.NISTP521ECDHKWType,
   618  		},
   619  		{
   620  			name:    "undefined type test",
   621  			keyType: "undefined",
   622  		},
   623  	}
   624  
   625  	t.Parallel()
   626  
   627  	for _, test := range tests {
   628  		tc := test
   629  		t.Run(tc.name, func(t *testing.T) {
   630  			switch tc.keyType {
   631  			case kms.ED25519Type:
   632  				pubKey, _, err := ed25519.GenerateKey(rand.Reader)
   633  				require.NoError(t, err)
   634  
   635  				jwkKey, err := PubKeyBytesToJWK(pubKey, tc.keyType)
   636  				require.NoError(t, err)
   637  				require.NotEmpty(t, jwkKey)
   638  				require.Equal(t, okpKty, jwkKey.Kty)
   639  				require.Equal(t, "Ed25519", jwkKey.Crv)
   640  			case kms.BLS12381G2Type:
   641  				pubKey, _, err := bbs12381g2pub.GenerateKeyPair(sha256.New, nil)
   642  				require.NoError(t, err)
   643  
   644  				keyBytes, err := pubKey.Marshal()
   645  				require.NoError(t, err)
   646  
   647  				jwkKey, err := PubKeyBytesToJWK(keyBytes, tc.keyType)
   648  				require.NoError(t, err)
   649  				require.NotEmpty(t, jwkKey)
   650  				require.Equal(t, ecKty, jwkKey.Kty)
   651  				require.Equal(t, bls12381G2Crv, jwkKey.Crv)
   652  
   653  				_, err = PubKeyBytesToJWK([]byte("invalidbbsKey"), tc.keyType)
   654  				require.EqualError(t, err, "invalid size of public key")
   655  			case kms.ECDSAP256TypeIEEEP1363, kms.ECDSAP384TypeIEEEP1363, kms.ECDSAP521TypeIEEEP1363:
   656  				crv := getECDSACurve(tc.keyType)
   657  				privKey, err := ecdsa.GenerateKey(crv, rand.Reader)
   658  				require.NoError(t, err)
   659  
   660  				keyBytes := elliptic.Marshal(crv, privKey.X, privKey.Y)
   661  
   662  				jwkKey, err := PubKeyBytesToJWK(keyBytes, tc.keyType)
   663  				require.NoError(t, err)
   664  				require.NotEmpty(t, jwkKey)
   665  				require.Equal(t, "EC", jwkKey.Kty)
   666  				require.Equal(t, crv.Params().Name, jwkKey.Crv)
   667  			case kms.ECDSAP256TypeDER, kms.ECDSAP384TypeDER, kms.ECDSAP521TypeDER:
   668  				crv := getECDSACurve(tc.keyType)
   669  				privKey, err := ecdsa.GenerateKey(crv, rand.Reader)
   670  				require.NoError(t, err)
   671  
   672  				keyBytes, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey)
   673  				require.NoError(t, err)
   674  
   675  				jwkKey, err := PubKeyBytesToJWK(keyBytes, tc.keyType)
   676  				require.NoError(t, err)
   677  				require.NotEmpty(t, jwkKey)
   678  				require.Equal(t, "EC", jwkKey.Kty)
   679  				require.Equal(t, crv.Params().Name, jwkKey.Crv)
   680  
   681  				_, err = PubKeyBytesToJWK([]byte("invalid EC Key"), tc.keyType)
   682  				require.Error(t, err)
   683  				require.Contains(t, err.Error(), "asn1: structure error: tags don't match")
   684  
   685  				pubEdKey, _, err := ed25519.GenerateKey(rand.Reader)
   686  				require.NoError(t, err)
   687  
   688  				pubEdKeyBytes, err := x509.MarshalPKIXPublicKey(pubEdKey)
   689  				require.NoError(t, err)
   690  
   691  				_, err = PubKeyBytesToJWK(pubEdKeyBytes, tc.keyType)
   692  				require.EqualError(t, err, "invalid EC key")
   693  			case kms.NISTP256ECDHKWType, kms.NISTP384ECDHKWType, kms.NISTP521ECDHKWType:
   694  				crv := getECDSACurve(tc.keyType)
   695  				privKey, err := ecdsa.GenerateKey(crv, rand.Reader)
   696  				require.NoError(t, err)
   697  
   698  				pubKey := &cryptoapi.PublicKey{
   699  					X:     privKey.X.Bytes(),
   700  					Y:     privKey.Y.Bytes(),
   701  					Curve: crv.Params().Name,
   702  					Type:  "EC",
   703  				}
   704  
   705  				keyBytes, err := json.Marshal(pubKey)
   706  				require.NoError(t, err)
   707  
   708  				jwkKey, err := PubKeyBytesToJWK(keyBytes, tc.keyType)
   709  				require.NoError(t, err)
   710  				require.NotEmpty(t, jwkKey)
   711  				require.Equal(t, "EC", jwkKey.Kty)
   712  				require.Equal(t, crv.Params().Name, jwkKey.Crv)
   713  
   714  				_, err = PubKeyBytesToJWK([]byte("invalid EC Key"), tc.keyType)
   715  				require.EqualError(t, err, "invalid character 'i' looking for beginning of value")
   716  			case kms.X25519ECDHKWType:
   717  				pubKeyBytes := make([]byte, 32)
   718  				_, err := rand.Read(pubKeyBytes)
   719  				require.NoError(t, err)
   720  
   721  				jwkKey, err := PubKeyBytesToJWK(pubKeyBytes, tc.keyType)
   722  				require.NoError(t, err)
   723  				require.NotEmpty(t, jwkKey)
   724  				require.Equal(t, okpKty, jwkKey.Kty)
   725  				require.Equal(t, x25519Crv, jwkKey.Crv)
   726  			default:
   727  				_, err := PubKeyBytesToJWK([]byte{}, tc.keyType)
   728  				require.EqualError(t, err, "convertPubKeyJWK: invalid key type: undefined")
   729  			}
   730  		})
   731  	}
   732  }
   733  
   734  func TestEmptyCurve(t *testing.T) {
   735  	crv := getECDSACurve(kms.ChaCha20Poly1305)
   736  	require.Empty(t, crv)
   737  }
   738  
   739  func TestPublicKeyFromJWK(t *testing.T) {
   740  	prv256Key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   741  	require.NoError(t, err)
   742  
   743  	jwk256PrivKey, err := JWKFromKey(prv256Key)
   744  	require.NoError(t, err)
   745  
   746  	jwk256PubKey, err := JWKFromKey(&prv256Key.PublicKey)
   747  	require.NoError(t, err)
   748  
   749  	prv384Key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
   750  	require.NoError(t, err)
   751  
   752  	jwk384PrivKey, err := JWKFromKey(prv384Key)
   753  	require.NoError(t, err)
   754  
   755  	jwk384PubKey, err := JWKFromKey(&prv384Key.PublicKey)
   756  	require.NoError(t, err)
   757  
   758  	prv521Key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
   759  	require.NoError(t, err)
   760  
   761  	jwk521PrivKey, err := JWKFromKey(prv521Key)
   762  	require.NoError(t, err)
   763  
   764  	jwk521PubKey, err := JWKFromKey(&prv521Key.PublicKey)
   765  	require.NoError(t, err)
   766  
   767  	edPubKey, edPrivKey, err := ed25519.GenerateKey(rand.Reader)
   768  	require.NoError(t, err)
   769  
   770  	jwkEdPrivKey, err := JWKFromKey(edPrivKey)
   771  	require.NoError(t, err)
   772  
   773  	jwkEdPubKey, err := JWKFromKey(edPubKey)
   774  	require.NoError(t, err)
   775  
   776  	bbsPubKey, bbsPrivKey, err := bbs12381g2pub.GenerateKeyPair(sha256.New, nil)
   777  	require.NoError(t, err)
   778  
   779  	jwkBLSPrivKey, err := JWKFromKey(bbsPrivKey)
   780  	require.NoError(t, err)
   781  
   782  	jwkBLSPubKey, err := JWKFromKey(bbsPubKey)
   783  	require.NoError(t, err)
   784  
   785  	tests := []struct {
   786  		name   string
   787  		jwkKey *jwk.JWK
   788  	}{
   789  		{
   790  			name:   "success p-256 key from JWK with private key",
   791  			jwkKey: jwk256PrivKey,
   792  		},
   793  		{
   794  			name:   "success p-256 key from JWK with public key",
   795  			jwkKey: jwk256PubKey,
   796  		},
   797  		{
   798  			name:   "success p-384 key from JWK with private key",
   799  			jwkKey: jwk384PrivKey,
   800  		},
   801  		{
   802  			name:   "success p-384 key from JWK with public key",
   803  			jwkKey: jwk384PubKey,
   804  		},
   805  		{
   806  			name:   "success p-521 key from JWK with private key",
   807  			jwkKey: jwk521PrivKey,
   808  		},
   809  		{
   810  			name:   "success p-521 key from JWK with public key",
   811  			jwkKey: jwk521PubKey,
   812  		},
   813  		{
   814  			name:   "success ed25519 key from JWK with private key",
   815  			jwkKey: jwkEdPrivKey,
   816  		},
   817  		{
   818  			name:   "success ed25519 key from JWK with public key",
   819  			jwkKey: jwkEdPubKey,
   820  		},
   821  		{
   822  			name:   "success BBS key from JWK with private key",
   823  			jwkKey: jwkBLSPrivKey,
   824  		},
   825  		{
   826  			name:   "success BBS key from JWK with public key",
   827  			jwkKey: jwkBLSPubKey,
   828  		},
   829  		{
   830  			name: "fail invalid key type",
   831  			jwkKey: &jwk.JWK{
   832  				JSONWebKey: jose.JSONWebKey{
   833  					Key: "badKeytype",
   834  				},
   835  				Kty: "",
   836  				Crv: "",
   837  			},
   838  		},
   839  	}
   840  
   841  	for _, tt := range tests {
   842  		tc := tt
   843  
   844  		t.Run(tc.name, func(t *testing.T) {
   845  			var pubKey *cryptoapi.PublicKey
   846  
   847  			pubKey, err = PublicKeyFromJWK(tc.jwkKey)
   848  			if strings.HasPrefix(tc.name, "success ") {
   849  				require.NoError(t, err)
   850  				require.Equal(t, tc.jwkKey.Crv, pubKey.Curve)
   851  			} else if strings.EqualFold(tc.name, "fail invalid key type") {
   852  				require.EqualError(t, err, fmt.Sprintf("publicKeyFromJWK: unsupported jwk key type %T", tc.jwkKey.Key))
   853  			}
   854  		})
   855  	}
   856  
   857  	t.Run("failure with empty jwk", func(t *testing.T) {
   858  		_, err = PublicKeyFromJWK(nil)
   859  		require.EqualError(t, err, "publicKeyFromJWK: jwk is empty")
   860  	})
   861  }
   862  
   863  func TestRSAKeyFailParse(t *testing.T) {
   864  	resultJWK, err := PubKeyBytesToJWK([]byte{0x1}, kms.RSARS256)
   865  	require.ErrorContains(t, err, "rsa: invalid public key")
   866  	require.Nil(t, resultJWK)
   867  }
   868  
   869  func TestRSAKey(t *testing.T) {
   870  	key, err := rsa.GenerateKey(rand.Reader, 2048)
   871  	require.NoError(t, err)
   872  
   873  	pubBytes, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
   874  	require.NoError(t, err)
   875  
   876  	resultJWK, err := PubKeyBytesToJWK(pubBytes, kms.RSARS256)
   877  	require.NoError(t, err)
   878  
   879  	pb, err := PublicKeyFromJWK(resultJWK)
   880  	require.NoError(t, err)
   881  	require.NotNil(t, pb)
   882  	require.NotNil(t, pb.N)
   883  	require.NotNil(t, pb.E)
   884  	require.Equal(t, "RSA", pb.Type)
   885  }
   886  
   887  type PublicKeyInfo struct {
   888  	Raw       asn1.RawContent
   889  	Algorithm pkix.AlgorithmIdentifier
   890  	PublicKey asn1.BitString
   891  }
   892  
   893  func marshalSecp256k1DER(pub *ecdsa.PublicKey) ([]byte, error) {
   894  	publicKeyBytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
   895  
   896  	pki := PublicKeyInfo{
   897  		Algorithm: pkix.AlgorithmIdentifier{
   898  			Algorithm: asn1.ObjectIdentifier{
   899  				2, 0, // incorrect but syntactically valid data to allow asn.1 marshal to succeed
   900  			},
   901  		},
   902  		PublicKey: asn1.BitString{
   903  			Bytes:     publicKeyBytes,
   904  			BitLength: 8 * len(publicKeyBytes),
   905  		},
   906  	}
   907  
   908  	out, err := asn1.Marshal(pki)
   909  	if err != nil {
   910  		return nil, err
   911  	}
   912  
   913  	return out, nil
   914  }