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