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 }