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 }