github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/cmds/core/gpgv/gpgv.go (about) 1 // Copyright 2016-2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // gpgv validates a signature against a file. 6 // 7 // Synopsis: 8 // gpgv [-v] KEY SIG CONTENT 9 // 10 // Description: 11 // It prints "OK\n" to stdout if the check succeeds and exits with 0. It 12 // prints an error message and exits with non-0 otherwise. 13 // 14 // The openpgp package ReadKeyRing function does not completely implement 15 // RFC4880 in that it can't use a PublicSigningKey with 0 signatures. We 16 // use one from Eric Grosse instead. 17 // 18 // Options: 19 // -v: verbose 20 // 21 // Author: 22 // grosse@gmail.com. 23 package main 24 25 import ( 26 "crypto" 27 "flag" 28 "fmt" 29 "io" 30 "log" 31 "os" 32 33 "golang.org/x/crypto/openpgp/errors" 34 "golang.org/x/crypto/openpgp/packet" 35 ) 36 37 var ( 38 verbose bool 39 debug = func(string, ...interface{}) {} 40 ) 41 42 func main() { 43 flag.BoolVar(&verbose, "v", false, "verbose") 44 flag.Parse() 45 if verbose { 46 debug = log.Printf 47 } 48 if flag.NArg() != 3 { 49 log.Fatal("usage: boot-verify [-v] key sig content") 50 } 51 52 keyf, err := os.Open(flag.Args()[0]) 53 if err != nil { 54 log.Fatal(err) 55 } 56 sigf, err := os.Open(flag.Args()[1]) 57 if err != nil { 58 log.Fatal(err) 59 } 60 contentf, err := os.Open(flag.Args()[2]) 61 if err != nil { 62 log.Fatal(err) 63 } 64 65 key, err := readPublicSigningKey(keyf) 66 if err != nil { 67 log.Fatal("key ", err) 68 } 69 70 if err = verifyDetachedSignature(key, contentf, sigf); err != nil { 71 log.Fatal("verify: ", err) 72 } 73 fmt.Printf("OK") 74 } 75 76 func readPublicSigningKey(keyf io.Reader) (*packet.PublicKey, error) { 77 keypackets := packet.NewReader(keyf) 78 p, err := keypackets.Next() 79 if err != nil { 80 return nil, err 81 } 82 switch pkt := p.(type) { 83 case *packet.PublicKey: 84 debug("key: ", pkt) 85 return pkt, nil 86 default: 87 log.Printf("ReadPublicSigningKey: got %T, want *packet.PublicKey", pkt) 88 } 89 return nil, errors.StructuralError("expected first packet to be PublicKey") 90 } 91 92 func verifyDetachedSignature(key *packet.PublicKey, contentf, sigf io.Reader) error { 93 var hashFunc crypto.Hash 94 95 packets := packet.NewReader(sigf) 96 p, err := packets.Next() 97 if err != nil { 98 return err 99 } 100 switch sig := p.(type) { 101 case *packet.Signature: 102 hashFunc = sig.Hash 103 case *packet.SignatureV3: 104 hashFunc = sig.Hash 105 default: 106 return errors.UnsupportedError("unrecognized signature") 107 } 108 109 h := hashFunc.New() 110 if _, err := io.Copy(h, contentf); err != nil && err != io.EOF { 111 return err 112 } 113 switch sig := p.(type) { 114 case *packet.Signature: 115 err = key.VerifySignature(h, sig) 116 case *packet.SignatureV3: 117 err = key.VerifySignatureV3(h, sig) 118 default: 119 panic("unreachable") 120 } 121 return err 122 }