Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pluggable verifiers #84

Merged
merged 1 commit into from
May 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions signed/verifiers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package signed

import (
"crypto"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"

"github.com/flynn/go-tuf/Godeps/_workspace/src/github.com/agl/ed25519"
)

// Verifier describes the verification interface. Implement this interface
// to add additional verifiers to go-tuf.
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 []byte, msg []byte, sig []byte) error
}

// Verifiers is used to map algorithm names to Verifier instances.
var Verifiers = map[string]Verifier{
"ed25519": Ed25519Verifier{},
//"rsa": RSAVerifier{},
}

// RegisterVerifier provides a convenience function for init() functions
// to register additional verifiers or replace existing ones.
func RegisterVerifier(name string, v Verifier) {
Verifiers[name] = v
}

// Ed25519Verifier is an implementation of a Verifier that verifies ed25519 signatures
type Ed25519Verifier struct{}

func (v Ed25519Verifier) Verify(key []byte, msg []byte, sig []byte) error {
var sigBytes [ed25519.SignatureSize]byte
if len(sig) != len(sigBytes) {
return ErrInvalid
}
copy(sigBytes[:], sig)

var keyBytes [ed25519.PublicKeySize]byte
copy(keyBytes[:], key)

if !ed25519.Verify(&keyBytes, msg, &sigBytes) {
return ErrInvalid
}
return nil
}

// RSAVerifier is an implementation of a Verifier that verifies RSA signatures.
// N.B. Currently not covered by unit tests, use at your own risk.
type RSAVerifier struct{}

func (v RSAVerifier) Verify(key []byte, msg []byte, sig []byte) error {
digest := sha256.Sum256(msg)
pub, err := x509.ParsePKIXPublicKey(key)
if err != nil {
return ErrInvalid
}

rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
return ErrInvalid
}

if err = rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, digest[:], sig); err != nil {
return ErrInvalid
}
return nil
}
6 changes: 3 additions & 3 deletions signed/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func VerifySignatures(s *data.Signed, role string, db *keys.DB) error {
valid := make(map[string]struct{})
var sigBytes [ed25519.SignatureSize]byte
for _, sig := range s.Signatures {
if sig.Method != "ed25519" {
if _, ok := Verifiers[sig.Method]; !ok {
return ErrWrongMethod
}
if len(sig.Signature) != len(sigBytes) {
Expand All @@ -92,8 +92,8 @@ func VerifySignatures(s *data.Signed, role string, db *keys.DB) error {
}

copy(sigBytes[:], sig.Signature)
if !ed25519.Verify(&key.Public, msg, &sigBytes) {
return ErrInvalid
if err := Verifiers[sig.Method].Verify(key.Public[:], msg, sigBytes[:]); err != nil {
return err
}
valid[sig.KeyID] = struct{}{}
}
Expand Down