...

Source file src/github.com/secure-systems-lab/go-securesystemslib/signerverifier/rsa_test.go

Documentation: github.com/secure-systems-lab/go-securesystemslib/signerverifier

     1  package signerverifier
     2  
     3  import (
     4  	"context"
     5  	"crypto/rsa"
     6  	"encoding/json"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/secure-systems-lab/go-securesystemslib/cjson"
    12  	"github.com/secure-systems-lab/go-securesystemslib/dsse"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestNewRSAPSSSignerVerifierFromSSLibKey(t *testing.T) {
    17  	key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
    18  	if err != nil {
    19  		t.Error(err)
    20  	}
    21  
    22  	sv, err := NewRSAPSSSignerVerifierFromSSLibKey(key)
    23  	if err != nil {
    24  		t.Error(err)
    25  	}
    26  
    27  	expectedPublicString := "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA04egZRic+dZMVtiQc56D\nejU4FF1q3aOkUKnD+Q4lTbj1zp6ODKJTcktupmrad68jqtMiSGG8he6ELFs377q8\nbbgEUMWgAf+06Q8oFvUSfOXzZNFI7H5SMPOJY5aDWIMIEZ8DlcO7TfkA7D3iAEJX\nxxTOVS3UAIk5umO7Y7t7yXr8O/C4u78krGazCnoblcekMLJZV4O/5BloWNAe/B1c\nvZdaZUf3brD4ZZrxEtXw/tefhn1aHsSUajVW2wwjSpKhqj7Z0XS3bDS3T95/3xsN\n6+hlS6A7rJfiWpKIRHj0vh2SXLDmmhQl1In8TD/aiycTUyWcBRHVPlYFgYPt6SaT\nVQSgMzSxC43/2fINb2fyt8SbUHJ3Ct+mzRzd/1AQikWhBdstJLxInewzjYE/sb+c\n2CmCxMPQG2BwmAWXaaumeJcXVPBlMgAcjMatM8bPByTbXpKDnQslOE7g/gswDIwn\nEm53T13mZzYUvbLJ0q3aljZVLIC3IZn3ZwA2yCWchBkVAgMBAAE=\n-----END PUBLIC KEY-----"
    28  	_, expectedPublicKey, err := decodeAndParsePEM([]byte(expectedPublicString))
    29  	assert.Nil(t, err)
    30  
    31  	assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", sv.keyID)
    32  	assert.Equal(t, expectedPublicKey.(*rsa.PublicKey), sv.public)
    33  	assert.Nil(t, sv.private)
    34  }
    35  
    36  func TestLoadRSAPSSKeyFromFile(t *testing.T) {
    37  	t.Run("RSA public key", func(t *testing.T) {
    38  		key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
    39  		assert.Nil(t, err)
    40  
    41  		assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", key.KeyID)
    42  		assert.Equal(t, "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA04egZRic+dZMVtiQc56D\nejU4FF1q3aOkUKnD+Q4lTbj1zp6ODKJTcktupmrad68jqtMiSGG8he6ELFs377q8\nbbgEUMWgAf+06Q8oFvUSfOXzZNFI7H5SMPOJY5aDWIMIEZ8DlcO7TfkA7D3iAEJX\nxxTOVS3UAIk5umO7Y7t7yXr8O/C4u78krGazCnoblcekMLJZV4O/5BloWNAe/B1c\nvZdaZUf3brD4ZZrxEtXw/tefhn1aHsSUajVW2wwjSpKhqj7Z0XS3bDS3T95/3xsN\n6+hlS6A7rJfiWpKIRHj0vh2SXLDmmhQl1In8TD/aiycTUyWcBRHVPlYFgYPt6SaT\nVQSgMzSxC43/2fINb2fyt8SbUHJ3Ct+mzRzd/1AQikWhBdstJLxInewzjYE/sb+c\n2CmCxMPQG2BwmAWXaaumeJcXVPBlMgAcjMatM8bPByTbXpKDnQslOE7g/gswDIwn\nEm53T13mZzYUvbLJ0q3aljZVLIC3IZn3ZwA2yCWchBkVAgMBAAE=\n-----END PUBLIC KEY-----", key.KeyVal.Public)
    43  		assert.Equal(t, RSAKeyScheme, key.Scheme)
    44  		assert.Equal(t, RSAKeyType, key.KeyType)
    45  	})
    46  
    47  	t.Run("RSA private key", func(t *testing.T) {
    48  		key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key"))
    49  		assert.Nil(t, err)
    50  
    51  		assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", key.KeyID)
    52  		assert.Equal(t, "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA04egZRic+dZMVtiQc56D\nejU4FF1q3aOkUKnD+Q4lTbj1zp6ODKJTcktupmrad68jqtMiSGG8he6ELFs377q8\nbbgEUMWgAf+06Q8oFvUSfOXzZNFI7H5SMPOJY5aDWIMIEZ8DlcO7TfkA7D3iAEJX\nxxTOVS3UAIk5umO7Y7t7yXr8O/C4u78krGazCnoblcekMLJZV4O/5BloWNAe/B1c\nvZdaZUf3brD4ZZrxEtXw/tefhn1aHsSUajVW2wwjSpKhqj7Z0XS3bDS3T95/3xsN\n6+hlS6A7rJfiWpKIRHj0vh2SXLDmmhQl1In8TD/aiycTUyWcBRHVPlYFgYPt6SaT\nVQSgMzSxC43/2fINb2fyt8SbUHJ3Ct+mzRzd/1AQikWhBdstJLxInewzjYE/sb+c\n2CmCxMPQG2BwmAWXaaumeJcXVPBlMgAcjMatM8bPByTbXpKDnQslOE7g/gswDIwn\nEm53T13mZzYUvbLJ0q3aljZVLIC3IZn3ZwA2yCWchBkVAgMBAAE=\n-----END PUBLIC KEY-----", key.KeyVal.Public)
    53  		expectedPrivateKey := "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----"
    54  		assert.Equal(t, expectedPrivateKey, key.KeyVal.Private)
    55  		assert.Equal(t, RSAKeyScheme, key.Scheme)
    56  		assert.Equal(t, RSAKeyType, key.KeyType)
    57  	})
    58  
    59  	t.Run("invalid path", func(t *testing.T) {
    60  		_, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "invalid"))
    61  		assert.ErrorContains(t, err, "unable to load RSA key from file")
    62  	})
    63  }
    64  
    65  func TestRSAPSSSignerVerifierSignAndVerify(t *testing.T) {
    66  	t.Run("using valid key", func(t *testing.T) {
    67  		key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key"))
    68  		if err != nil {
    69  			t.Error(err)
    70  		}
    71  
    72  		sv, err := NewRSAPSSSignerVerifierFromSSLibKey(key)
    73  		if err != nil {
    74  			t.Error(err)
    75  		}
    76  
    77  		message := []byte("test message")
    78  
    79  		signature, err := sv.Sign(context.Background(), message)
    80  		assert.Nil(t, err)
    81  
    82  		err = sv.Verify(context.Background(), message, signature)
    83  		assert.Nil(t, err)
    84  	})
    85  
    86  	t.Run("using invalid key", func(t *testing.T) {
    87  		key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
    88  		if err != nil {
    89  			t.Error(err)
    90  		}
    91  
    92  		sv, err := NewRSAPSSSignerVerifierFromSSLibKey(key)
    93  		if err != nil {
    94  			t.Error(err)
    95  		}
    96  
    97  		message := []byte("test message")
    98  
    99  		_, err = sv.Sign(context.Background(), message)
   100  		assert.ErrorIs(t, err, ErrNotPrivateKey)
   101  	})
   102  }
   103  
   104  func TestRSAPSSSignerVerifierWithDSSEEnvelope(t *testing.T) {
   105  	key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key"))
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  
   110  	sv, err := NewRSAPSSSignerVerifierFromSSLibKey(key)
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  
   115  	payloadType := "application/vnd.dsse+json"
   116  	payload := []byte("test message")
   117  
   118  	es, err := dsse.NewEnvelopeSigner(sv)
   119  	if err != nil {
   120  		t.Error(err)
   121  	}
   122  
   123  	env, err := es.SignPayload(context.Background(), payloadType, payload)
   124  	if err != nil {
   125  		t.Error(err)
   126  	}
   127  
   128  	assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", env.Signatures[0].KeyID)
   129  	envPayload, err := env.DecodeB64Payload()
   130  	assert.Equal(t, payload, envPayload)
   131  	assert.Nil(t, err)
   132  
   133  	key, err = LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  
   138  	sv, err = NewRSAPSSSignerVerifierFromSSLibKey(key)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  
   143  	ev, err := dsse.NewEnvelopeVerifier(sv)
   144  	if err != nil {
   145  		t.Error(err)
   146  	}
   147  
   148  	acceptedKeys, err := ev.Verify(context.Background(), env)
   149  	assert.Nil(t, err)
   150  	assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", acceptedKeys[0].KeyID)
   151  }
   152  
   153  func TestRSAPSSSignerVerifierWithMetablockFile(t *testing.T) {
   154  	key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
   155  	if err != nil {
   156  		t.Fatal(err)
   157  	}
   158  
   159  	sv, err := NewRSAPSSSignerVerifierFromSSLibKey(key)
   160  	if err != nil {
   161  		t.Fatal(err)
   162  	}
   163  
   164  	metadataBytes, err := os.ReadFile(filepath.Join("test-data", "test-rsa.4e8d20af.link"))
   165  	if err != nil {
   166  		t.Fatal(err)
   167  	}
   168  
   169  	mb := struct {
   170  		Signatures []struct {
   171  			KeyID string `json:"keyid"`
   172  			Sig   string `json:"sig"`
   173  		} `json:"signatures"`
   174  		Signed any `json:"signed"`
   175  	}{}
   176  
   177  	if err := json.Unmarshal(metadataBytes, &mb); err != nil {
   178  		t.Fatal(err)
   179  	}
   180  
   181  	assert.Equal(t, "8958e5be66ee4352880a531bd097d1727adcc78e66b4faeb4a2cd6ad073dcb84f9a34e8156af39a7144cb5cd925325a18ccd4f0b2f981d6ff82655a7d63210d36655c50a0bf24e4839c10430a040dd6189d04fabec90eae4314c75ae2d585da17a56aaf6755e613a3a6a471ad2eddbb24504848e34f9ac163660f8ab80d7701bfa1189578a59597b3809ee62a70a7cc9545cfa65e23018fa442a45279b9fcf9d80bc92df711bfcfe16e3eae1bcf61b3286c1f0bdda17bc28bfab5b736bdcac4a38e31db1d0e0f56a2853b1b451650305f040a3425c3be47125700e92ef82c5a91a040b5e70ab7f6ebbe037ae1a6835044b5699748037e2e39a55a420c41cd9fa6e16868776367e3620e7d28eb9d8a3d710bdc98d488df1a9947d2ec8400f3c6209e8ca587cbffa30ceb3be98105e03182aab1bbb3c4e2560d99f0b09c012df2271f273ac70a6abb185abe11d559b118dca616417fa9205e74ab58e89ffd8b965da304ae9dc9cf6ffac4838b7c5375d6c2057a61cb286f06ad3b02a49c3af6178", mb.Signatures[0].Sig)
   182  	assert.Equal(t, sv.keyID, mb.Signatures[0].KeyID)
   183  
   184  	encodedBytes, err := cjson.EncodeCanonical(mb.Signed)
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	decodedSig := hexDecode(t, mb.Signatures[0].Sig)
   190  
   191  	err = sv.Verify(context.Background(), encodedBytes, decodedSig)
   192  	assert.Nil(t, err)
   193  }
   194  

View as plain text