[#55] refs: Add Scheme field to Signature

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-02-22 14:25:43 +03:00 committed by LeL
parent 66e1fb8c53
commit a4349f6692
10 changed files with 252 additions and 85 deletions

View file

@ -260,6 +260,7 @@ func (s *Signature) ToGRPCMessage() grpc.Message {
m.SetKey(s.key)
m.SetSign(s.sign)
m.SetScheme(refs.SignatureScheme(s.scheme))
}
return m
@ -273,6 +274,7 @@ func (s *Signature) FromGRPCMessage(m grpc.Message) error {
s.key = v.GetKey()
s.sign = v.GetSign()
s.scheme = SignatureScheme(v.GetScheme())
return nil
}

View file

@ -77,6 +77,26 @@ func (x *Signature) SetSign(v []byte) {
}
}
// SetScheme sets signature scheme.
func (x *Signature) SetScheme(s SignatureScheme) {
if x != nil {
x.Scheme = s
}
}
// FromString parses SignatureScheme from a string representation,
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (x *SignatureScheme) FromString(s string) bool {
i, ok := SignatureScheme_value[s]
if ok {
*x = SignatureScheme(i)
}
return ok
}
// FromString parses ChecksumType from a string representation,
// It is a reverse action to String().
//

151
refs/grpc/types.pb.go generated
View file

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.19.1
// protoc v3.19.4
// source: refs/grpc/types.proto
package refs
@ -20,6 +20,59 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Signature scheme describes digital signing scheme used for (key, signature) pair.
type SignatureScheme int32
const (
// Unknown. The default interpretation depends on a particular structure type.
SignatureScheme_UNSPECIFIED SignatureScheme = 0
// ECDSA with SHA-512 hashing (FIPS 186-3).
SignatureScheme_ECDSA_SHA512 SignatureScheme = 1
// Deterministic ECDSA with SHA-256 hashing (RFC 6979)
SignatureScheme_ECDSA_RFC6979_SHA256 SignatureScheme = 2
)
// Enum value maps for SignatureScheme.
var (
SignatureScheme_name = map[int32]string{
0: "UNSPECIFIED",
1: "ECDSA_SHA512",
2: "ECDSA_RFC6979_SHA256",
}
SignatureScheme_value = map[string]int32{
"UNSPECIFIED": 0,
"ECDSA_SHA512": 1,
"ECDSA_RFC6979_SHA256": 2,
}
)
func (x SignatureScheme) Enum() *SignatureScheme {
p := new(SignatureScheme)
*p = x
return p
}
func (x SignatureScheme) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (SignatureScheme) Descriptor() protoreflect.EnumDescriptor {
return file_refs_grpc_types_proto_enumTypes[0].Descriptor()
}
func (SignatureScheme) Type() protoreflect.EnumType {
return &file_refs_grpc_types_proto_enumTypes[0]
}
func (x SignatureScheme) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use SignatureScheme.Descriptor instead.
func (SignatureScheme) EnumDescriptor() ([]byte, []int) {
return file_refs_grpc_types_proto_rawDescGZIP(), []int{0}
}
// Checksum algorithm type.
type ChecksumType int32
@ -57,11 +110,11 @@ func (x ChecksumType) String() string {
}
func (ChecksumType) Descriptor() protoreflect.EnumDescriptor {
return file_refs_grpc_types_proto_enumTypes[0].Descriptor()
return file_refs_grpc_types_proto_enumTypes[1].Descriptor()
}
func (ChecksumType) Type() protoreflect.EnumType {
return &file_refs_grpc_types_proto_enumTypes[0]
return &file_refs_grpc_types_proto_enumTypes[1]
}
func (x ChecksumType) Number() protoreflect.EnumNumber {
@ -70,7 +123,7 @@ func (x ChecksumType) Number() protoreflect.EnumNumber {
// Deprecated: Use ChecksumType.Descriptor instead.
func (ChecksumType) EnumDescriptor() ([]byte, []int) {
return file_refs_grpc_types_proto_rawDescGZIP(), []int{0}
return file_refs_grpc_types_proto_rawDescGZIP(), []int{1}
}
// Objects in NeoFS are addressed by their ContainerID and ObjectID.
@ -448,6 +501,8 @@ type Signature struct {
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
// Signature
Sign []byte `protobuf:"bytes,2,opt,name=sign,json=signature,proto3" json:"sign,omitempty"`
// Scheme contains digital signature scheme identifier.
Scheme SignatureScheme `protobuf:"varint,3,opt,name=scheme,proto3,enum=neo.fs.v2.refs.SignatureScheme" json:"scheme,omitempty"`
}
func (x *Signature) Reset() {
@ -496,6 +551,13 @@ func (x *Signature) GetSign() []byte {
return nil
}
func (x *Signature) GetScheme() SignatureScheme {
if x != nil {
return x.Scheme
}
return SignatureScheme_UNSPECIFIED
}
// Checksum message.
// Depending on checksum algorithm type the string presentation may vary:
//
@ -585,25 +647,34 @@ var file_refs_grpc_types_proto_rawDesc = []byte{
0x61, 0x6c, 0x75, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05,
0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x22, 0x36, 0x0a, 0x09, 0x53,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x22, 0x6f, 0x0a, 0x09, 0x53,
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x69,
0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x22, 0x4e, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12,
0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e,
0x6e, 0x65, 0x6f, 0x2e, 0x66, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x2e, 0x43,
0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70,
0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03,
0x73, 0x75, 0x6d, 0x2a, 0x41, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x54,
0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x53, 0x55, 0x4d, 0x5f,
0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x54, 0x5a, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48,
0x41, 0x32, 0x35, 0x36, 0x10, 0x02, 0x42, 0x50, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x73, 0x70, 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x6e,
0x65, 0x6f, 0x66, 0x73, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x72,
0x65, 0x66, 0x73, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x3b, 0x72, 0x65, 0x66, 0x73, 0xaa, 0x02, 0x18,
0x4e, 0x65, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e,
0x41, 0x50, 0x49, 0x2e, 0x52, 0x65, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x75, 0x72, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6e, 0x65, 0x6f, 0x2e, 0x66, 0x73, 0x2e, 0x76, 0x32, 0x2e,
0x72, 0x65, 0x66, 0x73, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x63,
0x68, 0x65, 0x6d, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x22, 0x4e, 0x0a, 0x08,
0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6e, 0x65, 0x6f, 0x2e, 0x66, 0x73, 0x2e,
0x76, 0x32, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d,
0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x75,
0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x75, 0x6d, 0x2a, 0x4e, 0x0a, 0x0f,
0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12,
0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
0x12, 0x10, 0x0a, 0x0c, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32,
0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x52, 0x46, 0x43, 0x36,
0x39, 0x37, 0x39, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0c,
0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19,
0x43, 0x48, 0x45, 0x43, 0x4b, 0x53, 0x55, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e,
0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x54,
0x5a, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x02, 0x42,
0x50, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x73,
0x70, 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x6e, 0x65, 0x6f, 0x66, 0x73, 0x2d, 0x61, 0x70,
0x69, 0x2d, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x66, 0x73, 0x2f, 0x67, 0x72, 0x70,
0x63, 0x3b, 0x72, 0x65, 0x66, 0x73, 0xaa, 0x02, 0x18, 0x4e, 0x65, 0x6f, 0x2e, 0x46, 0x69, 0x6c,
0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x50, 0x49, 0x2e, 0x52, 0x65, 0x66,
0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -618,28 +689,30 @@ func file_refs_grpc_types_proto_rawDescGZIP() []byte {
return file_refs_grpc_types_proto_rawDescData
}
var file_refs_grpc_types_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_refs_grpc_types_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_refs_grpc_types_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_refs_grpc_types_proto_goTypes = []interface{}{
(ChecksumType)(0), // 0: neo.fs.v2.refs.ChecksumType
(*Address)(nil), // 1: neo.fs.v2.refs.Address
(*ObjectID)(nil), // 2: neo.fs.v2.refs.ObjectID
(*ContainerID)(nil), // 3: neo.fs.v2.refs.ContainerID
(*OwnerID)(nil), // 4: neo.fs.v2.refs.OwnerID
(*SubnetID)(nil), // 5: neo.fs.v2.refs.SubnetID
(*Version)(nil), // 6: neo.fs.v2.refs.Version
(*Signature)(nil), // 7: neo.fs.v2.refs.Signature
(*Checksum)(nil), // 8: neo.fs.v2.refs.Checksum
(SignatureScheme)(0), // 0: neo.fs.v2.refs.SignatureScheme
(ChecksumType)(0), // 1: neo.fs.v2.refs.ChecksumType
(*Address)(nil), // 2: neo.fs.v2.refs.Address
(*ObjectID)(nil), // 3: neo.fs.v2.refs.ObjectID
(*ContainerID)(nil), // 4: neo.fs.v2.refs.ContainerID
(*OwnerID)(nil), // 5: neo.fs.v2.refs.OwnerID
(*SubnetID)(nil), // 6: neo.fs.v2.refs.SubnetID
(*Version)(nil), // 7: neo.fs.v2.refs.Version
(*Signature)(nil), // 8: neo.fs.v2.refs.Signature
(*Checksum)(nil), // 9: neo.fs.v2.refs.Checksum
}
var file_refs_grpc_types_proto_depIdxs = []int32{
3, // 0: neo.fs.v2.refs.Address.container_id:type_name -> neo.fs.v2.refs.ContainerID
2, // 1: neo.fs.v2.refs.Address.object_id:type_name -> neo.fs.v2.refs.ObjectID
0, // 2: neo.fs.v2.refs.Checksum.type:type_name -> neo.fs.v2.refs.ChecksumType
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
4, // 0: neo.fs.v2.refs.Address.container_id:type_name -> neo.fs.v2.refs.ContainerID
3, // 1: neo.fs.v2.refs.Address.object_id:type_name -> neo.fs.v2.refs.ObjectID
0, // 2: neo.fs.v2.refs.Signature.scheme:type_name -> neo.fs.v2.refs.SignatureScheme
1, // 3: neo.fs.v2.refs.Checksum.type:type_name -> neo.fs.v2.refs.ChecksumType
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_refs_grpc_types_proto_init() }
@ -750,7 +823,7 @@ func file_refs_grpc_types_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_refs_grpc_types_proto_rawDesc,
NumEnums: 1,
NumEnums: 2,
NumMessages: 8,
NumExtensions: 0,
NumServices: 0,

View file

@ -21,6 +21,7 @@ const (
signatureKeyField = 1
signatureValueField = 2
signatureSchemeField = 3
versionMajorField = 1
versionMinorField = 2
@ -250,7 +251,14 @@ func (s *Signature) StableMarshal(buf []byte) ([]byte, error) {
offset += n
_, err = proto.BytesMarshal(signatureValueField, buf[offset:], s.sign)
n, err = proto.BytesMarshal(signatureValueField, buf[offset:], s.sign)
if err != nil {
return nil, err
}
offset += n
_, err = proto.EnumMarshal(signatureSchemeField, buf[offset:], int32(s.scheme))
if err != nil {
return nil, err
}
@ -265,6 +273,7 @@ func (s *Signature) StableSize() (size int) {
size += proto.BytesSize(signatureKeyField, s.key)
size += proto.BytesSize(signatureValueField, s.sign)
size += proto.EnumSize(signatureSchemeField, int32(s.scheme))
return size
}

View file

@ -24,3 +24,24 @@ func (t *ChecksumType) FromString(s string) bool {
return ok
}
// String returns string representation of SignatureScheme.
func (t SignatureScheme) String() string {
return refs.SignatureScheme(t).String()
}
// FromString parses SignatureScheme from a string representation.
// It is a reverse action to String().
//
// Returns true if s was parsed successfully.
func (t *SignatureScheme) FromString(s string) bool {
var g refs.SignatureScheme
ok := g.FromString(s)
if ok {
*t = SignatureScheme(g)
}
return ok
}

View file

@ -1,6 +1,8 @@
package refstest
import (
"math/rand"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
)
@ -88,6 +90,7 @@ func GenerateSignature(empty bool) *refs.Signature {
if !empty {
m.SetKey([]byte{1})
m.SetSign([]byte{2})
m.SetScheme(refs.SignatureScheme(rand.Int31() % 3))
}
return m

View file

@ -31,8 +31,17 @@ type Checksum struct {
type ChecksumType uint32
type SignatureScheme uint32
const (
UnspecifiedScheme SignatureScheme = iota
ECDSA_SHA512
ECDSA_RFC6979_SHA256
)
type Signature struct {
key, sign []byte
scheme SignatureScheme
}
type SubnetID struct {
@ -175,6 +184,19 @@ func (s *Signature) SetSign(v []byte) {
}
}
func (s *Signature) GetScheme() SignatureScheme {
if s != nil {
return s.scheme
}
return UnspecifiedScheme
}
func (s *Signature) SetScheme(scheme SignatureScheme) {
if s != nil {
s.scheme = scheme
}
}
func (s *SubnetID) SetValue(id uint32) {
if s != nil {
s.value = id

View file

@ -131,19 +131,6 @@ func (s StableMarshalerWrapper) SignedDataSize() int {
return 0
}
func keySignatureHandler(s *refs.Signature) signature.KeySignatureHandler {
return func(key []byte, sig []byte) {
s.SetKey(key)
s.SetSign(sig)
}
}
func keySignatureSource(s *refs.Signature) signature.KeySignatureSource {
return func() ([]byte, []byte) {
return s.GetKey(), s.GetSign()
}
}
func SignServiceMessage(key *ecdsa.PrivateKey, msg interface{}) error {
var (
body, meta, verifyOrigin stableMarshaler
@ -213,7 +200,9 @@ func signServiceMessagePart(key *ecdsa.PrivateKey, part stableMarshaler, sigWrit
if err := signature.SignDataWithHandler(
key,
&StableMarshalerWrapper{part},
keySignatureHandler(sig),
func(s *refs.Signature) {
*sig = *s
},
); err != nil {
return err
}
@ -285,7 +274,7 @@ func verifyMatryoshkaLevel(body stableMarshaler, meta metaHeader, verify verific
func verifyServiceMessagePart(part stableMarshaler, sigRdr func() *refs.Signature) error {
return signature.VerifyDataWithSource(
&StableMarshalerWrapper{part},
keySignatureSource(sigRdr()),
sigRdr,
)
}

View file

@ -3,6 +3,7 @@ package signature
import (
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
crypto "github.com/nspcc-dev/neofs-crypto"
)
@ -13,24 +14,24 @@ type DataSource interface {
type DataWithSignature interface {
DataSource
GetSignatureWithKey() (key, sig []byte)
SetSignatureWithKey(key, sig []byte)
GetSignature() *refs.Signature
SetSignature(*refs.Signature)
}
type SignOption func(*cfg)
type KeySignatureHandler func(key []byte, sig []byte)
type KeySignatureHandler func(*refs.Signature)
type KeySignatureSource func() (key, sig []byte)
type KeySignatureSource func() *refs.Signature
func DataSignature(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) ([]byte, error) {
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error {
if key == nil {
return nil, crypto.ErrEmptyPrivateKey
return crypto.ErrEmptyPrivateKey
}
data, err := dataForSignature(src)
if err != nil {
return nil, err
return err
}
defer bytesPool.Put(data)
@ -40,16 +41,16 @@ func DataSignature(key *ecdsa.PrivateKey, src DataSource, opts ...SignOption) ([
opts[i](cfg)
}
return cfg.signFunc(key, data)
}
func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySignatureHandler, opts ...SignOption) error {
sig, err := DataSignature(key, src, opts...)
sigData, err := sign(cfg, cfg.defaultScheme, key, data)
if err != nil {
return err
}
handler(crypto.MarshalPublicKey(&key.PublicKey), sig)
sig := new(refs.Signature)
sig.SetScheme(cfg.defaultScheme)
sig.SetKey(crypto.MarshalPublicKey(&key.PublicKey))
sig.SetSign(sigData)
handler(sig)
return nil
}
@ -67,19 +68,13 @@ func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ..
opts[i](cfg)
}
key, sig := sigSrc()
return cfg.verifyFunc(
crypto.UnmarshalPublicKey(key),
data,
sig,
)
return verify(cfg, data, sigSrc())
}
func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) error {
return SignDataWithHandler(key, v, v.SetSignatureWithKey, opts...)
return SignDataWithHandler(key, v, v.SetSignature, opts...)
}
func VerifyData(src DataWithSignature, opts ...SignOption) error {
return VerifyDataWithSource(src, src.GetSignatureWithKey, opts...)
return VerifyDataWithSource(src, src.GetSignature, opts...)
}

View file

@ -2,25 +2,58 @@ package signature
import (
"crypto/ecdsa"
"fmt"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
crypto "github.com/nspcc-dev/neofs-crypto"
)
type cfg struct {
signFunc func(key *ecdsa.PrivateKey, msg []byte) ([]byte, error)
verifyFunc func(key *ecdsa.PublicKey, msg []byte, sig []byte) error
defaultScheme refs.SignatureScheme
restrictScheme refs.SignatureScheme
}
func defaultCfg() *cfg {
return &cfg{
signFunc: crypto.Sign,
verifyFunc: crypto.Verify,
defaultScheme: refs.ECDSA_SHA512,
restrictScheme: refs.UnspecifiedScheme,
}
}
func verify(cfg *cfg, data []byte, sig *refs.Signature) error {
scheme := sig.GetScheme()
if scheme == refs.UnspecifiedScheme {
scheme = cfg.defaultScheme
}
if cfg.restrictScheme != refs.UnspecifiedScheme && scheme != cfg.restrictScheme {
return fmt.Errorf("%w: unexpected signature scheme", crypto.ErrInvalidSignature)
}
pub := crypto.UnmarshalPublicKey(sig.GetKey())
switch scheme {
case refs.ECDSA_SHA512:
return crypto.Verify(pub, data, sig.GetSign())
case refs.ECDSA_RFC6979_SHA256:
return crypto.VerifyRFC6979(pub, data, sig.GetSign())
default:
return crypto.ErrInvalidSignature
}
}
func sign(cfg *cfg, scheme refs.SignatureScheme, key *ecdsa.PrivateKey, data []byte) ([]byte, error) {
switch scheme {
case refs.ECDSA_SHA512:
return crypto.Sign(key, data)
case refs.ECDSA_RFC6979_SHA256:
return crypto.SignRFC6979(key, data)
default:
panic("unsupported scheme")
}
}
func SignWithRFC6979() SignOption {
return func(c *cfg) {
c.signFunc = crypto.SignRFC6979
c.verifyFunc = crypto.VerifyRFC6979
c.defaultScheme = refs.ECDSA_RFC6979_SHA256
c.restrictScheme = refs.ECDSA_RFC6979_SHA256
}
}