github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/bccsp/pkcs11/pkcs11.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  package pkcs11
    17  
    18  import (
    19  	"crypto/ecdsa"
    20  	"crypto/elliptic"
    21  	"crypto/sha256"
    22  	"encoding/asn1"
    23  	"encoding/hex"
    24  	"fmt"
    25  	"math/big"
    26  	"sync"
    27  
    28  	"github.com/miekg/pkcs11"
    29  	"github.com/op/go-logging"
    30  )
    31  
    32  func loadLib(lib, pin, label string) (*pkcs11.Ctx, uint, *pkcs11.SessionHandle, error) {
    33  	var slot uint = 0
    34  	logger.Debugf("Loading pkcs11 library [%s]\n", lib)
    35  	if lib == "" {
    36  		return nil, slot, nil, fmt.Errorf("No PKCS11 library default")
    37  	}
    38  
    39  	ctx := pkcs11.New(lib)
    40  	if ctx == nil {
    41  		return nil, slot, nil, fmt.Errorf("Instantiate failed [%s]", lib)
    42  	}
    43  
    44  	ctx.Initialize()
    45  	slots, err := ctx.GetSlotList(true)
    46  	if err != nil {
    47  		return nil, slot, nil, fmt.Errorf("Could not get Slot List [%s]", err)
    48  	}
    49  	found := false
    50  	for _, s := range slots {
    51  		info, err := ctx.GetTokenInfo(s)
    52  		if err != nil {
    53  			continue
    54  		}
    55  		logger.Debugf("Looking for %s, found label %s\n", label, info.Label)
    56  		if label == info.Label {
    57  			found = true
    58  			slot = s
    59  			break
    60  		}
    61  	}
    62  	if !found {
    63  		return nil, slot, nil, fmt.Errorf("Could not find token with label %s", label)
    64  	}
    65  
    66  	var session pkcs11.SessionHandle
    67  	for i := 0; i < 10; i++ {
    68  		session, err = ctx.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
    69  		if err != nil {
    70  			logger.Warningf("OpenSession failed, retrying [%s]\n", err)
    71  		} else {
    72  			break
    73  		}
    74  	}
    75  	if err != nil {
    76  		logger.Fatalf("OpenSession [%s]\n", err)
    77  	}
    78  	logger.Debugf("Created new pkcs11 session %+v on slot %d\n", session, slot)
    79  
    80  	if pin == "" {
    81  		return nil, slot, nil, fmt.Errorf("No PIN set\n")
    82  	}
    83  	err = ctx.Login(session, pkcs11.CKU_USER, pin)
    84  	if err != nil {
    85  		if err != pkcs11.Error(pkcs11.CKR_USER_ALREADY_LOGGED_IN) {
    86  			return nil, slot, nil, fmt.Errorf("Login failed [%s]\n", err)
    87  		}
    88  	}
    89  
    90  	return ctx, slot, &session, nil
    91  }
    92  
    93  func (csp *impl) getSession() (session pkcs11.SessionHandle) {
    94  	select {
    95  	case session = <-csp.sessions:
    96  		logger.Debugf("Reusing existing pkcs11 session %+v on slot %d\n", session, csp.slot)
    97  
    98  	default:
    99  		// cache is empty (or completely in use), create a new session
   100  		var s pkcs11.SessionHandle
   101  		var err error = nil
   102  		for i := 0; i < 10; i++ {
   103  			s, err = csp.ctx.OpenSession(csp.slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
   104  			if err != nil {
   105  				logger.Warningf("OpenSession failed, retrying [%s]\n", err)
   106  			} else {
   107  				break
   108  			}
   109  		}
   110  		if err != nil {
   111  			panic(fmt.Errorf("OpenSession failed [%s]\n", err))
   112  		}
   113  		logger.Debugf("Created new pkcs11 session %+v on slot %d\n", s, csp.slot)
   114  		session = s
   115  	}
   116  	return session
   117  }
   118  
   119  func (csp *impl) returnSession(session pkcs11.SessionHandle) {
   120  	select {
   121  	case csp.sessions <- session:
   122  		// returned session back to session cache
   123  	default:
   124  		// have plenty of sessions in cache, dropping
   125  		csp.ctx.CloseSession(session)
   126  	}
   127  }
   128  
   129  // Look for an EC key by SKI, stored in CKA_ID
   130  // This function can probably be addapted for both EC and RSA keys.
   131  func (csp *impl) getECKey(ski []byte) (pubKey *ecdsa.PublicKey, isPriv bool, err error) {
   132  	p11lib := csp.ctx
   133  	session := csp.getSession()
   134  	defer csp.returnSession(session)
   135  	isPriv = true
   136  	_, err = findKeyPairFromSKI(p11lib, session, ski, privateKeyFlag)
   137  	if err != nil {
   138  		isPriv = false
   139  		logger.Debugf("Private key not found [%s] for SKI [%s], looking for Public key", err, hex.EncodeToString(ski))
   140  	}
   141  
   142  	publicKey, err := findKeyPairFromSKI(p11lib, session, ski, publicKeyFlag)
   143  	if err != nil {
   144  		return nil, false, fmt.Errorf("Public key not found [%s] for SKI [%s]", err, hex.EncodeToString(ski))
   145  	}
   146  
   147  	ecpt, marshaledOid, err := ecPoint(p11lib, session, *publicKey)
   148  	if err != nil {
   149  		return nil, false, fmt.Errorf("Public key not found [%s] for SKI [%s]", err, hex.EncodeToString(ski))
   150  	}
   151  
   152  	curveOid := new(asn1.ObjectIdentifier)
   153  	_, err = asn1.Unmarshal(marshaledOid, curveOid)
   154  	if err != nil {
   155  		return nil, false, fmt.Errorf("Failed Unmarshaling Curve OID [%s]\n%s", err.Error(), hex.EncodeToString(marshaledOid))
   156  	}
   157  
   158  	curve := namedCurveFromOID(*curveOid)
   159  	if curve == nil {
   160  		return nil, false, fmt.Errorf("Cound not recognize Curve from OID")
   161  	}
   162  	x, y := elliptic.Unmarshal(curve, ecpt)
   163  	if x == nil {
   164  		return nil, false, fmt.Errorf("Failed Unmarshaling Public Key")
   165  	}
   166  
   167  	pubKey = &ecdsa.PublicKey{Curve: curve, X: x, Y: y}
   168  	return pubKey, isPriv, nil
   169  }
   170  
   171  // RFC 5480, 2.1.1.1. Named Curve
   172  //
   173  // secp224r1 OBJECT IDENTIFIER ::= {
   174  //   iso(1) identified-organization(3) certicom(132) curve(0) 33 }
   175  //
   176  // secp256r1 OBJECT IDENTIFIER ::= {
   177  //   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
   178  //   prime(1) 7 }
   179  //
   180  // secp384r1 OBJECT IDENTIFIER ::= {
   181  //   iso(1) identified-organization(3) certicom(132) curve(0) 34 }
   182  //
   183  // secp521r1 OBJECT IDENTIFIER ::= {
   184  //   iso(1) identified-organization(3) certicom(132) curve(0) 35 }
   185  //
   186  var (
   187  	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
   188  	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
   189  	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
   190  	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
   191  )
   192  
   193  func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
   194  	switch {
   195  	case oid.Equal(oidNamedCurveP224):
   196  		return elliptic.P224()
   197  	case oid.Equal(oidNamedCurveP256):
   198  		return elliptic.P256()
   199  	case oid.Equal(oidNamedCurveP384):
   200  		return elliptic.P384()
   201  	case oid.Equal(oidNamedCurveP521):
   202  		return elliptic.P521()
   203  	}
   204  	return nil
   205  }
   206  
   207  func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
   208  	switch curve {
   209  	case elliptic.P224():
   210  		return oidNamedCurveP224, true
   211  	case elliptic.P256():
   212  		return oidNamedCurveP256, true
   213  	case elliptic.P384():
   214  		return oidNamedCurveP384, true
   215  	case elliptic.P521():
   216  		return oidNamedCurveP521, true
   217  	}
   218  
   219  	return nil, false
   220  }
   221  
   222  func (csp *impl) generateECKey(curve asn1.ObjectIdentifier, ephemeral bool) (ski []byte, pubKey *ecdsa.PublicKey, err error) {
   223  	p11lib := csp.ctx
   224  	session := csp.getSession()
   225  	defer csp.returnSession(session)
   226  
   227  	id := nextIDCtr()
   228  	publabel := fmt.Sprintf("BCPUB%s", id.Text(16))
   229  	prvlabel := fmt.Sprintf("BCPRV%s", id.Text(16))
   230  
   231  	marshaledOID, err := asn1.Marshal(curve)
   232  	if err != nil {
   233  		return nil, nil, fmt.Errorf("Could not marshal OID [%s]", err.Error())
   234  	}
   235  
   236  	pubkey_t := []*pkcs11.Attribute{
   237  		pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC),
   238  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
   239  		pkcs11.NewAttribute(pkcs11.CKA_TOKEN, !ephemeral),
   240  		pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
   241  		pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, marshaledOID),
   242  		pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
   243  
   244  		pkcs11.NewAttribute(pkcs11.CKA_ID, publabel),
   245  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, publabel),
   246  	}
   247  
   248  	prvkey_t := []*pkcs11.Attribute{
   249  		pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC),
   250  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
   251  		pkcs11.NewAttribute(pkcs11.CKA_TOKEN, !ephemeral),
   252  		pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
   253  		pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
   254  
   255  		pkcs11.NewAttribute(pkcs11.CKA_ID, prvlabel),
   256  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, prvlabel),
   257  
   258  		pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, !csp.noPrivImport),
   259  	}
   260  
   261  	pub, prv, err := p11lib.GenerateKeyPair(session,
   262  		[]*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_EC_KEY_PAIR_GEN, nil)},
   263  		pubkey_t, prvkey_t)
   264  
   265  	if err != nil {
   266  		return nil, nil, fmt.Errorf("P11: keypair generate failed [%s]\n", err)
   267  	}
   268  
   269  	ecpt, _, _ := ecPoint(p11lib, session, pub)
   270  	hash := sha256.Sum256(ecpt)
   271  	ski = hash[:]
   272  
   273  	// set CKA_ID of the both keys to SKI(public key)
   274  	setski_t := []*pkcs11.Attribute{
   275  		pkcs11.NewAttribute(pkcs11.CKA_ID, ski),
   276  	}
   277  
   278  	logger.Infof("Generated new P11 key, SKI %x\n", ski)
   279  	err = p11lib.SetAttributeValue(session, pub, setski_t)
   280  	if err != nil {
   281  		return nil, nil, fmt.Errorf("P11: set-ID-to-SKI[public] failed [%s]\n", err)
   282  	}
   283  
   284  	err = p11lib.SetAttributeValue(session, prv, setski_t)
   285  	if err != nil {
   286  		return nil, nil, fmt.Errorf("P11: set-ID-to-SKI[private] failed [%s]\n", err)
   287  	}
   288  
   289  	nistCurve := namedCurveFromOID(curve)
   290  	if curve == nil {
   291  		return nil, nil, fmt.Errorf("Cound not recognize Curve from OID")
   292  	}
   293  	x, y := elliptic.Unmarshal(nistCurve, ecpt)
   294  	if x == nil {
   295  		return nil, nil, fmt.Errorf("Failed Unmarshaling Public Key")
   296  	}
   297  
   298  	pubGoKey := &ecdsa.PublicKey{Curve: nistCurve, X: x, Y: y}
   299  
   300  	if logger.IsEnabledFor(logging.DEBUG) {
   301  		listAttrs(p11lib, session, prv)
   302  		listAttrs(p11lib, session, pub)
   303  	}
   304  
   305  	return ski, pubGoKey, nil
   306  }
   307  
   308  func (csp *impl) signP11ECDSA(ski []byte, msg []byte) (R, S *big.Int, err error) {
   309  	p11lib := csp.ctx
   310  	session := csp.getSession()
   311  	defer csp.returnSession(session)
   312  
   313  	privateKey, err := findKeyPairFromSKI(p11lib, session, ski, privateKeyFlag)
   314  	if err != nil {
   315  		return nil, nil, fmt.Errorf("Private key not found [%s]\n", err)
   316  	}
   317  
   318  	err = p11lib.SignInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil)}, *privateKey)
   319  	if err != nil {
   320  		return nil, nil, fmt.Errorf("Sign-initialize  failed [%s]\n", err)
   321  	}
   322  
   323  	var sig []byte
   324  
   325  	sig, err = p11lib.Sign(session, msg)
   326  	if err != nil {
   327  		return nil, nil, fmt.Errorf("P11: sign failed [%s]\n", err)
   328  	}
   329  
   330  	R = new(big.Int)
   331  	S = new(big.Int)
   332  	R.SetBytes(sig[0 : len(sig)/2])
   333  	S.SetBytes(sig[len(sig)/2:])
   334  
   335  	return R, S, nil
   336  }
   337  
   338  func (csp *impl) verifyP11ECDSA(ski []byte, msg []byte, R, S *big.Int, byteSize int) (valid bool, err error) {
   339  	p11lib := csp.ctx
   340  	session := csp.getSession()
   341  	defer csp.returnSession(session)
   342  
   343  	logger.Debugf("Verify ECDSA\n")
   344  
   345  	publicKey, err := findKeyPairFromSKI(p11lib, session, ski, publicKeyFlag)
   346  	if err != nil {
   347  		return false, fmt.Errorf("Public key not found [%s]\n", err)
   348  	}
   349  
   350  	r := R.Bytes()
   351  	s := S.Bytes()
   352  
   353  	// Pad front of R and S with Zeroes if needed
   354  	sig := make([]byte, 2*byteSize)
   355  	copy(sig[byteSize-len(r):byteSize], r)
   356  	copy(sig[2*byteSize-len(s):], s)
   357  
   358  	err = p11lib.VerifyInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil)},
   359  		*publicKey)
   360  	if err != nil {
   361  		return false, fmt.Errorf("PKCS11: Verify-initialize [%s]\n", err)
   362  	}
   363  	err = p11lib.Verify(session, msg, sig)
   364  	if err == pkcs11.Error(pkcs11.CKR_SIGNATURE_INVALID) {
   365  		return false, nil
   366  	}
   367  	if err != nil {
   368  		return false, fmt.Errorf("PKCS11: Verify failed [%s]\n", err)
   369  	}
   370  
   371  	return true, nil
   372  }
   373  
   374  func (csp *impl) importECKey(curve asn1.ObjectIdentifier, privKey, ecPt []byte, ephemeral bool, keyType bool) (ski []byte, err error) {
   375  	p11lib := csp.ctx
   376  	session := csp.getSession()
   377  	defer csp.returnSession(session)
   378  
   379  	id := nextIDCtr()
   380  
   381  	marshaledOID, err := asn1.Marshal(curve)
   382  	if err != nil {
   383  		return nil, fmt.Errorf("Could not marshal OID [%s]", err.Error())
   384  	}
   385  
   386  	var keyTemplate []*pkcs11.Attribute
   387  	if keyType == publicKeyFlag {
   388  		logger.Debug("Importing Public EC Key")
   389  		publabel := fmt.Sprintf("BCPUB%s", id.Text(16))
   390  
   391  		hash := sha256.Sum256(ecPt)
   392  		ski = hash[:]
   393  
   394  		// Add DER encoding for the CKA_EC_POINT
   395  		ecPt = append([]byte{0x04, byte(len(ecPt))}, ecPt...)
   396  
   397  		keyTemplate = []*pkcs11.Attribute{
   398  			pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC),
   399  			pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
   400  			pkcs11.NewAttribute(pkcs11.CKA_TOKEN, !ephemeral),
   401  			pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
   402  			pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, marshaledOID),
   403  
   404  			pkcs11.NewAttribute(pkcs11.CKA_ID, ski),
   405  			pkcs11.NewAttribute(pkcs11.CKA_LABEL, publabel),
   406  			pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, ecPt),
   407  			pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
   408  		}
   409  	} else { // isPrivateKey
   410  		ski, err = csp.importECKey(curve, nil, ecPt, ephemeral, publicKeyFlag)
   411  		if err != nil {
   412  			return nil, fmt.Errorf("Failed importing private EC Key [%s]\n", err)
   413  		}
   414  
   415  		logger.Debugf("Importing Private EC Key [%d]\n%s\n", len(privKey)*8, hex.Dump(privKey))
   416  		prvlabel := fmt.Sprintf("BCPRV%s", id.Text(16))
   417  		keyTemplate = []*pkcs11.Attribute{
   418  			pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC),
   419  			pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
   420  			pkcs11.NewAttribute(pkcs11.CKA_TOKEN, !ephemeral),
   421  			pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
   422  			pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
   423  			pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, marshaledOID),
   424  
   425  			pkcs11.NewAttribute(pkcs11.CKA_ID, ski),
   426  			pkcs11.NewAttribute(pkcs11.CKA_LABEL, prvlabel),
   427  			pkcs11.NewAttribute(pkcs11.CKR_ATTRIBUTE_SENSITIVE, false),
   428  			pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, true),
   429  			pkcs11.NewAttribute(pkcs11.CKA_VALUE, privKey),
   430  		}
   431  	}
   432  
   433  	keyHandle, err := p11lib.CreateObject(session, keyTemplate)
   434  	if err != nil {
   435  		return nil, fmt.Errorf("P11: keypair generate failed [%s]\n", err)
   436  	}
   437  
   438  	if logger.IsEnabledFor(logging.DEBUG) {
   439  		listAttrs(p11lib, session, keyHandle)
   440  	}
   441  
   442  	return ski, nil
   443  }
   444  
   445  const (
   446  	privateKeyFlag = true
   447  	publicKeyFlag  = false
   448  )
   449  
   450  func findKeyPairFromSKI(mod *pkcs11.Ctx, session pkcs11.SessionHandle, ski []byte, keyType bool) (*pkcs11.ObjectHandle, error) {
   451  	ktype := pkcs11.CKO_PUBLIC_KEY
   452  	if keyType == privateKeyFlag {
   453  		ktype = pkcs11.CKO_PRIVATE_KEY
   454  	}
   455  
   456  	template := []*pkcs11.Attribute{
   457  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, ktype),
   458  		pkcs11.NewAttribute(pkcs11.CKA_ID, ski),
   459  	}
   460  	if err := mod.FindObjectsInit(session, template); err != nil {
   461  		return nil, err
   462  	}
   463  
   464  	// single session instance, assume one hit only
   465  	objs, _, err := mod.FindObjects(session, 1)
   466  	if err != nil {
   467  		return nil, err
   468  	}
   469  	if err = mod.FindObjectsFinal(session); err != nil {
   470  		return nil, err
   471  	}
   472  
   473  	if len(objs) == 0 {
   474  		return nil, fmt.Errorf("Key not found [%s]", hex.Dump(ski))
   475  	}
   476  
   477  	return &objs[0], nil
   478  }
   479  
   480  // Fairly straightforward EC-point query, other than opencryptoki
   481  // mis-reporting length, including the 04 Tag of the field following
   482  // the SPKI in EP11-returned MACed publickeys:
   483  //
   484  // attr type 385/x181, length 66 b  -- SHOULD be 1+64
   485  // EC point:
   486  // 00000000  04 ce 30 31 6d 5a fd d3  53 2d 54 9a 27 54 d8 7c
   487  // 00000010  d9 80 35 91 09 2d 6f 06  5a 8e e3 cb c0 01 b7 c9
   488  // 00000020  13 5d 70 d4 e5 62 f2 1b  10 93 f7 d5 77 41 ba 9d
   489  // 00000030  93 3e 18 3e 00 c6 0a 0e  d2 36 cc 7f be 50 16 ef
   490  // 00000040  06 04
   491  //
   492  // cf. correct field:
   493  //   0  89: SEQUENCE {
   494  //   2  19:   SEQUENCE {
   495  //   4   7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
   496  //  13   8:     OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
   497  //        :     }
   498  //  23  66:   BIT STRING
   499  //        :     04 CE 30 31 6D 5A FD D3 53 2D 54 9A 27 54 D8 7C
   500  //        :     D9 80 35 91 09 2D 6F 06 5A 8E E3 CB C0 01 B7 C9
   501  //        :     13 5D 70 D4 E5 62 F2 1B 10 93 F7 D5 77 41 BA 9D
   502  //        :     93 3E 18 3E 00 C6 0A 0E D2 36 CC 7F BE 50 16 EF
   503  //        :     06
   504  //        :   }
   505  //
   506  // as a short-term workaround, remove the trailing byte if:
   507  //   - receiving an even number of bytes == 2*prime-coordinate +2 bytes
   508  //   - starting byte is 04: uncompressed EC point
   509  //   - trailing byte is 04: assume it belongs to the next OCTET STRING
   510  //
   511  // [mis-parsing encountered with v3.5.1, 2016-10-22]
   512  //
   513  // SoftHSM reports extra two bytes before the uncrompressed point
   514  // 0x04 || <Length*2+1>
   515  //                 VV< Actual start of point
   516  // 00000000  04 41 04 6c c8 57 32 13  02 12 6a 19 23 1d 5a 64  |.A.l.W2...j.#.Zd|
   517  // 00000010  33 0c eb 75 4d e8 99 22  92 35 96 b2 39 58 14 1e  |3..uM..".5..9X..|
   518  // 00000020  19 de ef 32 46 50 68 02  24 62 36 db ed b1 84 7b  |...2FPh.$b6....{|
   519  // 00000030  93 d8 40 c3 d5 a6 b7 38  16 d2 35 0a 53 11 f9 51  |..@....8..5.S..Q|
   520  // 00000040  fc a7 16                                          |...|
   521  func ecPoint(p11lib *pkcs11.Ctx, session pkcs11.SessionHandle, key pkcs11.ObjectHandle) (ecpt, oid []byte, err error) {
   522  	template := []*pkcs11.Attribute{
   523  		pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil),
   524  		pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, nil),
   525  	}
   526  
   527  	attr, err := p11lib.GetAttributeValue(session, key, template)
   528  	if err != nil {
   529  		return nil, nil, fmt.Errorf("PKCS11: get(EC point) [%s]\n", err)
   530  	}
   531  
   532  	for _, a := range attr {
   533  		if a.Type == pkcs11.CKA_EC_POINT {
   534  			logger.Debugf("EC point: attr type %d/0x%x, len %d\n%s\n", a.Type, a.Type, len(a.Value), hex.Dump(a.Value))
   535  
   536  			// workarounds, see above
   537  			if (0 == (len(a.Value) % 2)) &&
   538  				(byte(0x04) == a.Value[0]) &&
   539  				(byte(0x04) == a.Value[len(a.Value)-1]) {
   540  				logger.Debugf("Detected opencryptoki bug, trimming trailing 0x04")
   541  				ecpt = a.Value[0 : len(a.Value)-1] // Trim trailing 0x04
   542  			} else if byte(0x04) == a.Value[0] && byte(0x04) == a.Value[2] {
   543  				logger.Debugf("Detected SoftHSM bug, trimming leading 0x04 0xXX")
   544  				ecpt = a.Value[2:len(a.Value)]
   545  			} else {
   546  				ecpt = a.Value
   547  			}
   548  		} else if a.Type == pkcs11.CKA_EC_PARAMS {
   549  			logger.Debugf("EC point: attr type %d/0x%x, len %d\n%s\n", a.Type, a.Type, len(a.Value), hex.Dump(a.Value))
   550  
   551  			oid = a.Value
   552  		}
   553  	}
   554  	if oid == nil || ecpt == nil {
   555  		return nil, nil, fmt.Errorf("CKA_EC_POINT not found, perhaps not an EC Key?")
   556  	}
   557  
   558  	return ecpt, oid, nil
   559  }
   560  
   561  func listAttrs(p11lib *pkcs11.Ctx, session pkcs11.SessionHandle, obj pkcs11.ObjectHandle) {
   562  	var cktype, ckclass uint
   563  	var ckaid, cklabel []byte
   564  
   565  	if p11lib == nil {
   566  		return
   567  	}
   568  
   569  	template := []*pkcs11.Attribute{
   570  		pkcs11.NewAttribute(pkcs11.CKA_CLASS, ckclass),
   571  		pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, cktype),
   572  		pkcs11.NewAttribute(pkcs11.CKA_ID, ckaid),
   573  		pkcs11.NewAttribute(pkcs11.CKA_LABEL, cklabel),
   574  	}
   575  
   576  	// certain errors are tolerated, if value is missing
   577  	attr, err := p11lib.GetAttributeValue(session, obj, template)
   578  	if err != nil {
   579  		logger.Debugf("P11: get(attrlist) [%s]\n", err)
   580  	}
   581  
   582  	for _, a := range attr {
   583  		// Would be friendlier if the bindings provided a way convert Attribute hex to string
   584  		logger.Debugf("ListAttr: type %d/0x%x, length %d\n%s", a.Type, a.Type, len(a.Value), hex.Dump(a.Value))
   585  	}
   586  }
   587  
   588  func (csp *impl) getSecretValue(ski []byte) []byte {
   589  	p11lib := csp.ctx
   590  	session := csp.getSession()
   591  	defer csp.returnSession(session)
   592  
   593  	keyHandle, err := findKeyPairFromSKI(p11lib, session, ski, privateKeyFlag)
   594  
   595  	var privKey []byte
   596  	template := []*pkcs11.Attribute{
   597  		pkcs11.NewAttribute(pkcs11.CKA_VALUE, privKey),
   598  	}
   599  
   600  	// certain errors are tolerated, if value is missing
   601  	attr, err := p11lib.GetAttributeValue(session, *keyHandle, template)
   602  	if err != nil {
   603  		logger.Warningf("P11: get(attrlist) [%s]\n", err)
   604  	}
   605  
   606  	for _, a := range attr {
   607  		// Would be friendlier if the bindings provided a way convert Attribute hex to string
   608  		logger.Debugf("ListAttr: type %d/0x%x, length %d\n%s", a.Type, a.Type, len(a.Value), hex.Dump(a.Value))
   609  		return a.Value
   610  	}
   611  	logger.Warningf("No Key Value found!", err)
   612  	return nil
   613  }
   614  
   615  var (
   616  	bigone   = new(big.Int).SetInt64(1)
   617  	id_ctr   = new(big.Int)
   618  	id_mutex sync.Mutex
   619  )
   620  
   621  func nextIDCtr() *big.Int {
   622  	id_mutex.Lock()
   623  	id_ctr = new(big.Int).Add(id_ctr, bigone)
   624  	id_mutex.Unlock()
   625  	return id_ctr
   626  }