338 return new P11PrivateKey |
338 return new P11PrivateKey |
339 (session, keyID, algorithm, keyLength, attributes); |
339 (session, keyID, algorithm, keyLength, attributes); |
340 } else { |
340 } else { |
341 switch (algorithm) { |
341 switch (algorithm) { |
342 case "RSA": |
342 case "RSA": |
343 // XXX better test for RSA CRT keys (single getAttributes() call) |
343 // In order to decide if this is RSA CRT key, we first query |
344 // we need to determine whether this is a CRT key |
344 // and see if all extra CRT attributes are available. |
345 // see if we can obtain the public exponent |
|
346 // this should also be readable for sensitive/extractable keys |
|
347 CK_ATTRIBUTE[] attrs2 = new CK_ATTRIBUTE[] { |
345 CK_ATTRIBUTE[] attrs2 = new CK_ATTRIBUTE[] { |
348 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), |
346 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), |
|
347 new CK_ATTRIBUTE(CKA_PRIME_1), |
|
348 new CK_ATTRIBUTE(CKA_PRIME_2), |
|
349 new CK_ATTRIBUTE(CKA_EXPONENT_1), |
|
350 new CK_ATTRIBUTE(CKA_EXPONENT_2), |
|
351 new CK_ATTRIBUTE(CKA_COEFFICIENT), |
349 }; |
352 }; |
350 boolean crtKey; |
353 boolean crtKey; |
351 try { |
354 try { |
352 session.token.p11.C_GetAttributeValue |
355 session.token.p11.C_GetAttributeValue |
353 (session.id(), keyID, attrs2); |
356 (session.id(), keyID, attrs2); |
354 crtKey = (attrs2[0].pValue instanceof byte[]); |
357 crtKey = ((attrs2[0].pValue instanceof byte[]) && |
|
358 (attrs2[1].pValue instanceof byte[]) && |
|
359 (attrs2[2].pValue instanceof byte[]) && |
|
360 (attrs2[3].pValue instanceof byte[]) && |
|
361 (attrs2[4].pValue instanceof byte[]) && |
|
362 (attrs2[5].pValue instanceof byte[])) ; |
355 } catch (PKCS11Exception e) { |
363 } catch (PKCS11Exception e) { |
356 // ignore, assume not available |
364 // ignore, assume not available |
357 crtKey = false; |
365 crtKey = false; |
358 } |
366 } |
359 if (crtKey) { |
367 if (crtKey) { |
360 return new P11RSAPrivateKey |
368 return new P11RSAPrivateKey |
361 (session, keyID, algorithm, keyLength, attributes); |
369 (session, keyID, algorithm, keyLength, attributes, attrs2); |
362 } else { |
370 } else { |
363 return new P11RSAPrivateNonCRTKey |
371 return new P11RSAPrivateNonCRTKey |
364 (session, keyID, algorithm, keyLength, attributes); |
372 (session, keyID, algorithm, keyLength, attributes); |
365 } |
373 } |
366 case "DSA": |
374 case "DSA": |
473 private static final long serialVersionUID = 9215872438913515220L; |
481 private static final long serialVersionUID = 9215872438913515220L; |
474 |
482 |
475 private BigInteger n, e, d, p, q, pe, qe, coeff; |
483 private BigInteger n, e, d, p, q, pe, qe, coeff; |
476 private byte[] encoded; |
484 private byte[] encoded; |
477 P11RSAPrivateKey(Session session, long keyID, String algorithm, |
485 P11RSAPrivateKey(Session session, long keyID, String algorithm, |
478 int keyLength, CK_ATTRIBUTE[] attributes) { |
486 int keyLength, CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE[] crtAttrs) { |
479 super(PRIVATE, session, keyID, algorithm, keyLength, attributes); |
487 super(PRIVATE, session, keyID, algorithm, keyLength, attrs); |
|
488 |
|
489 for (CK_ATTRIBUTE a : crtAttrs) { |
|
490 if (a.type == CKA_PUBLIC_EXPONENT) { |
|
491 e = a.getBigInteger(); |
|
492 } else if (a.type == CKA_PRIME_1) { |
|
493 p = a.getBigInteger(); |
|
494 } else if (a.type == CKA_PRIME_2) { |
|
495 q = a.getBigInteger(); |
|
496 } else if (a.type == CKA_EXPONENT_1) { |
|
497 pe = a.getBigInteger(); |
|
498 } else if (a.type == CKA_EXPONENT_2) { |
|
499 qe = a.getBigInteger(); |
|
500 } else if (a.type == CKA_COEFFICIENT) { |
|
501 coeff = a.getBigInteger(); |
|
502 } |
|
503 } |
480 } |
504 } |
481 private synchronized void fetchValues() { |
505 private synchronized void fetchValues() { |
482 token.ensureValid(); |
506 token.ensureValid(); |
483 if (n != null) { |
507 if (n != null) { |
484 return; |
508 return; |
485 } |
509 } |
486 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { |
510 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { |
487 new CK_ATTRIBUTE(CKA_MODULUS), |
511 new CK_ATTRIBUTE(CKA_MODULUS), |
488 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), |
|
489 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), |
512 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), |
490 new CK_ATTRIBUTE(CKA_PRIME_1), |
|
491 new CK_ATTRIBUTE(CKA_PRIME_2), |
|
492 new CK_ATTRIBUTE(CKA_EXPONENT_1), |
|
493 new CK_ATTRIBUTE(CKA_EXPONENT_2), |
|
494 new CK_ATTRIBUTE(CKA_COEFFICIENT), |
|
495 }; |
513 }; |
496 fetchAttributes(attributes); |
514 fetchAttributes(attributes); |
497 n = attributes[0].getBigInteger(); |
515 n = attributes[0].getBigInteger(); |
498 e = attributes[1].getBigInteger(); |
516 d = attributes[1].getBigInteger(); |
499 d = attributes[2].getBigInteger(); |
517 } |
500 p = attributes[3].getBigInteger(); |
518 |
501 q = attributes[4].getBigInteger(); |
|
502 pe = attributes[5].getBigInteger(); |
|
503 qe = attributes[6].getBigInteger(); |
|
504 coeff = attributes[7].getBigInteger(); |
|
505 } |
|
506 public String getFormat() { |
519 public String getFormat() { |
507 token.ensureValid(); |
520 token.ensureValid(); |
508 return "PKCS#8"; |
521 return "PKCS#8"; |
509 } |
522 } |
510 synchronized byte[] getEncodedInternal() { |
523 synchronized byte[] getEncodedInternal() { |
527 public BigInteger getModulus() { |
540 public BigInteger getModulus() { |
528 fetchValues(); |
541 fetchValues(); |
529 return n; |
542 return n; |
530 } |
543 } |
531 public BigInteger getPublicExponent() { |
544 public BigInteger getPublicExponent() { |
532 fetchValues(); |
|
533 return e; |
545 return e; |
534 } |
546 } |
535 public BigInteger getPrivateExponent() { |
547 public BigInteger getPrivateExponent() { |
536 fetchValues(); |
548 fetchValues(); |
537 return d; |
549 return d; |
538 } |
550 } |
539 public BigInteger getPrimeP() { |
551 public BigInteger getPrimeP() { |
540 fetchValues(); |
|
541 return p; |
552 return p; |
542 } |
553 } |
543 public BigInteger getPrimeQ() { |
554 public BigInteger getPrimeQ() { |
544 fetchValues(); |
|
545 return q; |
555 return q; |
546 } |
556 } |
547 public BigInteger getPrimeExponentP() { |
557 public BigInteger getPrimeExponentP() { |
548 fetchValues(); |
|
549 return pe; |
558 return pe; |
550 } |
559 } |
551 public BigInteger getPrimeExponentQ() { |
560 public BigInteger getPrimeExponentQ() { |
552 fetchValues(); |
|
553 return qe; |
561 return qe; |
554 } |
562 } |
555 public BigInteger getCrtCoefficient() { |
563 public BigInteger getCrtCoefficient() { |
556 fetchValues(); |
|
557 return coeff; |
564 return coeff; |
558 } |
565 } |
559 } |
566 } |
560 |
567 |
561 // RSA non-CRT private key |
568 // RSA non-CRT private key |