From 4c4e04b6b1f37d9b7a1e50b178c457d214c78337 Mon Sep 17 00:00:00 2001 From: umbynos Date: Thu, 3 Jun 2021 15:34:17 +0200 Subject: [PATCH] make `verifySignature` public, enhanced tests, remove `board` word --- arduino/security/signature_test.go | 38 +++++++++++++++++++++++------- arduino/security/signatures.go | 14 ++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/arduino/security/signature_test.go b/arduino/security/signature_test.go index 82d5572f219..edf32289e64 100644 --- a/arduino/security/signature_test.go +++ b/arduino/security/signature_test.go @@ -19,16 +19,17 @@ import ( "testing" "github.com/arduino/go-paths-helper" + rice "github.com/cmaglie/go.rice" "github.com/stretchr/testify/require" ) var ( - PackageIndexPath = paths.New("testdata/package_index.json") - PackageSignaturePath = paths.New("testdata/package_index.json.sig") - BoardIndexPath = paths.New("testdata/module_firmware_index.json") - BoardSignaturePath = paths.New("testdata/module_firmware_index.json.sig") - BoardKey = paths.New("testdata/module_firmware_index_public.gpg.key") - InvalidIndexPath = paths.New("testdata/invalid_file.json") + PackageIndexPath = paths.New("testdata/package_index.json") + PackageSignaturePath = paths.New("testdata/package_index.json.sig") + ModuleFWIndexPath = paths.New("testdata/module_firmware_index.json") + ModuleFWSignaturePath = paths.New("testdata/module_firmware_index.json.sig") + ModuleFWIndexKey = paths.New("testdata/module_firmware_index_public.gpg.key") + InvalidIndexPath = paths.New("testdata/invalid_file.json") ) func TestVerifyArduinoDetachedSignature(t *testing.T) { @@ -45,13 +46,34 @@ func TestVerifyArduinoDetachedSignature(t *testing.T) { } func TestVerifyDetachedSignature(t *testing.T) { - res, signer, err := VerifyDetachedSignature(BoardIndexPath, BoardSignaturePath, BoardKey) + res, signer, err := VerifyDetachedSignature(ModuleFWIndexPath, ModuleFWSignaturePath, ModuleFWIndexKey) require.NoError(t, err) require.NotNil(t, signer) require.True(t, res) require.Equal(t, uint64(0x82f2d7c7c5a22a73), signer.PrimaryKey.KeyId) - res, signer, err = VerifyDetachedSignature(InvalidIndexPath, PackageSignaturePath, BoardKey) + res, signer, err = VerifyDetachedSignature(InvalidIndexPath, PackageSignaturePath, ModuleFWIndexKey) + require.False(t, res) + require.Nil(t, signer) + require.Error(t, err) +} + +func TestVerifySignature(t *testing.T) { + keysBox, err := rice.FindBox("keys") + if err != nil { + panic("could not find bundled signature keys") + } + arduinoKeyringFile, err := keysBox.Open("arduino_public.gpg.key") + if err != nil { + panic("could not find bundled signature keys") + } + res, signer, err := VerifySignature(PackageIndexPath, PackageSignaturePath, arduinoKeyringFile) + require.NoError(t, err) + require.NotNil(t, signer) + require.True(t, res) + require.Equal(t, uint64(0x7baf404c2dfab4ae), signer.PrimaryKey.KeyId) + + res, signer, err = VerifySignature(InvalidIndexPath, PackageSignaturePath, arduinoKeyringFile) require.False(t, res) require.Nil(t, signer) require.Error(t, err) diff --git a/arduino/security/signatures.go b/arduino/security/signatures.go index 2bc7a9fec88..21f32fbd5f8 100644 --- a/arduino/security/signatures.go +++ b/arduino/security/signatures.go @@ -29,7 +29,8 @@ import ( // signaturePath file) matches the given targetPath file and is an authentic // signature from the bundled trusted keychain. If any of the above conditions // fails this function returns false. The PGP entity in the trusted keychain that -// produced the signature is returned too. +// produced the signature is returned too. This function use the default and bundled +// arduino_public.gpg.key func VerifyArduinoDetachedSignature(targetPath *paths.Path, signaturePath *paths.Path) (bool, *openpgp.Entity, error) { keysBox, err := rice.FindBox("keys") if err != nil { @@ -39,7 +40,7 @@ func VerifyArduinoDetachedSignature(targetPath *paths.Path, signaturePath *paths if err != nil { panic("could not find bundled signature keys") } - return verifySignature(targetPath, signaturePath, arduinoKeyringFile) + return VerifySignature(targetPath, signaturePath, arduinoKeyringFile) } // VerifyDetachedSignature checks that the detached GPG signature (in the @@ -54,14 +55,15 @@ func VerifyDetachedSignature(targetPath *paths.Path, signaturePath *paths.Path, panic("could not open signature keys") } defer arduinoKeyringFile.Close() - return verifySignature(targetPath, signaturePath, arduinoKeyringFile) + return VerifySignature(targetPath, signaturePath, arduinoKeyringFile) } -//verifySignature is an helper function that checks that the detached GPG signature (in the +// VerifySignature checks that the detached GPG signature (in the // signaturePath file) matches the given targetPath file and is an authentic -// signature. If any of the above conditions fails this function returns false. +// signature. This function allows to pass an io.Reader to read the custom key. +// If any of the above conditions fails this function returns false. // The PGP entity in the trusted keychain that produced the signature is returned too. -func verifySignature(targetPath *paths.Path, signaturePath *paths.Path, arduinoKeyringFile io.Reader) (bool, *openpgp.Entity, error) { +func VerifySignature(targetPath *paths.Path, signaturePath *paths.Path, arduinoKeyringFile io.Reader) (bool, *openpgp.Entity, error) { keyRing, err := openpgp.ReadKeyRing(arduinoKeyringFile) if err != nil { return false, nil, fmt.Errorf("retrieving Arduino public keys: %s", err)