diff --git a/crypto/envelope.go b/crypto/envelope.go index a60a54c..86181fd 100644 --- a/crypto/envelope.go +++ b/crypto/envelope.go @@ -6,58 +6,80 @@ import ( "errors" "github.com/golang/protobuf/proto" pb "github.com/libp2p/go-libp2p-core/crypto/pb" + "github.com/libp2p/go-libp2p-core/peer" ) -func MakeEnvelope(privateKey PrivKey, domain string, typeHint []byte, contents []byte) (*pb.SignedEnvelope, error) { - pubKey, err := PublicKeyToProto(privateKey.GetPublic()) - if err != nil { - return nil, err - } +type SignedEnvelope struct { + PublicKey PubKey + TypeHint []byte + contents []byte + signature []byte +} +func MakeEnvelope(privateKey PrivKey, domain string, typeHint []byte, contents []byte) (*SignedEnvelope, error) { toSign := makeSigBuffer(domain, typeHint, contents) sig, err := privateKey.Sign(toSign) if err != nil { return nil, err } - return &pb.SignedEnvelope{ - PublicKey: pubKey, - TypeHint: typeHint, - Contents: contents, - Signature: sig, + return &SignedEnvelope{ + PublicKey: privateKey.GetPublic(), + TypeHint: typeHint, + contents: contents, + signature: sig, }, nil } -func ValidateEnvelope(domain string, envelope *pb.SignedEnvelope) (bool, error) { - key, err := PublicKeyFromProto(envelope.PublicKey) - if err != nil { - return false, err - } - toVerify := makeSigBuffer(domain, envelope.TypeHint, envelope.Contents) - return key.Verify(toVerify, envelope.Signature) -} - -func MarshalEnvelope(envelope *pb.SignedEnvelope) ([]byte, error) { - return proto.Marshal(envelope) -} - -func UnmarshalEnvelope(serializedEnvelope []byte) (*pb.SignedEnvelope, error) { +func UnmarshalEnvelope(serializedEnvelope []byte) (*SignedEnvelope, error) { e := pb.SignedEnvelope{} if err := proto.Unmarshal(serializedEnvelope, &e); err != nil { return nil, err } - return &e, nil + key, err := PublicKeyFromProto(e.PublicKey) + if err != nil { + return nil, err + } + return &SignedEnvelope{ + PublicKey: key, + TypeHint: e.TypeHint, + contents: e.Contents, + signature: e.Signature, + }, nil } -func OpenEnvelope(domain string, envelope *pb.SignedEnvelope) ([]byte, error) { - valid, err := ValidateEnvelope(domain, envelope) +func (e *SignedEnvelope) SignerID() (peer.ID, error) { + return peer.IDFromPublicKey(e.PublicKey) +} + +func (e *SignedEnvelope) Validate(domain string) (bool, error) { + toVerify := makeSigBuffer(domain, e.TypeHint, e.contents) + return e.PublicKey.Verify(toVerify, e.signature) +} + +func (e *SignedEnvelope) Marshal() ([]byte, error) { + key, err := PublicKeyToProto(e.PublicKey) + if err != nil { + return nil, err + } + msg := pb.SignedEnvelope{ + PublicKey: key, + TypeHint: e.TypeHint, + Contents: e.contents, + Signature: e.signature, + } + return proto.Marshal(&msg) +} + +func (e *SignedEnvelope) Open(domain string) ([]byte, error) { + valid, err := e.Validate(domain) if err != nil { return nil, err } if !valid { - return nil, errors.New("invalid signature") + return nil, errors.New("invalid signature or incorrect domain") } - return envelope.Contents, nil + return e.contents, nil } func makeSigBuffer(domain string, typeHint []byte, content []byte) []byte {