github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/integration/pkcs11/p11key.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package pkcs11 8 9 import ( 10 "crypto" 11 "crypto/ecdsa" 12 "encoding/asn1" 13 "fmt" 14 "io" 15 "math/big" 16 17 "github.com/miekg/pkcs11" 18 ) 19 20 // P11ECDSAKey test implementation of crypto.Signer. 21 type P11ECDSAKey struct { 22 ctx *pkcs11.Ctx 23 session pkcs11.SessionHandle 24 publicKey *ecdsa.PublicKey 25 privateKeyHandle pkcs11.ObjectHandle 26 } 27 28 // Public returns the corresponding public key for the 29 // private key. 30 func (k *P11ECDSAKey) Public() crypto.PublicKey { 31 return k.publicKey 32 } 33 34 // Sign implements crypto.Signer Sign(). Signs the digest the with the private key and returns a byte signature. 35 func (k *P11ECDSAKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { 36 if len(digest) != opts.HashFunc().Size() { 37 return nil, fmt.Errorf("digest length does not equal hash function length") 38 } 39 40 mech := []*pkcs11.Mechanism{ 41 pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil), 42 } 43 44 err = k.ctx.SignInit(k.session, mech, k.privateKeyHandle) 45 if err != nil { 46 return nil, fmt.Errorf("sign init failed: %s", err) 47 } 48 49 signature, err = k.ctx.Sign(k.session, digest) 50 if err != nil { 51 return nil, fmt.Errorf("sign failed: %s", err) 52 } 53 54 type ECDSASignature struct{ R, S *big.Int } 55 56 R := new(big.Int) 57 S := new(big.Int) 58 R.SetBytes(signature[0 : len(signature)/2]) 59 S.SetBytes(signature[len(signature)/2:]) 60 61 return asn1.Marshal(ECDSASignature{R: R, S: S}) 62 }