mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
release/dist/cli: add verify-package-signature command (#9110)
Helper command to verify package signatures, mainly for debugging. Also fix a copy-paste mistake in error message in distsign. Updates #8760 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
parent
c86a610eb3
commit
18d9c92342
@ -224,7 +224,7 @@ func (c *Client) Download(srcPath, dstPath string) error {
|
||||
if !VerifyAny(sigPub, msg, sig) {
|
||||
// Best-effort clean up of downloaded package.
|
||||
os.Remove(dstPathUnverified)
|
||||
return fmt.Errorf("signature %q for key %q does not validate with the current release signing key; either you are under attack, or attempting to download an old version of Tailscale which was signed with an older signing key", sigURL, srcURL)
|
||||
return fmt.Errorf("signature %q for file %q does not validate with the current release signing key; either you are under attack, or attempting to download an old version of Tailscale which was signed with an older signing key", sigURL, srcURL)
|
||||
}
|
||||
|
||||
if err := os.Rename(dstPathUnverified, dstPath); err != nil {
|
||||
|
63
release/dist/cli/cli.go
vendored
63
release/dist/cli/cli.go
vendored
@ -8,10 +8,12 @@ import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"encoding/binary"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -119,6 +121,21 @@ func CLI(getTargets func() ([]dist.Target, error)) *ffcli.Command {
|
||||
return fs
|
||||
})(),
|
||||
},
|
||||
{
|
||||
Name: "verify-package-signature",
|
||||
Exec: func(ctx context.Context, args []string) error {
|
||||
return runVerifyPackageSignature(ctx)
|
||||
},
|
||||
ShortUsage: "dist verify-package-signature",
|
||||
ShortHelp: "Verify a package signture using a signing key",
|
||||
FlagSet: (func() *flag.FlagSet {
|
||||
fs := flag.NewFlagSet("verify-package-signature", flag.ExitOnError)
|
||||
fs.StringVar(&verifyPackageSignatureArgs.signPubPath, "sign-pub-path", "signing-public-key.pem", "path to the signing public key; this can be a bundle of multiple keys")
|
||||
fs.StringVar(&verifyPackageSignatureArgs.packagePath, "package-path", "", "path to the package that was signed")
|
||||
fs.StringVar(&verifyPackageSignatureArgs.sigPath, "sig-path", "signature.bin", "path to the signature file")
|
||||
return fs
|
||||
})(),
|
||||
},
|
||||
},
|
||||
Exec: func(context.Context, []string) error { return flag.ErrHelp },
|
||||
}
|
||||
@ -287,19 +304,20 @@ var verifyKeySignatureArgs struct {
|
||||
}
|
||||
|
||||
func runVerifyKeySignature(ctx context.Context) error {
|
||||
rootPubBundle, err := os.ReadFile(verifyKeySignatureArgs.rootPubPath)
|
||||
args := verifyKeySignatureArgs
|
||||
rootPubBundle, err := os.ReadFile(args.rootPubPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rootPubs, err := distsign.ParseRootKeyBundle(rootPubBundle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing %q: %w", verifyKeySignatureArgs.rootPubPath, err)
|
||||
return fmt.Errorf("parsing %q: %w", args.rootPubPath, err)
|
||||
}
|
||||
signPubBundle, err := os.ReadFile(verifyKeySignatureArgs.signPubPath)
|
||||
signPubBundle, err := os.ReadFile(args.signPubPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sig, err := os.ReadFile(verifyKeySignatureArgs.sigPath)
|
||||
sig, err := os.ReadFile(args.sigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -309,3 +327,40 @@ func runVerifyKeySignature(ctx context.Context) error {
|
||||
fmt.Println("signature ok")
|
||||
return nil
|
||||
}
|
||||
|
||||
var verifyPackageSignatureArgs struct {
|
||||
signPubPath string
|
||||
packagePath string
|
||||
sigPath string
|
||||
}
|
||||
|
||||
func runVerifyPackageSignature(ctx context.Context) error {
|
||||
args := verifyPackageSignatureArgs
|
||||
signPubBundle, err := os.ReadFile(args.signPubPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
signPubs, err := distsign.ParseSigningKeyBundle(signPubBundle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing %q: %w", args.signPubPath, err)
|
||||
}
|
||||
pkg, err := os.Open(args.packagePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer pkg.Close()
|
||||
pkgHash := distsign.NewPackageHash()
|
||||
if _, err := io.Copy(pkgHash, pkg); err != nil {
|
||||
return fmt.Errorf("reading %q: %w", args.packagePath, err)
|
||||
}
|
||||
hash := binary.LittleEndian.AppendUint64(pkgHash.Sum(nil), uint64(pkgHash.Len()))
|
||||
sig, err := os.ReadFile(args.sigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !distsign.VerifyAny(signPubs, hash, sig) {
|
||||
return errors.New("signature not valid")
|
||||
}
|
||||
fmt.Println("signature ok")
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user