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