Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7eb9c57

Browse files
authored
Implement function to verify index signature with custom key (#1304)
* add gpg public key to verify board_index.json * add new function to allow the usage of another gpg key * add new test and enhance existing ones * apply suggestions by @cmaglie * move `module_firmware_index.gpg.key` under `testdata/`
1 parent cdbebe9 commit 7eb9c57

File tree

5 files changed

+505
-4
lines changed

5 files changed

+505
-4
lines changed

‎arduino/security/signature_test.go‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,36 @@ import (
2222
"github.com/stretchr/testify/require"
2323
)
2424

25-
func TestSignatureVerification(t *testing.T) {
26-
res, signer, err := VerifyArduinoDetachedSignature(paths.New("testdata/package_index.json"), paths.New("testdata/package_index.json.sig"))
25+
var (
26+
PackageIndexPath = paths.New("testdata/package_index.json")
27+
PackageSignaturePath = paths.New("testdata/package_index.json.sig")
28+
BoardIndexPath = paths.New("testdata/module_firmware_index.json")
29+
BoardSignaturePath = paths.New("testdata/module_firmware_index.json.sig")
30+
BoardKey = paths.New("testdata/module_firmware_index_public.gpg.key")
31+
InvalidIndexPath = paths.New("testdata/invalid_file.json")
32+
)
33+
34+
func TestVerifyArduinoDetachedSignature(t *testing.T) {
35+
res, signer, err := VerifyArduinoDetachedSignature(PackageIndexPath, PackageSignaturePath)
2736
require.NoError(t, err)
2837
require.NotNil(t, signer)
2938
require.True(t, res)
3039
require.Equal(t, uint64(0x7baf404c2dfab4ae), signer.PrimaryKey.KeyId)
3140

32-
res, signer, err = VerifyArduinoDetachedSignature(paths.New("testdata/invalid_file.json"), paths.New("testdata/package_index.json.sig"))
41+
res, signer, err = VerifyArduinoDetachedSignature(InvalidIndexPath, PackageSignaturePath)
42+
require.False(t, res)
43+
require.Nil(t, signer)
44+
require.Error(t, err)
45+
}
46+
47+
func TestVerifyDetachedSignature(t *testing.T) {
48+
res, signer, err := VerifyDetachedSignature(BoardIndexPath, BoardSignaturePath, BoardKey)
49+
require.NoError(t, err)
50+
require.NotNil(t, signer)
51+
require.True(t, res)
52+
require.Equal(t, uint64(0x82f2d7c7c5a22a73), signer.PrimaryKey.KeyId)
53+
54+
res, signer, err = VerifyDetachedSignature(InvalidIndexPath, PackageSignaturePath, BoardKey)
3355
require.False(t, res)
3456
require.Nil(t, signer)
3557
require.Error(t, err)

‎arduino/security/signatures.go‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ package security
1717

1818
import (
1919
"fmt"
20+
"io"
21+
"os"
2022

2123
"github.com/arduino/go-paths-helper"
2224
rice "github.com/cmaglie/go.rice"
@@ -37,11 +39,33 @@ func VerifyArduinoDetachedSignature(targetPath *paths.Path, signaturePath *paths
3739
if err != nil {
3840
panic("could not find bundled signature keys")
3941
}
42+
return verifySignature(targetPath, signaturePath, arduinoKeyringFile)
43+
}
44+
45+
// VerifyDetachedSignature checks that the detached GPG signature (in the
46+
// signaturePath file) matches the given targetPath file and is an authentic
47+
// signature from the bundled trusted keychain. The keyPath is the path of the public key used.
48+
// This function allows to specify the path of the key to use.
49+
// If any of the above conditions fails this function returns false.
50+
// The PGP entity in the trusted keychain that produced the signature is returned too.
51+
func VerifyDetachedSignature(targetPath *paths.Path, signaturePath *paths.Path, keyPath *paths.Path) (bool, *openpgp.Entity, error) {
52+
arduinoKeyringFile, err := os.Open(keyPath.String())
53+
if err != nil {
54+
panic("could not open signature keys")
55+
}
56+
defer arduinoKeyringFile.Close()
57+
return verifySignature(targetPath, signaturePath, arduinoKeyringFile)
58+
}
59+
60+
//verifySignature is an helper function that checks that the detached GPG signature (in the
61+
// signaturePath file) matches the given targetPath file and is an authentic
62+
// signature. If any of the above conditions fails this function returns false.
63+
// The PGP entity in the trusted keychain that produced the signature is returned too.
64+
func verifySignature(targetPath *paths.Path, signaturePath *paths.Path, arduinoKeyringFile io.Reader) (bool, *openpgp.Entity, error) {
4065
keyRing, err := openpgp.ReadKeyRing(arduinoKeyringFile)
4166
if err != nil {
4267
return false, nil, fmt.Errorf("retrieving Arduino public keys: %s", err)
4368
}
44-
4569
target, err := targetPath.Open()
4670
if err != nil {
4771
return false, nil, fmt.Errorf("opening target file: %s", err)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /