mirror of
https://github.com/libp2p/go-libp2p-core.git
synced 2025-02-24 08:30:11 +08:00
79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
package crypto
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"github.com/golang/protobuf/proto"
|
|
pb "github.com/libp2p/go-libp2p-core/crypto/pb"
|
|
)
|
|
|
|
func MakeEnvelope(privateKey PrivKey, domain string, typeHint []byte, contents []byte) (*pb.SignedEnvelope, error) {
|
|
pubKey, err := PublicKeyToProto(privateKey.GetPublic())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
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,
|
|
}, 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) {
|
|
e := pb.SignedEnvelope{}
|
|
if err := proto.Unmarshal(serializedEnvelope, &e); err != nil {
|
|
return nil, err
|
|
}
|
|
return &e, nil
|
|
}
|
|
|
|
func OpenEnvelope(domain string, envelope *pb.SignedEnvelope) ([]byte, error) {
|
|
valid, err := ValidateEnvelope(domain, envelope)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !valid {
|
|
return nil, errors.New("invalid signature")
|
|
}
|
|
return envelope.Contents, nil
|
|
}
|
|
|
|
func makeSigBuffer(domain string, typeHint []byte, content []byte) []byte {
|
|
b := bytes.Buffer{}
|
|
domainBytes := []byte(domain)
|
|
b.Write(encodedSize(domainBytes))
|
|
b.Write(domainBytes)
|
|
b.Write(encodedSize(typeHint))
|
|
b.Write(typeHint)
|
|
b.Write(encodedSize(content))
|
|
b.Write(content)
|
|
return b.Bytes()
|
|
}
|
|
|
|
func encodedSize(content []byte) []byte {
|
|
b := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(b, uint64(len(content)))
|
|
return b
|
|
} |