github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/bccsp/pkcs11/pkcs11.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/elliptic" 11 "crypto/sha256" 12 "encoding/asn1" 13 "encoding/hex" 14 "fmt" 15 "github.com/hellobchain/newcryptosm/ecdsa" 16 "math/big" 17 "sync" 18 19 "github.com/miekg/pkcs11" 20 "go.uber.org/zap/zapcore" 21 ) 22 23 func loadLib(lib, pin, label string) (*pkcs11.Ctx, uint, *pkcs11.SessionHandle, error) { 24 var slot uint 25 logger.Debugf("Loading pkcs11 library [%s]\n", lib) 26 if lib == "" { 27 return nil, slot, nil, fmt.Errorf("No PKCS11 library default") 28 } 29 30 ctx := pkcs11.New(lib) 31 if ctx == nil { 32 return nil, slot, nil, fmt.Errorf("Instantiate failed [%s]", lib) 33 } 34 35 ctx.Initialize() 36 slots, err := ctx.GetSlotList(true) 37 if err != nil { 38 return nil, slot, nil, fmt.Errorf("Could not get Slot List [%s]", err) 39 } 40 found := false 41 for _, s := range slots { 42 info, errToken := ctx.GetTokenInfo(s) 43 if errToken != nil { 44 continue 45 } 46 logger.Debugf("Looking for %s, found label %s\n", label, info.Label) 47 if label == info.Label { 48 found = true 49 slot = s 50 break 51 } 52 } 53 if !found { 54 return nil, slot, nil, fmt.Errorf("Could not find token with label %s", label) 55 } 56 57 session := createSession(ctx, slot, pin) 58 59 logger.Debugf("Created new pkcs11 session %+v on slot %d\n", session, slot) 60 61 if pin == "" { 62 return nil, slot, nil, fmt.Errorf("No PIN set") 63 } 64 err = ctx.Login(session, pkcs11.CKU_USER, pin) 65 if err != nil { 66 if err != pkcs11.Error(pkcs11.CKR_USER_ALREADY_LOGGED_IN) { 67 return nil, slot, nil, fmt.Errorf("Login failed [%s]", err) 68 } 69 } 70 71 return ctx, slot, &session, nil 72 } 73 74 func (csp *impl) getSession() (session pkcs11.SessionHandle) { 75 select { 76 case session = <-csp.sessions: 77 _, err := csp.ctx.GetSessionInfo(session) 78 if err != nil { 79 logger.Warningf("Get session info failed [%s], closing existing session and getting a new session\n", err) 80 csp.ctx.CloseSession(session) 81 session = createSession(csp.ctx, csp.slot, csp.pin) 82 } else { 83 logger.Debugf("Reusing existing pkcs11 session %+v on slot %d\n", session, csp.slot) 84 } 85 86 default: 87 // cache is empty (or completely in use), create a new session 88 session = createSession(csp.ctx, csp.slot, csp.pin) 89 } 90 return session 91 } 92 93 func createSession(ctx *pkcs11.Ctx, slot uint, pin string) pkcs11.SessionHandle { 94 var s pkcs11.SessionHandle 95 var err error 96 for i := 0; i < 10; i++ { 97 s, err = ctx.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) 98 if err != nil { 99 logger.Warningf("OpenSession failed, retrying [%s]\n", err) 100 } else { 101 break 102 } 103 } 104 if err != nil { 105 logger.Fatalf("OpenSession failed [%s]", err) 106 } 107 logger.Debugf("Created new pkcs11 session %+v on slot %d\n", s, slot) 108 session := s 109 110 err = ctx.Login(session, pkcs11.CKU_USER, pin) 111 if err != nil { 112 if err != pkcs11.Error(pkcs11.CKR_USER_ALREADY_LOGGED_IN) { 113 logger.Errorf("Login failed [%s]", err) 114 } 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 adapted 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, csp.altId, 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, csp.altId, 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 keylabel := "" 228 updateSKI := false 229 if csp.altId == "" { 230 // Generate using the SKI process and then make keypair immutable according to csp.immutable 231 keylabel = fmt.Sprintf("BCP%s", nextIDCtr().Text(16)) 232 updateSKI = true 233 } else if csp.altId != "" && csp.immutable { 234 // Generate the key pair using AltID process. 235 // No need to worry about immutable since AltID is used with Write-Once HSMs 236 keylabel = csp.altId 237 updateSKI = false 238 } else if csp.altId != "" && !csp.immutable { 239 // Raise an error since AltID is used with Write-Once HSMs 240 // So cannot make support AltID with immutable = false. 241 return nil, nil, fmt.Errorf("Cannot generate a mutable key using AltID.") 242 } 243 244 marshaledOID, err := asn1.Marshal(curve) 245 if err != nil { 246 return nil, nil, fmt.Errorf("Could not marshal OID [%s]", err.Error()) 247 } 248 249 pubkeyT := []*pkcs11.Attribute{ 250 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC), 251 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY), 252 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, !ephemeral), 253 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true), 254 pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, marshaledOID), 255 256 pkcs11.NewAttribute(pkcs11.CKA_ID, []byte(keylabel)), 257 pkcs11.NewAttribute(pkcs11.CKA_LABEL, keylabel), 258 } 259 260 prvkeyT := []*pkcs11.Attribute{ 261 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_EC), 262 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY), 263 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, !ephemeral), 264 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true), 265 pkcs11.NewAttribute(pkcs11.CKA_SIGN, true), 266 267 pkcs11.NewAttribute(pkcs11.CKA_ID, []byte(keylabel)), 268 pkcs11.NewAttribute(pkcs11.CKA_LABEL, keylabel), 269 270 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false), 271 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true), 272 } 273 274 pub, prv, err := p11lib.GenerateKeyPair(session, 275 []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_EC_KEY_PAIR_GEN, nil)}, 276 pubkeyT, prvkeyT) 277 278 if err != nil { 279 return nil, nil, fmt.Errorf("P11: keypair generate failed [%s]", err) 280 } 281 282 ecpt, _, err := ecPoint(p11lib, session, pub) 283 if err != nil { 284 return nil, nil, fmt.Errorf("Error querying EC-point: [%s]", err) 285 } 286 hash := sha256.Sum256(ecpt) 287 ski = hash[:] 288 289 if updateSKI { 290 // set CKA_ID of the both keys to SKI(public key) and CKA_LABEL to hex string of SKI 291 setskiT := []*pkcs11.Attribute{ 292 pkcs11.NewAttribute(pkcs11.CKA_ID, ski), 293 pkcs11.NewAttribute(pkcs11.CKA_LABEL, hex.EncodeToString(ski)), 294 } 295 296 logger.Infof("Generated new P11 key, SKI %x\n", ski) 297 err = p11lib.SetAttributeValue(session, pub, setskiT) 298 if err != nil { 299 return nil, nil, fmt.Errorf("P11: set-ID-to-SKI[public] failed [%s]", err) 300 } 301 302 err = p11lib.SetAttributeValue(session, prv, setskiT) 303 if err != nil { 304 return nil, nil, fmt.Errorf("P11: set-ID-to-SKI[private] failed [%s]", err) 305 } 306 307 //Set CKA_Modifible to false for both public key and private keys 308 if csp.immutable { 309 setCKAModifiable := []*pkcs11.Attribute{ 310 pkcs11.NewAttribute(pkcs11.CKA_MODIFIABLE, false), 311 } 312 313 _, pubCopyerror := p11lib.CopyObject(session, pub, setCKAModifiable) 314 if pubCopyerror != nil { 315 return nil, nil, fmt.Errorf("P11: Public Key copy failed with error [%s] . Please contact your HSM vendor", pubCopyerror) 316 } 317 318 pubKeyDestroyError := p11lib.DestroyObject(session, pub) 319 if pubKeyDestroyError != nil { 320 return nil, nil, fmt.Errorf("P11: Public Key destroy failed with error [%s]. Please contact your HSM vendor", pubCopyerror) 321 } 322 323 _, prvCopyerror := p11lib.CopyObject(session, prv, setCKAModifiable) 324 if prvCopyerror != nil { 325 return nil, nil, fmt.Errorf("P11: Private Key copy failed with error [%s]. Please contact your HSM vendor", prvCopyerror) 326 } 327 prvKeyDestroyError := p11lib.DestroyObject(session, prv) 328 if pubKeyDestroyError != nil { 329 return nil, nil, fmt.Errorf("P11: Private Key destroy failed with error [%s]. Please contact your HSM vendor", prvKeyDestroyError) 330 } 331 } 332 } 333 334 nistCurve := namedCurveFromOID(curve) 335 if curve == nil { 336 return nil, nil, fmt.Errorf("Cound not recognize Curve from OID") 337 } 338 x, y := elliptic.Unmarshal(nistCurve, ecpt) 339 if x == nil { 340 return nil, nil, fmt.Errorf("Failed Unmarshaling Public Key") 341 } 342 343 pubGoKey := &ecdsa.PublicKey{Curve: nistCurve, X: x, Y: y} 344 345 if logger.IsEnabledFor(zapcore.DebugLevel) { 346 listAttrs(p11lib, session, prv) 347 listAttrs(p11lib, session, pub) 348 } 349 350 return ski, pubGoKey, nil 351 } 352 353 func (csp *impl) signP11ECDSA(ski []byte, msg []byte) (R, S *big.Int, err error) { 354 p11lib := csp.ctx 355 session := csp.getSession() 356 defer csp.returnSession(session) 357 358 privateKey, err := findKeyPairFromSKI(p11lib, session, ski, csp.altId, privateKeyFlag) 359 if err != nil { 360 return nil, nil, fmt.Errorf("Private key not found [%s]", err) 361 } 362 363 err = p11lib.SignInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil)}, *privateKey) 364 if err != nil { 365 return nil, nil, fmt.Errorf("Sign-initialize failed [%s]", err) 366 } 367 368 var sig []byte 369 370 sig, err = p11lib.Sign(session, msg) 371 if err != nil { 372 return nil, nil, fmt.Errorf("P11: sign failed [%s]", err) 373 } 374 375 R = new(big.Int) 376 S = new(big.Int) 377 R.SetBytes(sig[0 : len(sig)/2]) 378 S.SetBytes(sig[len(sig)/2:]) 379 380 return R, S, nil 381 } 382 383 func (csp *impl) verifyP11ECDSA(ski []byte, msg []byte, R, S *big.Int, byteSize int) (bool, error) { 384 p11lib := csp.ctx 385 session := csp.getSession() 386 defer csp.returnSession(session) 387 388 logger.Debugf("Verify ECDSA\n") 389 390 publicKey, err := findKeyPairFromSKI(p11lib, session, ski, csp.altId, publicKeyFlag) 391 if err != nil { 392 return false, fmt.Errorf("Public key not found [%s]", err) 393 } 394 395 r := R.Bytes() 396 s := S.Bytes() 397 398 // Pad front of R and S with Zeroes if needed 399 sig := make([]byte, 2*byteSize) 400 copy(sig[byteSize-len(r):byteSize], r) 401 copy(sig[2*byteSize-len(s):], s) 402 403 err = p11lib.VerifyInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_ECDSA, nil)}, 404 *publicKey) 405 if err != nil { 406 return false, fmt.Errorf("PKCS11: Verify-initialize [%s]", err) 407 } 408 err = p11lib.Verify(session, msg, sig) 409 if err == pkcs11.Error(pkcs11.CKR_SIGNATURE_INVALID) { 410 return false, nil 411 } 412 if err != nil { 413 return false, fmt.Errorf("PKCS11: Verify failed [%s]", err) 414 } 415 416 return true, nil 417 } 418 419 const ( 420 privateKeyFlag = true 421 publicKeyFlag = false 422 ) 423 424 func findKeyPairFromSKI(mod *pkcs11.Ctx, session pkcs11.SessionHandle, ski []byte, altID string, keyType bool) (*pkcs11.ObjectHandle, error) { 425 ktype := pkcs11.CKO_PUBLIC_KEY 426 if keyType == privateKeyFlag { 427 ktype = pkcs11.CKO_PRIVATE_KEY 428 } 429 430 keyId := []byte(altID) 431 if altID == "" { 432 keyId = ski 433 } 434 435 template := []*pkcs11.Attribute{ 436 pkcs11.NewAttribute(pkcs11.CKA_CLASS, ktype), 437 pkcs11.NewAttribute(pkcs11.CKA_ID, keyId), 438 } 439 440 if err := mod.FindObjectsInit(session, template); err != nil { 441 return nil, err 442 } 443 444 // single session instance, assume one hit only 445 objs, _, err := mod.FindObjects(session, 1) 446 if err != nil { 447 return nil, err 448 } 449 if err = mod.FindObjectsFinal(session); err != nil { 450 return nil, err 451 } 452 453 if len(objs) == 0 { 454 return nil, fmt.Errorf("Key not found [%s]", hex.Dump(ski)) 455 } 456 457 return &objs[0], nil 458 } 459 460 // Fairly straightforward EC-point query, other than opencryptoki 461 // mis-reporting length, including the 04 Tag of the field following 462 // the SPKI in EP11-returned MACed publickeys: 463 // 464 // attr type 385/x181, length 66 b -- SHOULD be 1+64 465 // EC point: 466 // 00000000 04 ce 30 31 6d 5a fd d3 53 2d 54 9a 27 54 d8 7c 467 // 00000010 d9 80 35 91 09 2d 6f 06 5a 8e e3 cb c0 01 b7 c9 468 // 00000020 13 5d 70 d4 e5 62 f2 1b 10 93 f7 d5 77 41 ba 9d 469 // 00000030 93 3e 18 3e 00 c6 0a 0e d2 36 cc 7f be 50 16 ef 470 // 00000040 06 04 471 // 472 // cf. correct field: 473 // 0 89: SEQUENCE { 474 // 2 19: SEQUENCE { 475 // 4 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) 476 // 13 8: OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7) 477 // : } 478 // 23 66: BIT STRING 479 // : 04 CE 30 31 6D 5A FD D3 53 2D 54 9A 27 54 D8 7C 480 // : D9 80 35 91 09 2D 6F 06 5A 8E E3 CB C0 01 B7 C9 481 // : 13 5D 70 D4 E5 62 F2 1B 10 93 F7 D5 77 41 BA 9D 482 // : 93 3E 18 3E 00 C6 0A 0E D2 36 CC 7F BE 50 16 EF 483 // : 06 484 // : } 485 // 486 // as a short-term workaround, remove the trailing byte if: 487 // - receiving an even number of bytes == 2*prime-coordinate +2 bytes 488 // - starting byte is 04: uncompressed EC point 489 // - trailing byte is 04: assume it belongs to the next OCTET STRING 490 // 491 // [mis-parsing encountered with v3.5.1, 2016-10-22] 492 // 493 // SoftHSM reports extra two bytes before the uncompressed point 494 // 0x04 || <Length*2+1> 495 // VV< Actual start of point 496 // 00000000 04 41 04 6c c8 57 32 13 02 12 6a 19 23 1d 5a 64 |.A.l.W2...j.#.Zd| 497 // 00000010 33 0c eb 75 4d e8 99 22 92 35 96 b2 39 58 14 1e |3..uM..".5..9X..| 498 // 00000020 19 de ef 32 46 50 68 02 24 62 36 db ed b1 84 7b |...2FPh.$b6....{| 499 // 00000030 93 d8 40 c3 d5 a6 b7 38 16 d2 35 0a 53 11 f9 51 |..@....8..5.S..Q| 500 // 00000040 fc a7 16 |...| 501 func ecPoint(p11lib *pkcs11.Ctx, session pkcs11.SessionHandle, key pkcs11.ObjectHandle) (ecpt, oid []byte, err error) { 502 template := []*pkcs11.Attribute{ 503 pkcs11.NewAttribute(pkcs11.CKA_EC_POINT, nil), 504 pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, nil), 505 } 506 507 attr, err := p11lib.GetAttributeValue(session, key, template) 508 if err != nil { 509 return nil, nil, fmt.Errorf("PKCS11: get(EC point) [%s]", err) 510 } 511 512 for _, a := range attr { 513 if a.Type == pkcs11.CKA_EC_POINT { 514 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)) 515 516 // workarounds, see above 517 if (0 == (len(a.Value) % 2)) && 518 (byte(0x04) == a.Value[0]) && 519 (byte(0x04) == a.Value[len(a.Value)-1]) { 520 logger.Debugf("Detected opencryptoki bug, trimming trailing 0x04") 521 ecpt = a.Value[0 : len(a.Value)-1] // Trim trailing 0x04 522 } else if byte(0x04) == a.Value[0] && byte(0x04) == a.Value[2] { 523 logger.Debugf("Detected SoftHSM bug, trimming leading 0x04 0xXX") 524 ecpt = a.Value[2:len(a.Value)] 525 } else { 526 ecpt = a.Value 527 } 528 } else if a.Type == pkcs11.CKA_EC_PARAMS { 529 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)) 530 531 oid = a.Value 532 } 533 } 534 if oid == nil || ecpt == nil { 535 return nil, nil, fmt.Errorf("CKA_EC_POINT not found, perhaps not an EC Key?") 536 } 537 538 return ecpt, oid, nil 539 } 540 541 func listAttrs(p11lib *pkcs11.Ctx, session pkcs11.SessionHandle, obj pkcs11.ObjectHandle) { 542 var cktype, ckclass uint 543 var ckaid, cklabel []byte 544 545 if p11lib == nil { 546 return 547 } 548 549 template := []*pkcs11.Attribute{ 550 pkcs11.NewAttribute(pkcs11.CKA_CLASS, ckclass), 551 pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, cktype), 552 pkcs11.NewAttribute(pkcs11.CKA_ID, ckaid), 553 pkcs11.NewAttribute(pkcs11.CKA_LABEL, cklabel), 554 } 555 556 // certain errors are tolerated, if value is missing 557 attr, err := p11lib.GetAttributeValue(session, obj, template) 558 if err != nil { 559 logger.Debugf("P11: get(attrlist) [%s]\n", err) 560 } 561 562 for _, a := range attr { 563 // Would be friendlier if the bindings provided a way convert Attribute hex to string 564 logger.Debugf("ListAttr: type %d/0x%x, length %d\n%s", a.Type, a.Type, len(a.Value), hex.Dump(a.Value)) 565 } 566 } 567 568 func (csp *impl) getSecretValue(ski []byte) []byte { 569 p11lib := csp.ctx 570 session := csp.getSession() 571 defer csp.returnSession(session) 572 573 keyHandle, err := findKeyPairFromSKI(p11lib, session, ski, csp.altId, privateKeyFlag) 574 if err != nil { 575 logger.Warningf("P11: findKeyPairFromSKI [%s]\n", err) 576 } 577 var privKey []byte 578 template := []*pkcs11.Attribute{ 579 pkcs11.NewAttribute(pkcs11.CKA_VALUE, privKey), 580 } 581 582 // certain errors are tolerated, if value is missing 583 attr, err := p11lib.GetAttributeValue(session, *keyHandle, template) 584 if err != nil { 585 logger.Warningf("P11: get(attrlist) [%s]\n", err) 586 } 587 588 for _, a := range attr { 589 // Would be friendlier if the bindings provided a way convert Attribute hex to string 590 logger.Debugf("ListAttr: type %d/0x%x, length %d\n%s", a.Type, a.Type, len(a.Value), hex.Dump(a.Value)) 591 return a.Value 592 } 593 logger.Warningf("No Key Value found: %v", err) 594 return nil 595 } 596 597 var ( 598 bigone = new(big.Int).SetInt64(1) 599 idCtr = new(big.Int) 600 idMutex sync.Mutex 601 ) 602 603 func nextIDCtr() *big.Int { 604 idMutex.Lock() 605 idCtr = new(big.Int).Add(idCtr, bigone) 606 idMutex.Unlock() 607 return idCtr 608 }