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