github.com/keygen-sh/go-update@v1.0.0/verifier.go (about) 1 package update 2 3 import ( 4 "crypto" 5 "crypto/dsa" 6 "crypto/ecdsa" 7 "crypto/rsa" 8 "encoding/asn1" 9 "errors" 10 "math/big" 11 ) 12 13 // Verifier defines an interface for verfiying an update's signature with a public key. 14 type Verifier interface { 15 VerifySignature(checksum, signature []byte, h crypto.Hash, publicKey crypto.PublicKey) error 16 } 17 18 type verifyFn func([]byte, []byte, crypto.Hash, crypto.PublicKey) error 19 20 func (fn verifyFn) VerifySignature(checksum []byte, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error { 21 return fn(checksum, signature, hash, publicKey) 22 } 23 24 // NewRSAVerifier returns a Verifier that uses the RSA algorithm to verify updates. 25 func NewRSAVerifier() Verifier { 26 return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error { 27 key, ok := publicKey.(*rsa.PublicKey) 28 if !ok { 29 return errors.New("not a valid RSA public key") 30 } 31 return rsa.VerifyPKCS1v15(key, hash, checksum, signature) 32 }) 33 } 34 35 type rsDER struct { 36 R *big.Int 37 S *big.Int 38 } 39 40 // NewECDSAVerifier returns a Verifier that uses the ECDSA algorithm to verify updates. 41 func NewECDSAVerifier() Verifier { 42 return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error { 43 key, ok := publicKey.(*ecdsa.PublicKey) 44 if !ok { 45 return errors.New("not a valid ECDSA public key") 46 } 47 var rs rsDER 48 if _, err := asn1.Unmarshal(signature, &rs); err != nil { 49 return err 50 } 51 if !ecdsa.Verify(key, checksum, rs.R, rs.S) { 52 return errors.New("failed to verify ecsda signature") 53 } 54 return nil 55 }) 56 } 57 58 // NewDSAVerifier returns a Verifier that uses the DSA algorithm to verify updates. 59 func NewDSAVerifier() Verifier { 60 return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error { 61 key, ok := publicKey.(*dsa.PublicKey) 62 if !ok { 63 return errors.New("not a valid DSA public key") 64 } 65 var rs rsDER 66 if _, err := asn1.Unmarshal(signature, &rs); err != nil { 67 return err 68 } 69 if !dsa.Verify(key, checksum, rs.R, rs.S) { 70 return errors.New("failed to verify ecsda signature") 71 } 72 return nil 73 }) 74 }