gitee.com/lh-her-team/common@v1.5.1/crypto/pkcs11/crypto.go (about)

     1  package pkcs11
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/ecdsa"
     6  	"crypto/elliptic"
     7  	"crypto/rsa"
     8  	"encoding/binary"
     9  	"fmt"
    10  	"math/big"
    11  
    12  	"github.com/pkg/errors"
    13  	"github.com/tjfoc/gmsm/sm2"
    14  
    15  	"github.com/miekg/pkcs11"
    16  )
    17  
    18  func (p11 *P11Handle) GenerateRandom(length int) ([]byte, error) {
    19  	session, err := p11.getSession()
    20  	if err != nil {
    21  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    22  	}
    23  	defer p11.returnSession(err, session)
    24  	return p11.ctx.GenerateRandom(session, length)
    25  }
    26  
    27  // Decrypt decrypts the input with a given mechanism.
    28  func (p11 *P11Handle) Decrypt(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, cipher []byte) ([]byte, error) {
    29  	session, err := p11.getSession()
    30  	if err != nil {
    31  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    32  	}
    33  	defer p11.returnSession(err, session)
    34  	err = p11.ctx.DecryptInit(session, []*pkcs11.Mechanism{mech}, obj)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	out, err := p11.ctx.Decrypt(session, cipher)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	return out, nil
    43  }
    44  
    45  // Sign signs the input with a given mechanism.
    46  func (p11 *P11Handle) Sign(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, msg []byte) ([]byte, error) {
    47  	session, err := p11.getSession()
    48  	if err != nil {
    49  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    50  	}
    51  	defer p11.returnSession(err, session)
    52  	err = p11.ctx.SignInit(session, []*pkcs11.Mechanism{mech}, obj)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	out, err := p11.ctx.Sign(session, msg)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	return out, nil
    61  }
    62  
    63  // Verify verifies a signature over a message with a given mechanism.
    64  func (p11 *P11Handle) Verify(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, msg, sig []byte) error {
    65  	session, err := p11.getSession()
    66  	if err != nil {
    67  		return fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    68  	}
    69  	defer p11.returnSession(err, session)
    70  	err = p11.ctx.VerifyInit(session, []*pkcs11.Mechanism{mech}, obj)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	err = p11.ctx.Verify(session, msg, sig)
    75  	if err != nil {
    76  		return err
    77  	}
    78  	return nil
    79  }
    80  
    81  // Encrypt encrypts a plaintext with a given mechanism.
    82  func (p11 *P11Handle) Encrypt(obj pkcs11.ObjectHandle, mech *pkcs11.Mechanism, plain []byte) ([]byte, error) {
    83  	session, err := p11.getSession()
    84  	if err != nil {
    85  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
    86  	}
    87  	defer p11.returnSession(err, session)
    88  	err = p11.ctx.EncryptInit(session, []*pkcs11.Mechanism{mech}, obj)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  	out, err := p11.ctx.Encrypt(session, plain)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	return out, nil
    97  }
    98  
    99  // GenKeyPair returns asym keypair
   100  func (p11 *P11Handle) GenKeyPair(mech *pkcs11.Mechanism, privAttrs,
   101  	pubAttrs []*pkcs11.Attribute) (pri, pub *pkcs11.ObjectHandle, err error) {
   102  	session, err := p11.getSession()
   103  	if err != nil {
   104  		return nil, nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
   105  	}
   106  	defer p11.returnSession(err, session)
   107  	pubHandle, privHandle, err := p11.ctx.GenerateKeyPair(session, []*pkcs11.Mechanism{mech}, pubAttrs, privAttrs)
   108  	if err != nil {
   109  		return nil, nil, err
   110  	}
   111  	return &privHandle, &pubHandle, nil
   112  }
   113  
   114  // GenerateKey returns sym key
   115  func (p11 *P11Handle) GenerateKey(mech *pkcs11.Mechanism, attrs []*pkcs11.Attribute) (*pkcs11.ObjectHandle, error) {
   116  	session, err := p11.getSession()
   117  	if err != nil {
   118  		return nil, fmt.Errorf("PKCS11 error: fail to get session [%s]", err)
   119  	}
   120  	defer p11.returnSession(err, session)
   121  	keyHandle, err := p11.ctx.GenerateKey(session, []*pkcs11.Mechanism{mech}, attrs)
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	return &keyHandle, nil
   126  }
   127  
   128  // ExportRSAPublicKey export a rsa public key of pkcs11 rsa private key
   129  func (p11 *P11Handle) ExportRSAPublicKey(id []byte) (*rsa.PublicKey, error) {
   130  	template := []*pkcs11.Attribute{
   131  		pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil),
   132  		pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil),
   133  	}
   134  	attrs, err := p11.getAttributes(id, template)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  	n, e := big.NewInt(0), int(0)
   139  	for _, a := range attrs {
   140  		if a.Type == pkcs11.CKA_MODULUS {
   141  			n.SetBytes(a.Value)
   142  		} else if a.Type == pkcs11.CKA_PUBLIC_EXPONENT {
   143  			bigE := big.NewInt(0)
   144  			bigE.SetBytes(a.Value)
   145  			e = int(bigE.Int64())
   146  		}
   147  	}
   148  	if e == 0 || n.Cmp(big.NewInt(0)) == 0 {
   149  		return nil, errors.New("public key missing either modulus or exponent")
   150  	}
   151  	return &rsa.PublicKey{
   152  		N: n,
   153  		E: e,
   154  	}, nil
   155  }
   156  
   157  // ExportECDSAPublicKey export a ecdsa/sm2 public key of pkcs11 ecdsa/sm2 private key
   158  func (p11 *P11Handle) ExportECDSAPublicKey(id []byte, keyType P11KeyType) (interface{}, error) {
   159  	template := []*pkcs11.Attribute{
   160  		pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, nil),
   161  		pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil),
   162  		//pkcs11.NewAttribute(pkcs11.CKA_LABEL, nil),
   163  		//pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_KEY_INFO, nil), //PKCS#11 specification v2.40 support!
   164  	}
   165  	attrs, err := p11.getAttributes(id, template)
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  	if len(attrs) < 2 {
   170  		return nil, errors.New("Got attribute not enough, should greater than 2")
   171  	}
   172  	var curve elliptic.Curve
   173  	if keyType == SM2 {
   174  		curve = sm2.P256Sm2()
   175  	} else {
   176  		curve, err = unmarshalEcParams(attrs[0].Value)
   177  		if err != nil {
   178  			return nil, err
   179  		}
   180  	}
   181  	x, y, err := unmarshalEcPoint(curve, attrs[1].Value)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  	if keyType == SM2 {
   186  		return &sm2.PublicKey{Curve: curve, X: x, Y: y}, nil
   187  	}
   188  	return &ecdsa.PublicKey{Curve: curve, X: x, Y: y}, nil
   189  }
   190  
   191  // getSecretKeySize returns a pkcs11 secret key length
   192  func (p11 *P11Handle) getSecretKeySize(obj pkcs11.ObjectHandle) (int, error) {
   193  	session, err := p11.getSession()
   194  	if err != nil {
   195  		return 0, errors.WithMessage(err, "failed to get pkcs11 session")
   196  	}
   197  	defer p11.returnSession(err, session)
   198  	//CKA_VALUE_LEN
   199  	template := []*pkcs11.Attribute{
   200  		pkcs11.NewAttribute(pkcs11.CKA_VALUE_LEN, nil),
   201  	}
   202  	attrs, err := p11.ctx.GetAttributeValue(session, obj, template)
   203  	if err != nil {
   204  		return 0, errors.WithMessage(err, "failed to get aes key CKA_VALUE_LEN")
   205  	}
   206  	if len(attrs) == 1 {
   207  		return bytesToInt(attrs[0].Value)
   208  	}
   209  	//CKA_VALUE
   210  	template = []*pkcs11.Attribute{
   211  		pkcs11.NewAttribute(pkcs11.CKA_VALUE, nil),
   212  	}
   213  	attrs, err = p11.ctx.GetAttributeValue(session, obj, template)
   214  	if err != nil {
   215  		return 0, errors.WithMessage(err, "failed to get aes key attribute")
   216  	}
   217  	if attrs == nil || len(attrs) < 1 {
   218  		return 0, errors.New("attributes is empty")
   219  	}
   220  	return len(attrs[0].Value), nil
   221  }
   222  
   223  // bytesToInt le bytes to int32, little endian
   224  func bytesToInt(b []byte) (int, error) {
   225  	bytesBuffer := bytes.NewBuffer(b)
   226  	var x uint32
   227  	err := binary.Read(bytesBuffer, binary.LittleEndian, &x)
   228  	if err != nil {
   229  		return -1, err
   230  	}
   231  	return int(x), nil
   232  }