2022-12-13 14:36:35 +00:00
|
|
|
package frostfscrypto
|
2022-04-05 11:13:34 +00:00
|
|
|
|
|
|
|
import (
|
2022-07-07 10:51:05 +00:00
|
|
|
"errors"
|
2022-04-05 11:13:34 +00:00
|
|
|
"fmt"
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
2022-04-05 11:13:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Signature represents a confirmation of data integrity received by the
|
|
|
|
// digital signature mechanism.
|
|
|
|
//
|
2022-12-13 14:36:35 +00:00
|
|
|
// Signature is mutually compatible with github.com/TrueCloudLab/frostfs-api-go/v2/refs.Signature
|
2022-04-05 11:13:34 +00:00
|
|
|
// message. See ReadFromV2 / WriteToV2 methods.
|
|
|
|
//
|
|
|
|
// Note that direct typecast is not safe and may result in loss of compatibility:
|
2022-08-24 14:17:40 +00:00
|
|
|
//
|
|
|
|
// _ = Signature(refs.Signature{}) // not recommended
|
2022-04-05 11:13:34 +00:00
|
|
|
type Signature refs.Signature
|
|
|
|
|
2022-07-07 10:51:05 +00:00
|
|
|
// ReadFromV2 reads Signature from the refs.Signature message. Checks if the
|
2022-12-29 10:46:18 +00:00
|
|
|
// message conforms to FrostFS API V2 protocol.
|
2022-04-05 11:13:34 +00:00
|
|
|
//
|
|
|
|
// See also WriteToV2.
|
2022-07-07 10:51:05 +00:00
|
|
|
func (x *Signature) ReadFromV2(m refs.Signature) error {
|
|
|
|
if len(m.GetKey()) == 0 {
|
|
|
|
return errors.New("missing public key")
|
|
|
|
} else if len(m.GetSign()) == 0 {
|
|
|
|
return errors.New("missing signature")
|
|
|
|
}
|
|
|
|
|
|
|
|
switch m.GetScheme() {
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported scheme %v", m.GetSign())
|
|
|
|
case
|
|
|
|
refs.ECDSA_SHA512,
|
|
|
|
refs.ECDSA_RFC6979_SHA256,
|
|
|
|
refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT:
|
|
|
|
}
|
|
|
|
|
2022-04-05 11:13:34 +00:00
|
|
|
*x = Signature(m)
|
2022-07-07 10:51:05 +00:00
|
|
|
|
|
|
|
return nil
|
2022-04-05 11:13:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// WriteToV2 writes Signature to the refs.Signature message.
|
|
|
|
// The message must not be nil.
|
|
|
|
//
|
|
|
|
// See also ReadFromV2.
|
|
|
|
func (x Signature) WriteToV2(m *refs.Signature) {
|
|
|
|
*m = (refs.Signature)(x)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate signs data using Signer and encodes public key for subsequent
|
|
|
|
// verification.
|
|
|
|
//
|
|
|
|
// Signer MUST NOT be nil.
|
|
|
|
//
|
|
|
|
// See also Verify.
|
|
|
|
func (x *Signature) Calculate(signer Signer, data []byte) error {
|
|
|
|
signature, err := signer.Sign(data)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("signer %T failure: %w", signer, err)
|
|
|
|
}
|
|
|
|
|
2022-04-19 07:39:50 +00:00
|
|
|
pub := signer.Public()
|
|
|
|
|
|
|
|
key := make([]byte, pub.MaxEncodedSize())
|
|
|
|
key = key[:pub.Encode(key)]
|
2022-04-05 11:13:34 +00:00
|
|
|
|
|
|
|
m := (*refs.Signature)(x)
|
|
|
|
|
2022-04-19 07:25:42 +00:00
|
|
|
m.SetScheme(refs.SignatureScheme(signer.Scheme()))
|
2022-04-05 11:13:34 +00:00
|
|
|
m.SetSign(signature)
|
|
|
|
m.SetKey(key)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify verifies data signature using encoded public key. True means valid
|
|
|
|
// signature.
|
|
|
|
//
|
|
|
|
// Verify fails if signature scheme is not supported (see RegisterScheme).
|
|
|
|
//
|
|
|
|
// See also Calculate.
|
|
|
|
func (x Signature) Verify(data []byte) bool {
|
|
|
|
m := (*refs.Signature)(&x)
|
|
|
|
|
2022-04-19 07:25:42 +00:00
|
|
|
f, ok := publicKeys[Scheme(m.GetScheme())]
|
2022-04-05 11:13:34 +00:00
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
key := f()
|
|
|
|
|
|
|
|
err := key.Decode(m.GetKey())
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return key.Verify(data, m.GetSign())
|
|
|
|
}
|