Mainly move cryptography-related code outside.
package yacpki
import (
- "bytes"
- "hash"
-
- "github.com/google/uuid"
- "go.cypherpunks.su/gogost/v6/gost34112012256"
- "go.cypherpunks.su/gogost/v6/gost34112012512"
- "golang.org/x/crypto/blake2b"
-
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/yacpki/utils"
+ "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b"
+ "go.cypherpunks.su/yac/gyac/yacpki/gost"
)
const (
- AlgoEd25519BLAKE2b = "ed25519-blake2b"
- AlgoGOST3410256A = "gost3410-256A"
- AlgoGOST3410512C = "gost3410-512C"
- AlgoStreebog256 = "streebog256"
- AlgoStreebog512 = "streebog512"
+ Ed25519BLAKE2b = ed25519blake2b.Ed25519BLAKE2b
+ GOST3410256A = gost.GOST3410256A
+ GOST3410512C = gost.GOST3410512C
)
-
-var HashToNew = map[string]func() hash.Hash{
- AlgoStreebog256: gost34112012256.New,
- AlgoStreebog512: gost34112012512.New,
-}
-
-type AV struct {
- A string `yac:"a"`
- V []byte `yac:"v"`
-}
-
-func (av *AV) Id() (id uuid.UUID) {
- var hasher hash.Hash
- switch av.A {
- case AlgoEd25519BLAKE2b:
- var err error
- hasher, err = blake2b.New256(nil)
- if err != nil {
- panic(err)
- }
- case AlgoGOST3410256A, AlgoGOST3410512C:
- hasher = gost34112012256.New()
- default:
- panic("unsupported algorithm")
- }
- utils.MustWrite(hasher, gyac.FromGo(av).Encode(nil))
- id, err := uuid.NewRandomFromReader(bytes.NewReader(hasher.Sum(nil)))
- if err != nil {
- panic(err)
- }
- return id
-}
--- /dev/null
+package yacpki
+
+import (
+ "bytes"
+ "hash"
+
+ "github.com/google/uuid"
+
+ "go.cypherpunks.su/yac/gyac"
+ pkihash "go.cypherpunks.su/yac/gyac/yacpki/hash"
+ "go.cypherpunks.su/yac/gyac/yacpki/utils"
+)
+
+// Algorithm-value often used structure.
+type AV struct {
+ A string `yac:"a"`
+ V []byte `yac:"v"`
+}
+
+// Calculate UUID of the AV. UUIDv4 is generated from the hash output of
+// the av structure. Hash algorithm selection depends on av.A. uuid.Nil
+// is returned if algorithm is not supported.
+func (av *AV) Id() (id uuid.UUID) {
+ var hasher hash.Hash
+ switch av.A {
+ case Ed25519BLAKE2b:
+ hasher = pkihash.ByName(pkihash.BLAKE2b256)
+ case GOST3410256A, GOST3410512C:
+ hasher = pkihash.ByName(pkihash.Streebog256)
+ default:
+ return uuid.Nil
+ }
+ utils.MustWrite(hasher, gyac.FromGo(av).Encode(nil))
+ id, err := uuid.NewRandomFromReader(bytes.NewReader(hasher.Sum(nil)))
+ if err != nil {
+ panic(err)
+ }
+ return id
+}
"crypto"
"errors"
"fmt"
- "hash"
"time"
"github.com/google/uuid"
- "go.cypherpunks.su/gogost/v6/gost3410"
- "go.cypherpunks.su/gogost/v6/gost34112012256"
- "go.cypherpunks.su/gogost/v6/gost34112012512"
"go.cypherpunks.su/yac/gyac"
"go.cypherpunks.su/yac/gyac/mapstruct"
- "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b/ed25519"
- "go.cypherpunks.su/yac/gyac/yacpki/utils"
+ ed25519blake2b "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b"
+ "go.cypherpunks.su/yac/gyac/yacpki/gost"
)
const (
- KUCA = "ca"
- KUSig = "sig"
+ KUCA = "ca" // CA-capable key usage
+ KUSig = "sig" // Signing-capable key usage
)
+// Public key.
type Pub struct {
A string `yac:"a"`
V []byte `yac:"v"`
Id uuid.UUID `yac:"id"`
}
+// Certificate load (contents).
type CerLoad struct {
KU *map[string]*struct{} `yac:"ku,omitempty"`
Subj map[string]string `yac:"sub"`
Pub []Pub `yac:"pub"`
}
-func CerParse(data []byte) (sd *SignedData, tail []byte, err error) {
- sd, tail, err = SignedDataParse(data)
- if err != nil {
- return
- }
- err = sd.CerParse()
- return
-}
-
+// Parse SignedData contents as CerLoad (certificate) and check its
+// signatures necessary structure. sd.Load.V will hold the CerLoad in
+// case of success.
func (sd *SignedData) CerParse() error {
if sd.Load.T != "cer" {
return errors.New("CerParse: wrong load type")
return nil
}
-func (cer *CerLoad) Can(ku string) bool {
- if cer.KU == nil {
- return false
+// Parse YAC-encoded data as SignedData with the CerLoad (certificate) contents.
+func CerParse(data []byte) (sd *SignedData, tail []byte, err error) {
+ sd, tail, err = SignedDataParse(data)
+ if err != nil {
+ return
}
- if _, ok := (*cer.KU)[ku]; !ok {
+ err = sd.CerParse()
+ return
+}
+
+// Check if cer certificate has desired ku capability.
+func (cer *CerLoad) Can(ku string) (yes bool) {
+ if cer.KU == nil {
return false
}
- return true
+ _, yes = (*cer.KU)[ku]
+ return
}
+// Sign the current SignedData, having CerLoad payload with the provided
+// parent's CerLoad and prv key. Certificate's CID will be automatically
+// generated UUIDv7. since and till times must not have nanoseconds part.
func (sd *SignedData) CerIssueWith(
parent *CerLoad,
prv crypto.Signer,
var ErrSigInvalid = errors.New("signature is invalid")
+// Verify signature of signed data. ErrSigInvalid will be returned in
+// case of invalid signature.
func (cer *CerLoad) CheckSignature(signed, signature []byte) (err error) {
if !cer.Can(KUSig) || len(cer.Pub) != 1 {
err = errors.New("cer can not sign")
return
}
pub := cer.Pub[0]
+ var valid bool
switch pub.A {
- case AlgoEd25519BLAKE2b:
- if len(pub.V) != ed25519.PublicKeySize {
- err = errors.New("invalid ed25519 public key size")
- return
- }
- if !ed25519.Verify(ed25519.PublicKey(pub.V), signed, signature) {
- err = errors.New("invalid ed25519 signature")
- return
- }
- case AlgoGOST3410256A, AlgoGOST3410512C:
- var pk *gost3410.PublicKey
- pk, err = gost3410.NewPublicKeyBE(GOST3410CurveByName(pub.A), pub.V)
- if err != nil {
- return
- }
- var hasher hash.Hash
- switch pub.A {
- case AlgoGOST3410256A:
- hasher = gost34112012256.New()
- case AlgoGOST3410512C:
- hasher = gost34112012512.New()
+ case Ed25519BLAKE2b:
+ valid, err = ed25519blake2b.Verify(pub.V, signed, signature)
+ if !valid {
+ err = ErrSigInvalid
}
- utils.MustWrite(hasher, signed)
- hsh := hasher.Sum(nil)
- var valid bool
- valid, err = pk.VerifyDigest(hsh,
- append(signature[len(signature)/2:], signature[:len(signature)/2]...))
+ case GOST3410256A, GOST3410512C:
+ valid, err = gost.Verify(pub.A, pub.V, signed, signature)
if !valid {
err = ErrSigInvalid
}
return
}
+// Verify SignedData CerLoad certificate's signature with provided parent.
+// Currently only single signature can be verified.
func (sd *SignedData) CerCheckSignatureFrom(parent *CerLoad) (err error) {
if len(sd.Sigs) != 1 {
err = errors.New("can verify only single signature")
return parent.CheckSignature(gyac.FromGo(tbs).Encode(nil), sig.Sign.V)
}
+// Get CerLoad from SignedData.
+// Returns nil if SignedData does not hold it (or it is not yet parsed).
func (sd *SignedData) CerLoad() *CerLoad {
if sd.Load.T != "cer" {
return nil
return nil
}
+// Verify sd SignedData CerLoad certificate against cers chain of
+// certificate authority ones at specified point of time t.
func (sd *SignedData) CerVerify(cers []*SignedData, t time.Time) (err error) {
{
exp := *(sd.Sigs[0].TBS.Exp)
import (
"crypto"
- "crypto/rand"
"errors"
"flag"
- "io"
"log"
"os"
"strings"
"time"
- "go.cypherpunks.su/gogost/v6/gost3410"
-
"go.cypherpunks.su/yac/gyac"
"go.cypherpunks.su/yac/gyac/yacpki"
- "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b/ed25519"
+ ed25519blake2b "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b"
+ "go.cypherpunks.su/yac/gyac/yacpki/gost"
"go.cypherpunks.su/yac/gyac/yacpki/utils"
)
"Optional notBefore, \"2006-01-02 15:04:05\" format")
lifetime := flag.Uint("lifetime", 365,
"Lifetime of the certificate, days")
- algo := flag.String("algo", "gost3410-256A", "Public key algorithm")
+ algo := flag.String("algo", "", "Public key algorithm")
issuingPrv := flag.String("ca-prv", "",
"Path to private key file for issuing with")
reuseKey := flag.Bool("reuse-key", false,
if *issuingPrv == "" {
log.Fatal("no -ca-key is set")
}
- caPrv, err = yacpki.PrvParse(utils.MustReadFile(*issuingPrv))
+ caPrv, _, err = yacpki.PrvParse(utils.MustReadFile(*issuingPrv))
if err != nil {
log.Fatal(err)
}
}
var prv crypto.Signer
- var pubRaw []byte
- switch *algo {
- case yacpki.AlgoEd25519BLAKE2b:
- if *reuseKey {
- prv, err = yacpki.PrvParse(utils.MustReadFile(*prvPath))
- if err != nil {
- log.Fatal(err)
- }
- prvEd25519 := prv.(ed25519.PrivateKey)
- pubRaw = prvEd25519[ed25519.SeedSize:]
- } else {
- var prvEd25519 ed25519.PrivateKey
- var pubEd25519 ed25519.PublicKey
- pubEd25519, prvEd25519, err = ed25519.GenerateKey(rand.Reader)
- if err != nil {
- log.Fatal(err)
- }
- prv = prvEd25519
- pubRaw = pubEd25519[:]
- err = os.WriteFile(*prvPath, gyac.FromGo(
- yacpki.AV{A: *algo, V: prvEd25519.Seed()},
- ).Encode(nil), 0o600)
- if err != nil {
- log.Fatal(err)
- }
+ var prvRaw []byte
+ var pub []byte
+ if *reuseKey {
+ prv, pub, err = yacpki.PrvParse(utils.MustReadFile(*prvPath))
+ if err != nil {
+ log.Fatal(err)
}
- default: // GOST
- curve := yacpki.GOST3410CurveByName(*algo)
- if curve == nil {
- log.Fatal("unknown -algo specified")
+ } else {
+ switch *algo {
+ case yacpki.Ed25519BLAKE2b:
+ prv, prvRaw, pub, err = ed25519blake2b.NewKeypair()
+ case yacpki.GOST3410256A, yacpki.GOST3410512C:
+ prv, prvRaw, pub, err = gost.NewKeypair(*algo)
+ default:
+ err = errors.New("unknown -algo specified")
}
- var signer *yacpki.GOSTSigner
- if *reuseKey {
- prv, err = yacpki.PrvParse(utils.MustReadFile(*prvPath))
- if err != nil {
- log.Fatal(err)
- }
- signer = prv.(*yacpki.GOSTSigner)
- if signer.Prv.C.Name != curve.Name {
- log.Fatal("-algo is not same with private key")
- }
- } else {
- prvRaw := make([]byte, curve.PointSize())
- if _, err = io.ReadFull(rand.Reader, prvRaw); err != nil {
- log.Fatal(err)
- }
- var prvKey *gost3410.PrivateKey
- prvKey, err = gost3410.NewPrivateKeyBE(curve, prvRaw)
- if err != nil {
- log.Fatal(err)
- }
- raw := gyac.FromGo(yacpki.AV{A: *algo, V: prvKey.RawBE()}).Encode(nil)
- prv, err = yacpki.PrvParse(raw)
- if err != nil {
- log.Fatal(err)
- }
- err = os.WriteFile(*prvPath, raw, 0o600)
- if err != nil {
- log.Fatal(err)
- }
- signer = prv.(*yacpki.GOSTSigner)
+ if err != nil {
+ log.Fatal(err)
}
- var pub *gost3410.PublicKey
- pub, err = signer.Prv.PublicKey()
+ err = os.WriteFile(
+ *prvPath,
+ gyac.FromGo(yacpki.AV{A: *algo, V: prvRaw}).Encode(nil),
+ 0o600,
+ )
if err != nil {
log.Fatal(err)
}
- pubRaw = pub.RawBE()
}
- pubMap := yacpki.Pub{A: *algo, V: pubRaw}
+ pubMap := yacpki.Pub{A: *algo, V: pub}
{
- av := yacpki.AV{A: *algo, V: pubRaw}
+ av := yacpki.AV{A: *algo, V: pub}
pubMap.Id = av.Id()
}
cerLoad := yacpki.CerLoad{Subj: subj, Pub: []yacpki.Pub{pubMap}}
"go.cypherpunks.su/yac/gyac"
"go.cypherpunks.su/yac/gyac/yacpki"
+ pkihash "go.cypherpunks.su/yac/gyac/yacpki/hash"
"go.cypherpunks.su/yac/gyac/yacpki/utils"
)
sdPath := flag.String("sd", "", "Path to signed-data file")
typ := flag.String("type", "data", "Type of the content, /load/t value")
hashAlgo := flag.String("hash", "", "Algorithm identifier of the hash to use")
- verify := flag.Bool("verify", false, "Verify provided -cer with -ca-cer")
+ verify := flag.Bool("verify", false, "Verify with provided -cer")
flag.Parse()
log.SetFlags(log.Lshortfile)
if *prvPath == "" {
log.Fatal("no -prv is set")
}
- signer, err = yacpki.PrvParse(utils.MustReadFile(*prvPath))
+ signer, _, err = yacpki.PrvParse(utils.MustReadFile(*prvPath))
if err != nil {
log.Fatal(err)
}
}
- hashNew := yacpki.HashToNew[*hashAlgo]
- if hashNew == nil {
+ hasher := pkihash.ByName(*hashAlgo)
+ if hasher == nil {
log.Fatal("unknown -hash specified")
}
- hasher := hashNew()
_, err = io.Copy(hasher, bufio.NewReader(os.Stdin))
if err != nil {
log.Fatal(err)
--- /dev/null
+// yacpki provides PKI-related capabilities based on YAC encoded formats.
+package yacpki
--- /dev/null
+package ed25519blake2b
+
+const Ed25519BLAKE2b = "ed25519-blake2b"
--- /dev/null
+package ed25519blake2b
+
+import (
+ "crypto"
+ "crypto/rand"
+
+ "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b/ed25519"
+)
+
+func NewKeypair() (signer crypto.Signer, prv, pub []byte, err error) {
+ var prvEd ed25519.PrivateKey
+ var pubEd ed25519.PublicKey
+ pubEd, prvEd, err = ed25519.GenerateKey(rand.Reader)
+ if err != nil {
+ return
+ }
+ signer = prvEd
+ prv = prvEd.Seed()
+ pub = pubEd[:]
+ return
+}
--- /dev/null
+package ed25519blake2b
+
+import (
+ "crypto"
+ "errors"
+
+ "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b/ed25519"
+)
+
+func NewSigner(v []byte) (prv crypto.Signer, pub []byte, err error) {
+ if len(v) != ed25519.SeedSize {
+ err = errors.New("wrong ed25519 private key size")
+ return
+ }
+ p := ed25519.NewKeyFromSeed(v)
+ pub = p[ed25519.SeedSize:]
+ prv = p
+ return
+}
--- /dev/null
+package ed25519blake2b
+
+import (
+ "errors"
+
+ "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b/ed25519"
+)
+
+func Verify(pub, signed, signature []byte) (valid bool, err error) {
+ if len(pub) != ed25519.PublicKeySize {
+ err = errors.New("invalid ed25519 public key size")
+ return
+ }
+ valid = ed25519.Verify(ed25519.PublicKey(pub), signed, signature)
+ return
+}
+++ /dev/null
-package yacpki
-
-import (
- "crypto"
- "hash"
- "io"
- "log"
-
- "go.cypherpunks.su/gogost/v6/gost3410"
-)
-
-type GOSTSigner struct {
- Prv *gost3410.PrivateKey
- Hasher func() hash.Hash
-}
-
-func (s *GOSTSigner) Public() crypto.PublicKey {
- return s.Prv.Public()
-}
-
-func (s *GOSTSigner) Sign(
- rand io.Reader,
- msg []byte,
- opts crypto.SignerOpts,
-) (signature []byte, err error) {
- h := s.Hasher()
- h.Write(msg)
- dgst := h.Sum(nil)
- signature, err = s.Prv.Sign(rand, dgst, opts)
- if err != nil {
- return
- }
- signature = append(signature[len(signature)/2:], signature[:len(signature)/2]...)
- return
-}
-
-func GOST3410CurveByName(name string) (curve *gost3410.Curve) {
- switch name {
- case AlgoGOST3410256A:
- curve = gost3410.CurveIdtc26gost341012256paramSetA()
- case AlgoGOST3410512C:
- curve = gost3410.CurveIdtc26gost341012512paramSetC()
- default:
- log.Fatal("unknown curve")
- }
- return
-}
--- /dev/null
+package gost
+
+import (
+ "go.cypherpunks.su/gogost/v6/gost3410"
+)
+
+const (
+ GOST3410256A = "gost3410-256A"
+ GOST3410512C = "gost3410-512C"
+)
+
+func CurveByName(name string) (curve *gost3410.Curve) {
+ switch name {
+ case GOST3410256A:
+ curve = gost3410.CurveIdtc26gost341012256paramSetA()
+ case GOST3410512C:
+ curve = gost3410.CurveIdtc26gost341012512paramSetC()
+ }
+ return
+}
--- /dev/null
+package gost
+
+import (
+ "crypto"
+ "crypto/rand"
+ "errors"
+ "io"
+
+ "go.cypherpunks.su/gogost/v6/gost3410"
+)
+
+func NewKeypair(algo string) (signer crypto.Signer, prv, pub []byte, err error) {
+ curve := CurveByName(algo)
+ if curve == nil {
+ err = errors.New("unknown curve")
+ return
+ }
+ prv = make([]byte, curve.PointSize())
+ _, err = io.ReadFull(rand.Reader, prv)
+ if err != nil {
+ return
+ }
+ var pk *gost3410.PrivateKey
+ pk, err = gost3410.NewPrivateKeyBE(curve, prv)
+ if err != nil {
+ return
+ }
+ signer, pub, err = NewSigner(algo, pk.RawBE())
+ return
+}
--- /dev/null
+package gost
+
+import (
+ "crypto"
+ "hash"
+ "io"
+
+ "go.cypherpunks.su/gogost/v6/gost3410"
+ "go.cypherpunks.su/gogost/v6/gost34112012256"
+ "go.cypherpunks.su/gogost/v6/gost34112012512"
+)
+
+type Signer struct {
+ Prv *gost3410.PrivateKey
+ Hasher func() hash.Hash
+}
+
+func (s *Signer) Public() crypto.PublicKey {
+ return s.Prv.Public()
+}
+
+func (s *Signer) Sign(
+ rand io.Reader,
+ msg []byte,
+ opts crypto.SignerOpts,
+) (signature []byte, err error) {
+ h := s.Hasher()
+ h.Write(msg)
+ dgst := h.Sum(nil)
+ signature, err = s.Prv.Sign(rand, dgst, opts)
+ if err != nil {
+ return
+ }
+ signature = append(signature[len(signature)/2:], signature[:len(signature)/2]...)
+ return
+}
+
+func NewSigner(a string, v []byte) (prv crypto.Signer, pub []byte, err error) {
+ signer := Signer{}
+ switch a {
+ case GOST3410256A:
+ signer.Hasher = gost34112012256.New
+ signer.Prv, err = gost3410.NewPrivateKeyBE(
+ gost3410.CurveIdtc26gost341012256paramSetA(), v,
+ )
+ case GOST3410512C:
+ signer.Hasher = gost34112012512.New
+ signer.Prv, err = gost3410.NewPrivateKeyBE(
+ gost3410.CurveIdtc26gost341012512paramSetC(), v,
+ )
+ default:
+ panic("unknown GOST algorithm")
+ }
+ if err != nil {
+ return
+ }
+ prv = &signer
+ var pk *gost3410.PublicKey
+ pk, err = signer.Prv.PublicKey()
+ if err == nil {
+ pub = pk.RawBE()
+ }
+ return
+}
--- /dev/null
+package gost
+
+import (
+ "hash"
+
+ "go.cypherpunks.su/gogost/v6/gost3410"
+ "go.cypherpunks.su/gogost/v6/gost34112012256"
+ "go.cypherpunks.su/gogost/v6/gost34112012512"
+ "go.cypherpunks.su/yac/gyac/yacpki/utils"
+)
+
+func Verify(algo string, pub, signed, signature []byte) (valid bool, err error) {
+ var pk *gost3410.PublicKey
+ pk, err = gost3410.NewPublicKeyBE(CurveByName(algo), pub)
+ if err != nil {
+ return
+ }
+ var hasher hash.Hash
+ switch algo {
+ case GOST3410256A:
+ hasher = gost34112012256.New()
+ case GOST3410512C:
+ hasher = gost34112012512.New()
+ }
+ utils.MustWrite(hasher, signed)
+ hsh := hasher.Sum(nil)
+ valid, err = pk.VerifyDigest(hsh,
+ append(signature[len(signature)/2:], signature[:len(signature)/2]...))
+ return
+}
--- /dev/null
+package hash
+
+import (
+ "hash"
+
+ "go.cypherpunks.su/gogost/v6/gost34112012256"
+ "go.cypherpunks.su/gogost/v6/gost34112012512"
+ "golang.org/x/crypto/blake2b"
+)
+
+const (
+ Streebog256 = "streebog256"
+ Streebog512 = "streebog512"
+ BLAKE2b = "blake2b"
+ BLAKE2b256 = "blake2b256"
+)
+
+func ByName(name string) hash.Hash {
+ switch name {
+ case Streebog256:
+ return gost34112012256.New()
+ case Streebog512:
+ return gost34112012512.New()
+ case BLAKE2b:
+ h, err := blake2b.New512(nil)
+ if err != nil {
+ panic(err)
+ }
+ return h
+ case BLAKE2b256:
+ h, err := blake2b.New256(nil)
+ if err != nil {
+ panic(err)
+ }
+ return h
+ }
+ return nil
+}
"errors"
"fmt"
- "go.cypherpunks.su/gogost/v6/gost3410"
- "go.cypherpunks.su/gogost/v6/gost34112012256"
- "go.cypherpunks.su/gogost/v6/gost34112012512"
-
"go.cypherpunks.su/yac/gyac/mapstruct"
- "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b/ed25519"
+ ed25519blake2b "go.cypherpunks.su/yac/gyac/yacpki/ed25519-blake2b"
+ "go.cypherpunks.su/yac/gyac/yacpki/gost"
)
-func PrvParse(data []byte) (prv crypto.Signer, err error) {
+// Parse private key contained in AV YAC-encoded structure.
+func PrvParse(data []byte) (prv crypto.Signer, pub []byte, err error) {
var av AV
var tail []byte
tail, err = mapstruct.Decode(&av, data)
return
}
switch av.A {
- case AlgoEd25519BLAKE2b:
- prv = ed25519.NewKeyFromSeed(av.V)
- if len(av.V) != ed25519.SeedSize {
- err = errors.New("wrong ed25519 private key size")
- return
- }
- case AlgoGOST3410256A:
- signer := &GOSTSigner{Hasher: gost34112012256.New}
- signer.Prv, err = gost3410.NewPrivateKeyBE(
- gost3410.CurveIdtc26gost341012256paramSetA(), av.V,
- )
- prv = signer
- case AlgoGOST3410512C:
- signer := &GOSTSigner{Hasher: gost34112012512.New}
- signer.Prv, err = gost3410.NewPrivateKeyBE(
- gost3410.CurveIdtc26gost341012512paramSetC(), av.V,
- )
- prv = signer
+ case Ed25519BLAKE2b:
+ prv, pub, err = ed25519blake2b.NewSigner(av.V)
+ case GOST3410256A, GOST3410512C:
+ prv, pub, err = gost.NewSigner(av.A, av.V)
default:
err = fmt.Errorf("unknown private key algo: %s", av.A)
}
Sigs []*Sig `yac:"sigs"`
}
-func SignedDataParse(data []byte) (sd *SignedData, tail []byte, err error) {
- var item gyac.Item
- item, tail, err = gyac.Decode(data)
- if err != nil {
- return
- }
- sd, err = SignedDataParseItem(item)
- return
-}
-
+// Parse signed-data from decoded item.
func SignedDataParseItem(item gyac.Item) (sd *SignedData, err error) {
if item.T != types.Map {
err = errors.New("SignedDataParse: non-map")
return
}
+// Parse signed-data from YAC-encoded data. This is just a wrapper over
+// SignedDataParseItem.
+func SignedDataParse(data []byte) (sd *SignedData, tail []byte, err error) {
+ var item gyac.Item
+ item, tail, err = gyac.Decode(data)
+ if err != nil {
+ return
+ }
+ sd, err = SignedDataParseItem(item)
+ return
+}
+
+// Sign SignedData's contents and sigTBS corresponding data with the
+// provided prv signer, having parent certificate. Signature is appended
+// to the sd.Sigs. parent certificate must have "sig" key-usage.
func (sd *SignedData) SignWith(
parent *CerLoad,
prv crypto.Signer,