...

Source file src/github.com/sigstore/cosign/v2/test/pkcs11_test.go

Documentation: github.com/sigstore/cosign/v2/test

     1  // Copyright 2021 The Sigstore Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build !pkcs11keydisabled && softhsm
    16  // +build !pkcs11keydisabled,softhsm
    17  
    18  // DANGER
    19  // This test requires SoftHSMv2 to be installed. An initialized token should already exist.
    20  // This test will import an RSA key pair, using the specified token label.
    21  // By default, the test assumes the following :
    22  //	- The SoftHSMv2 library is located at "/usr/local/lib/softhsm/libsofthsm2.so"
    23  //	- The initialized token has the label "My Token"
    24  //	- The initialized token has the pin "1234"
    25  //	- The test will import the key pair using the key label "My Key"
    26  // These values can be overriden using the following environment variable :
    27  //	- SOFTHSM_LIB
    28  // 	- SOFTHSM_TOKENLABEL
    29  // 	- SOFTHSM_PIN
    30  // 	- SOFTHSM_KEYLABEL
    31  // By default, the test makes use of the following SoftHSMv2 configuration files :
    32  //	- /etc/softhsm2.conf
    33  // 	- /etc/softhsm.conf
    34  // These values can be overriden using the following environment variable :
    35  //	- SOFTHSM2_CONF
    36  // 	- SOFTHSM_CONF
    37  
    38  package test
    39  
    40  import (
    41  	"bytes"
    42  	"context"
    43  	"crypto/rsa"
    44  	"crypto/x509"
    45  	"encoding/hex"
    46  	"encoding/pem"
    47  	"fmt"
    48  	"io"
    49  	"math/big"
    50  	"os"
    51  	"strings"
    52  	"testing"
    53  
    54  	// Import the functions directly for testing.
    55  
    56  	"github.com/miekg/pkcs11"
    57  	. "github.com/sigstore/cosign/v2/cmd/cosign/cli/pkcs11cli"
    58  	"github.com/sigstore/cosign/v2/pkg/cosign/pkcs11key"
    59  	"github.com/stretchr/testify/require"
    60  )
    61  
    62  var (
    63  	modulePath = "/usr/local/lib/softhsm/libsofthsm2.so"
    64  	tokenLabel = "My Token"
    65  	pin        = "1234"
    66  	keyLabel   = "My Key"
    67  
    68  	keyID = "355d2d0b569a2a0169e46b82e172cf99aca41400"
    69  	uri   = ""
    70  )
    71  
    72  func init() {
    73  	if x := os.Getenv("SOFTHSM_LIB"); x != "" {
    74  		modulePath = x
    75  	}
    76  	if x := os.Getenv("SOFTHSM_TOKENLABEL"); x != "" {
    77  		tokenLabel = x
    78  	}
    79  	if x := os.Getenv("SOFTHSM_PIN"); x != "" {
    80  		pin = x
    81  	}
    82  	if x := os.Getenv("SOFTHSM_KEYLABEL"); x != "" {
    83  		keyLabel = x
    84  	}
    85  	if x := os.Getenv("SOFTHSM_CONF"); x == "" {
    86  		os.Setenv("SOFTHSM_CONF", "/etc/softhsm.conf")
    87  	}
    88  	if x := os.Getenv("SOFTHSM2_CONF"); x == "" {
    89  		os.Setenv("SOFTHSM2_CONF", "/etc/softhsm2.conf")
    90  	}
    91  
    92  	keyIDBytes, _ := hex.DecodeString(keyID)
    93  	pkcs11UriConfig := pkcs11key.NewPkcs11UriConfigFromInput(modulePath, nil, tokenLabel, []byte(keyLabel), keyIDBytes, pin)
    94  	uri, _ = pkcs11UriConfig.Construct()
    95  }
    96  
    97  func TestParsePKCS11URI(t *testing.T) {
    98  	_ = context.Background()
    99  
   100  	uriString := "pkcs11:"
   101  	uriString += "library-manufacturer=manufacturer;library-description=description;library-version=1;"
   102  	uriString += "slot-manufacturer=manufacturer;slot-description=description;slot-id=1;"
   103  	uriString += "manufacturer=manufacturer;model=model;serial=12345678;token=token%20label;"
   104  	uriString += "type=private;object=key%20label;id=%6b%65%79%5f%69%64"
   105  	uriString += "?"
   106  	uriString += "module-path=/path/to/some%20folder/libmodule.so&module-name=libmodule.so&"
   107  	uriString += "pin-value=1234&pin-source=/path/to/pinfile"
   108  
   109  	pkcs11UriConfig := pkcs11key.NewPkcs11UriConfig()
   110  	must(pkcs11UriConfig.Parse(uriString), t)
   111  	require.Equal(t, pkcs11UriConfig.KeyID, []byte("key_id"))
   112  	require.Equal(t, pkcs11UriConfig.KeyLabel, []byte("key label"))
   113  	require.Equal(t, pkcs11UriConfig.ModulePath, "/path/to/some folder/libmodule.so")
   114  	require.Equal(t, pkcs11UriConfig.Pin, "1234")
   115  	require.Equal(t, *pkcs11UriConfig.SlotID, 1)
   116  	require.Equal(t, pkcs11UriConfig.TokenLabel, "token label")
   117  }
   118  
   119  func TestConstructPKCS11URI(t *testing.T) {
   120  	_ = context.Background()
   121  
   122  	uri := "pkcs11:token=token%20label;slot-id=1;id=%6b%65%79%5f%69%64;object=key%20label"
   123  	uri += "?"
   124  	uri += "module-path=/path/to/some%20folder/libmodule.so&pin-value=1234"
   125  
   126  	slotID := 1
   127  	pkcs11UriConfig := pkcs11key.NewPkcs11UriConfigFromInput("/path/to/some folder/libmodule.so", &slotID, "token label", []byte("key label"), []byte("key_id"), "1234")
   128  	uriString, err := pkcs11UriConfig.Construct()
   129  	require.NoError(t, err)
   130  	require.Equal(t, uri, uriString)
   131  }
   132  
   133  func TestListTokensCmd(t *testing.T) {
   134  	ctx := context.Background()
   135  
   136  	tokens, err := GetTokens(ctx, modulePath)
   137  	if err != nil {
   138  		t.Fatal(err)
   139  	}
   140  
   141  	bTokenFound := false
   142  	for _, token := range tokens {
   143  		if token.TokenInfo.Label == tokenLabel {
   144  			bTokenFound = true
   145  			break
   146  		}
   147  	}
   148  
   149  	if !bTokenFound {
   150  		t.Fatalf("token with label '%s' not found", tokenLabel)
   151  	}
   152  }
   153  
   154  func TestListKeysUrisCmd(t *testing.T) {
   155  	ctx := context.Background()
   156  
   157  	tokens, err := GetTokens(ctx, modulePath)
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  
   162  	bTokenFound := false
   163  	var slotID uint
   164  	for _, token := range tokens {
   165  		if token.TokenInfo.Label == tokenLabel {
   166  			bTokenFound = true
   167  			slotID = token.Slot
   168  			break
   169  		}
   170  	}
   171  	if !bTokenFound {
   172  		t.Fatalf("token with label '%s' not found", tokenLabel)
   173  	}
   174  
   175  	err = importKey(slotID)
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	defer deleteKey(slotID)
   180  
   181  	keysInfo, err := GetKeysInfo(ctx, modulePath, slotID, pin)
   182  	if err != nil {
   183  		t.Fatal(err)
   184  	}
   185  
   186  	bKeyFound := false
   187  	for _, keyInfo := range keysInfo {
   188  		if hex.EncodeToString(keyInfo.KeyID) == keyID && string(keyInfo.KeyLabel) == keyLabel {
   189  			foundUriConfig := pkcs11key.NewPkcs11UriConfig()
   190  			err = foundUriConfig.Parse(keyInfo.KeyURI)
   191  			if err != nil {
   192  				t.Fatal(err)
   193  			}
   194  
   195  			uriConfig := pkcs11key.NewPkcs11UriConfig()
   196  			err = uriConfig.Parse(uri)
   197  			if err != nil {
   198  				t.Fatal(err)
   199  			}
   200  
   201  			if foundUriConfig.TokenLabel == uriConfig.TokenLabel &&
   202  				bytes.Compare(foundUriConfig.KeyID, uriConfig.KeyID) == 0 &&
   203  				bytes.Compare(foundUriConfig.KeyLabel, uriConfig.KeyLabel) == 0 &&
   204  				foundUriConfig.ModulePath == uriConfig.ModulePath &&
   205  				foundUriConfig.Pin == uriConfig.Pin {
   206  				bKeyFound = true
   207  			}
   208  
   209  			break
   210  		}
   211  	}
   212  
   213  	if !bKeyFound {
   214  		t.Fatalf("key not found")
   215  	}
   216  }
   217  
   218  func TestCertificateIgnored(t *testing.T) {
   219  	ctx := context.Background()
   220  
   221  	tokens, err := GetTokens(ctx, modulePath)
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	bTokenFound := false
   227  	var slotID uint
   228  	for _, token := range tokens {
   229  		if token.TokenInfo.Label == tokenLabel {
   230  			bTokenFound = true
   231  			slotID = token.Slot
   232  			break
   233  		}
   234  	}
   235  	if !bTokenFound {
   236  		t.Fatalf("token with label '%s' not found", tokenLabel)
   237  	}
   238  
   239  	err = importKey(slotID)
   240  	if err != nil {
   241  		t.Fatal(err)
   242  	}
   243  	defer deleteKey(slotID)
   244  
   245  	pkcs11UriConfig := pkcs11key.NewPkcs11UriConfig()
   246  	err = pkcs11UriConfig.Parse(uri)
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	const envvar = "COSIGN_PKCS11_IGNORE_CERTIFICATE"
   252  
   253  	if err := os.Setenv(envvar, "1"); err != nil {
   254  		t.Fatal(err)
   255  	}
   256  
   257  	defer os.Setenv(envvar, "")
   258  
   259  	sk, err := pkcs11key.GetKeyWithURIConfig(pkcs11UriConfig, true)
   260  	if err != nil {
   261  		t.Fatal(err)
   262  	}
   263  
   264  	defer sk.Close()
   265  
   266  	cert, err := sk.Certificate()
   267  	if err != nil {
   268  		t.Fatal(err)
   269  	}
   270  
   271  	if cert != nil {
   272  		t.Fatalf("expected certificate to be ignored while loading")
   273  	}
   274  }
   275  
   276  func TestSignAndVerify(t *testing.T) {
   277  	ctx := context.Background()
   278  
   279  	tokens, err := GetTokens(ctx, modulePath)
   280  	if err != nil {
   281  		t.Fatal(err)
   282  	}
   283  
   284  	bTokenFound := false
   285  	var slotID uint
   286  	for _, token := range tokens {
   287  		if token.TokenInfo.Label == tokenLabel {
   288  			bTokenFound = true
   289  			slotID = token.Slot
   290  			break
   291  		}
   292  	}
   293  	if !bTokenFound {
   294  		t.Fatalf("token with label '%s' not found", tokenLabel)
   295  	}
   296  
   297  	err = importKey(slotID)
   298  	if err != nil {
   299  		t.Fatal(err)
   300  	}
   301  	defer deleteKey(slotID)
   302  
   303  	pkcs11UriConfig := pkcs11key.NewPkcs11UriConfig()
   304  	err = pkcs11UriConfig.Parse(uri)
   305  	if err != nil {
   306  		t.Fatal(err)
   307  	}
   308  
   309  	sk, err := pkcs11key.GetKeyWithURIConfig(pkcs11UriConfig, true)
   310  	if err != nil {
   311  		t.Fatal(err)
   312  	}
   313  	defer sk.Close()
   314  
   315  	sv, err := sk.SignerVerifier()
   316  	if err != nil {
   317  		t.Fatal(err)
   318  	}
   319  
   320  	v, err := sk.Verifier()
   321  	if err != nil {
   322  		t.Fatal(err)
   323  	}
   324  
   325  	sig, err := sv.SignMessage(bytes.NewReader([]byte("hello, world!")))
   326  	if err != nil {
   327  		t.Fatal(err)
   328  	}
   329  
   330  	err = v.VerifySignature(bytes.NewReader(sig), bytes.NewReader([]byte("hello, world!")))
   331  	if err != nil {
   332  		t.Fatal(err)
   333  	}
   334  }
   335  
   336  var newPublicKeyAttrs = []*pkcs11.Attribute{
   337  	pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
   338  	pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
   339  	pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
   340  	pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
   341  }
   342  
   343  var newPrivateKeyAttrs = []*pkcs11.Attribute{
   344  	pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
   345  	pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
   346  	pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
   347  	pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
   348  	pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
   349  	pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
   350  }
   351  
   352  func rsaImportAttrs(priv *rsa.PrivateKey) (pubAttrs, privAttrs []*pkcs11.Attribute) {
   353  	pubAttrs = []*pkcs11.Attribute{
   354  		pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(priv.E)).Bytes()),
   355  		pkcs11.NewAttribute(pkcs11.CKA_MODULUS, priv.N.Bytes()),
   356  	}
   357  	privAttrs = []*pkcs11.Attribute{
   358  		pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(priv.E)).Bytes()),
   359  		pkcs11.NewAttribute(pkcs11.CKA_MODULUS, priv.N.Bytes()),
   360  		pkcs11.NewAttribute(pkcs11.CKA_PRIVATE_EXPONENT, priv.D.Bytes()),
   361  		pkcs11.NewAttribute(pkcs11.CKA_PRIME_1, priv.Primes[0].Bytes()),
   362  		pkcs11.NewAttribute(pkcs11.CKA_PRIME_2, priv.Primes[1].Bytes()),
   363  		pkcs11.NewAttribute(pkcs11.CKA_EXPONENT_1, priv.Precomputed.Dp.Bytes()),
   364  		pkcs11.NewAttribute(pkcs11.CKA_EXPONENT_2, priv.Precomputed.Dq.Bytes()),
   365  		pkcs11.NewAttribute(pkcs11.CKA_COEFFICIENT, priv.Precomputed.Qinv.Bytes()),
   366  	}
   367  	return
   368  }
   369  
   370  func attrConcat(attrSets ...[]*pkcs11.Attribute) []*pkcs11.Attribute {
   371  	ret := make([]*pkcs11.Attribute, 0)
   372  	for _, attrs := range attrSets {
   373  		ret = append(ret, attrs...)
   374  	}
   375  	return ret
   376  }
   377  
   378  func initPKCS11(modulePath string) (*pkcs11.Ctx, error) {
   379  	ctx := pkcs11.New(modulePath)
   380  	if ctx == nil {
   381  		return nil, fmt.Errorf("unable to load PKCS#11 module")
   382  	}
   383  
   384  	err := ctx.Initialize()
   385  	if err != nil {
   386  		return nil, fmt.Errorf("unable to initialize PKCS#11 module")
   387  	}
   388  
   389  	return ctx, nil
   390  }
   391  
   392  func importKey(slotID uint) error {
   393  	var pemBytes []byte
   394  	var priv interface{}
   395  
   396  	ctx, err := initPKCS11(modulePath)
   397  	if err != nil {
   398  		return err
   399  	}
   400  	defer func() {
   401  		ctx.Finalize()
   402  		ctx.Destroy()
   403  	}()
   404  
   405  	keyIDBytes, err := hex.DecodeString(keyID)
   406  	if err != nil {
   407  		return err
   408  	}
   409  	keyLabelBytes := []byte(keyLabel)
   410  
   411  	r := strings.NewReader(rsaPrivKey)
   412  	pemBytes, err = io.ReadAll(r)
   413  	if err != nil {
   414  		return fmt.Errorf("unable to read pem")
   415  	}
   416  	block, _ := pem.Decode(pemBytes)
   417  	if block == nil {
   418  		return fmt.Errorf("unable to decode pem")
   419  	}
   420  	priv, err = x509.ParsePKCS8PrivateKey(block.Bytes)
   421  	if err != nil {
   422  		return fmt.Errorf("unable to parse pem")
   423  	}
   424  	privKey, ok := priv.(*rsa.PrivateKey)
   425  	if !ok {
   426  		return fmt.Errorf("unable to load key")
   427  	}
   428  
   429  	session, err := ctx.OpenSession(slotID, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
   430  	if err != nil {
   431  		return fmt.Errorf("unable to open session")
   432  	}
   433  	defer ctx.CloseSession(session)
   434  	err = ctx.Login(session, pkcs11.CKU_USER, pin)
   435  	if err != nil {
   436  		return fmt.Errorf("unable to login")
   437  	}
   438  	defer ctx.Logout(session)
   439  
   440  	keyType := pkcs11.CKK_RSA
   441  	pubTypeAttrs, privTypeAttrs := rsaImportAttrs(privKey)
   442  	commonAttrs := []*pkcs11.Attribute{
   443  		pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, keyType),
   444  		pkcs11.NewAttribute(pkcs11.CKA_ID, keyIDBytes),
   445  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, keyLabelBytes),
   446  	}
   447  	pubAttrs := attrConcat(commonAttrs, newPublicKeyAttrs, pubTypeAttrs)
   448  	privAttrs := attrConcat(commonAttrs, newPrivateKeyAttrs, privTypeAttrs)
   449  	pubHandle, err := ctx.CreateObject(session, pubAttrs)
   450  	if err != nil {
   451  		return fmt.Errorf("unable to create public key")
   452  	}
   453  	_, err = ctx.CreateObject(session, privAttrs)
   454  	if err != nil {
   455  		ctx.DestroyObject(session, pubHandle)
   456  		return fmt.Errorf("unable to create private key")
   457  	}
   458  
   459  	return nil
   460  }
   461  
   462  func deleteKey(slotID uint) error {
   463  	var handles []pkcs11.ObjectHandle
   464  
   465  	ctx, err := initPKCS11(modulePath)
   466  	if err != nil {
   467  		return err
   468  	}
   469  	defer func() {
   470  		ctx.Finalize()
   471  		ctx.Destroy()
   472  	}()
   473  
   474  	keyIDBytes, err := hex.DecodeString(keyID)
   475  	if err != nil {
   476  		return err
   477  	}
   478  	keyLabelBytes := []byte(keyLabel)
   479  
   480  	session, err := ctx.OpenSession(slotID, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
   481  	if err != nil {
   482  		return fmt.Errorf("unable to open session")
   483  	}
   484  	defer ctx.CloseSession(session)
   485  	err = ctx.Login(session, pkcs11.CKU_USER, pin)
   486  	if err != nil {
   487  		return fmt.Errorf("unable to login")
   488  	}
   489  	defer ctx.Logout(session)
   490  
   491  	maxHandlePerFind := 20
   492  	publicAttrs := []*pkcs11.Attribute{
   493  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
   494  		pkcs11.NewAttribute(pkcs11.CKA_ID, keyIDBytes),
   495  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, keyLabelBytes),
   496  	}
   497  	if err = ctx.FindObjectsInit(session, publicAttrs); err != nil {
   498  		return fmt.Errorf("unable to initialize find objects")
   499  	}
   500  	handles, _, err = ctx.FindObjects(session, maxHandlePerFind)
   501  	if err != nil {
   502  		return fmt.Errorf("unable to find objects")
   503  	}
   504  	err = ctx.FindObjectsFinal(session)
   505  	if err != nil {
   506  		return fmt.Errorf("unable to finalize find objects")
   507  	}
   508  	if len(handles) == 1 {
   509  		ctx.DestroyObject(session, handles[0])
   510  		if err != nil {
   511  			return fmt.Errorf("unable to destroy public key")
   512  		}
   513  	}
   514  
   515  	privAttrs := []*pkcs11.Attribute{
   516  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
   517  		pkcs11.NewAttribute(pkcs11.CKA_ID, keyIDBytes),
   518  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, keyLabelBytes),
   519  	}
   520  	if err = ctx.FindObjectsInit(session, privAttrs); err != nil {
   521  		return fmt.Errorf("unable to initialize find objects")
   522  	}
   523  	handles, _, err = ctx.FindObjects(session, maxHandlePerFind)
   524  	if err != nil {
   525  		return fmt.Errorf("unable to find objects")
   526  	}
   527  	err = ctx.FindObjectsFinal(session)
   528  	if err != nil {
   529  		return fmt.Errorf("unable to finalize find objects")
   530  	}
   531  	if len(handles) == 1 {
   532  		ctx.DestroyObject(session, handles[0])
   533  		if err != nil {
   534  			return fmt.Errorf("unable to destroy private key")
   535  		}
   536  	}
   537  
   538  	return nil
   539  }
   540  
   541  func must(err error, t *testing.T) {
   542  	t.Helper()
   543  	if err != nil {
   544  		t.Fatal(err)
   545  	}
   546  }
   547  
   548  func mustErr(err error, t *testing.T) {
   549  	t.Helper()
   550  	if err == nil {
   551  		t.Fatal("expected error")
   552  	}
   553  }
   554  
   555  const rsaPrivKey = `-----BEGIN PRIVATE KEY-----
   556  MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDZJZ44vB04D2wm
   557  xz+3upmuWelrTWcceVC2v6fkBo9dIR9IejolFY+CsMF1Rc5LGXG3XStQHRrbmq1w
   558  UxC8jsIOK7gI2xI9IOwCgyaQun3J+1VQc6eZxHLGQfTTNq7Vx67VOG8V8d3RhN7L
   559  BvAMT5U55254bUgH0KVx5C1ybLcX6BdGaABCunh7tV+thgwEZSbr2/t0Tf8QneMr
   560  eHojTKZp7/d90TH8KF+/FiPWJWWv5OVhjpZPwTWqUgL+6pgrMKUSWD/92JSDIZe6
   561  UjxASE4JgnJWMQUhkerJ7j5P16gjdAwJAAt5m3L6wdfVQG2aZ9CJzUowk12ly4Dc
   562  Dx73/UufAgMBAAECggEAF8iA/eHMqXk29UBZgDwV3PzIDhKaOoonBv0S3GzDgwW/
   563  sWaBu9ISt9O4PKn6oEsXI2g2+D1X1bmpSWYvrRdNtdOgAohMBRn3/4Zx0OQ8JsU6
   564  YOdp8fOMRp6uu/t/RrbqNTxLHnIxQ2N0K3SFEjQdOgxZEyOVAhYeKM0/FQtHOnzj
   565  WoyZHT8pV3mr6WnxBw/4u/1Ahfau7fs6aVJLECc9jGF/6e7aQeb+yEeLrHayml8e
   566  sbBx4l/1LqU/2S7SQrWtQ+fi+/MlgxvLh0XC7tTPP6I3cTetyMZime9EwwDiPebX
   567  PLUgo8Kf/sHzd/25G9M3Yz+UCLemcPSMUjBUQTPtYQKBgQD8lnpjekyeOjNCdRVP
   568  5w6h1wGN4aC4bCksZ89HKpHc44+3AjDT/aVviory+CyOj05qbXDdpNnNh+jl5llM
   569  yDw15WIvSsXFx3UQ467VVrBKm7vr+k1LGgLJ2fSFbZUTyLvwW4NpP26KDW6SitZ8
   570  B9lkepTZ0G4Eao51VgidHsulKQKBgQDcFJNAIctqUWDli4tA5L0G5tiypcAA7iIZ
   571  0h2YK+7eOU2f3r8aaywbPhcRn+cKlrf3iV4BCZAv59WEJqq1HOlzU92jkmZspYPq
   572  8kSZLaaiDIBw+vwV4prHDSdZFEY+hHq5eULPIgVm/M474JcghetkVt8pG3ee+Dml
   573  o6zUrZr7hwKBgQDCiXbrpObbuoF+PsTSTGfFl923k74ALDWt4KoQ6qV61bz7O3G1
   574  5BYFiVOo/CD9Dzxa1b1mx6+ED5f9cOL4MwPEks2DFPircgoknucpomGWpMkgXyAm
   575  pnrdUcN0/Egj+6db4G+eoN8W7m9p6Ap3bmgtbge0lkYVmqfrkP6DXJOFuQKBgHA/
   576  hkMFeYyGaRdqruGwSMEGaKvlYiKXUok8459DeReavn61y16cHujeKEHy/pImATqd
   577  s3Zv/DyS0BIQ7qxlTKRnt/m/p8HuQXRJkLdX009/dNsrB/vZkfvIN7N1ZcZpJ3cF
   578  5A9lWMAIXN+pUythYofQzw1WVxKbpDtZWcM3sH5tAoGBAMHgZdtmIyllx/1BbYSg
   579  Emxj3LekvZL0e7afeod9f977ZETt/imaejnJNnGOPeSbtLSPfhwonLEp+5XmICzt
   580  lJZAF8iP2m1n9h8sZga5rZQ0JgiwVNFNwde4sp1pD5UcFrYepHRxKPo50eJi3rhR
   581  SwNAKWa96qm5o8BaQu/aRMRu
   582  -----END PRIVATE KEY-----`
   583  
   584  const rsaCert = `-----BEGIN CERTIFICATE-----
   585  MIIDazCCAlOgAwIBAgIUL7BdF7HSUwEAdqElJjVLQYd2OekwDQYJKoZIhvcNAQEL
   586  BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
   587  GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMDIxNzM3MzJaFw0zMTEw
   588  MzExNzM3MzJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
   589  HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
   590  AQUAA4IBDwAwggEKAoIBAQDZJZ44vB04D2wmxz+3upmuWelrTWcceVC2v6fkBo9d
   591  IR9IejolFY+CsMF1Rc5LGXG3XStQHRrbmq1wUxC8jsIOK7gI2xI9IOwCgyaQun3J
   592  +1VQc6eZxHLGQfTTNq7Vx67VOG8V8d3RhN7LBvAMT5U55254bUgH0KVx5C1ybLcX
   593  6BdGaABCunh7tV+thgwEZSbr2/t0Tf8QneMreHojTKZp7/d90TH8KF+/FiPWJWWv
   594  5OVhjpZPwTWqUgL+6pgrMKUSWD/92JSDIZe6UjxASE4JgnJWMQUhkerJ7j5P16gj
   595  dAwJAAt5m3L6wdfVQG2aZ9CJzUowk12ly4DcDx73/UufAgMBAAGjUzBRMB0GA1Ud
   596  DgQWBBRokgD44sdsSGQEQcbJ3vrCrXTIcTAfBgNVHSMEGDAWgBRokgD44sdsSGQE
   597  QcbJ3vrCrXTIcTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA8
   598  +CpbIGi4ycCcSeomBzGVXsTFgFutqqvh3BFQ1u6bPlV7hIlFd11zzgWBeKKxREJn
   599  z3SipT1qGX+uP4iVhUux94f2rQCV25mJNRKft2phAUylMr+laiO7IkHFB1zzJTfz
   600  Bi9gm55HGvGCIdSWFkLZ/MUNCMj3WtPrUYl5jqFgDDmCpLctmPoN4vxSa0of3apv
   601  ILH8jSsN5XbL8G1hsT/IGlRRbzoiLCKgCp6e6TjZSq/Y+JWGyw/+sZJMI8Mg4Mje
   602  054uJhD29xmbfxdYxrMWLAFb6yoWVbDJPdECFf9uwOXyDZ8bGd48frTdUU3Rb+m3
   603  5Hue2g5US98p2jnJiv75
   604  -----END CERTIFICATE-----`
   605  

View as plain text