From e9682162ac908e9b9d81f3378faf8b38d1baa630 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 28 Apr 2019 12:27:06 +0200 Subject: updater: add initial skeleton --- updater/signify.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 updater/signify.go (limited to 'updater/signify.go') diff --git a/updater/signify.go b/updater/signify.go new file mode 100644 index 00000000..d4605cbb --- /dev/null +++ b/updater/signify.go @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package updater + +import ( + "bytes" + "encoding/base64" + "encoding/hex" + "errors" + "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/ed25519" + "strings" +) + +/* + * Generate with: + * $ b2sum -l 256 *.msi > list + * $ signify -S -e -s release.sec -m list + * $ upload ./list.sec + */ + +type fileList map[string][blake2b.Size256]byte + +func readFileList(input []byte) (fileList, error) { + publicKeyBytes, err := base64.StdEncoding.DecodeString(releasePublicKeyBase64) + if err != nil || len(publicKeyBytes) != ed25519.PublicKeySize+10 || publicKeyBytes[0] != 'E' || publicKeyBytes[1] != 'd' { + return nil, errors.New("Invalid public key") + } + publicKeyBytes = publicKeyBytes[10:] + lines := bytes.SplitN(input, []byte{'\n'}, 3) + if len(lines) != 3 { + return nil, errors.New("Signature input has too few lines") + } + if !bytes.HasPrefix(lines[0], []byte("untrusted comment: ")) { + return nil, errors.New("Signature input is missing untrusted comment") + } + signatureBytes, err := base64.StdEncoding.DecodeString(string(lines[1])) + if err != nil { + return nil, errors.New("Signature input is not valid base64") + } + if len(signatureBytes) != ed25519.SignatureSize+10 || signatureBytes[0] != 'E' || signatureBytes[1] != 'd' { + return nil, errors.New("Signature input bytes are incorrect length or represent invalid signature type") + } + signatureBytes = signatureBytes[10:] + if !ed25519.Verify(publicKeyBytes, lines[2], signatureBytes) { + return nil, errors.New("Signature is invalid") + } + fileLines := strings.Split(string(lines[2]), "\n") + fileHashes := make(map[string][blake2b.Size256]byte, len(fileLines)) + for index, line := range fileLines { + if len(line) == 0 && index == len(fileLines)-1 { + break + } + components := strings.SplitN(line, " ", 2) + if len(components) != 2 { + return nil, errors.New("File hash line has too few components") + } + maybeHash, err := hex.DecodeString(components[0]) + if err != nil || len(maybeHash) != blake2b.Size256 { + return nil, errors.New("File hash is invalid base64 or incorrect number of bytes") + } + var hash [blake2b.Size256]byte + copy(hash[:], maybeHash) + fileHashes[components[1]] = hash + } + if len(fileHashes) == 0 { + return nil, errors.New("No file hashes found in signed input") + } + return fileHashes, nil +} -- cgit v1.2.3-59-g8ed1b