blob: 1473cabef3b78e93737aeadf9c06bce86004bcdf [file] [log] [blame]
package verify
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
"encoding/asn1"
"math/big"
"github.com/flynn/go-tuf/data"
"golang.org/x/crypto/ed25519"
)
// A Verifier verifies public key signatures.
type Verifier interface {
// Verify takes a key, message and signature, all as byte slices,
// and determines whether the signature is valid for the given
// key and message.
Verify(key, msg, sig []byte) error
// ValidKey returns true if the provided public key is valid and usable to
// verify signatures with this verifier.
ValidKey([]byte) bool
}
// Verifiers is used to map key types to Verifier instances.
var Verifiers = map[string]Verifier{
data.KeySchemeEd25519: ed25519Verifier{},
data.KeySchemeECDSA_SHA2_P256: p256Verifier{},
}
type ed25519Verifier struct{}
func (ed25519Verifier) Verify(key, msg, sig []byte) error {
if !ed25519.Verify(key, msg, sig) {
return ErrInvalid
}
return nil
}
func (ed25519Verifier) ValidKey(k []byte) bool {
return len(k) == ed25519.PublicKeySize
}
type ecdsaSignature struct {
R, S *big.Int
}
type p256Verifier struct{}
func (p256Verifier) Verify(key, msg, sigBytes []byte) error {
x, y := elliptic.Unmarshal(elliptic.P256(), key)
k := &ecdsa.PublicKey{
Curve: elliptic.P256(),
X: x,
Y: y,
}
var sig ecdsaSignature
if _, err := asn1.Unmarshal(sigBytes, &sig); err != nil {
return ErrInvalid
}
hash := sha256.Sum256(msg)
if !ecdsa.Verify(k, hash[:], sig.R, sig.S) {
return ErrInvalid
}
return nil
}
func (p256Verifier) ValidKey(k []byte) bool {
x, _ := elliptic.Unmarshal(elliptic.P256(), k)
return x != nil
}