2929import java .security .KeyFactory ;
3030import java .security .Provider ;
3131import java .security .Security ;
32- import java .security .interfaces .ECPrivateKey ;
32+ import java .security .interfaces .RSAPrivateCrtKey ;
3333import java .security .interfaces .RSAPrivateKey ;
3434import java .util .HashMap ;
3535import java .util .Map ;
4848import static sun .security .pkcs11 .wrapper .PKCS11Constants .*;
4949import static sun .security .pkcs11 .wrapper .PKCS11Exception .*;
5050import sun .security .pkcs11 .wrapper .PKCS11Exception ;
51+ import sun .security .rsa .RSAPrivateCrtKeyImpl ;
52+ import sun .security .rsa .RSAUtil ;
5153import sun .security .rsa .RSAUtil .KeyType ;
5254import sun .security .util .Debug ;
5355import sun .security .util .ECUtil ;
@@ -271,7 +273,8 @@ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attribu
271273 }
272274
273275 static void exportKey (SunPKCS11 sunPKCS11 , long hSession , long hObject ,
274- long keyClass , CK_ATTRIBUTE [] attributes ) throws PKCS11Exception {
276+ long keyClass , long keyType , Map <Long , CK_ATTRIBUTE > sensitiveAttrs )
277+ throws PKCS11Exception {
275278 Token token = sunPKCS11 .getToken ();
276279 if (debug != null ) {
277280 debug .println ("Private or Secret key will be exported in" +
@@ -316,60 +319,12 @@ static void exportKey(SunPKCS11 sunPKCS11, long hSession, long hObject,
316319 exporterKeyLock .unlock ();
317320 }
318321 if (keyClass == CKO_PRIVATE_KEY ) {
319- long keyType = 0L ;
320- for (CK_ATTRIBUTE attr : attributes ) {
321- if (attr .type == CKA_KEY_TYPE ) {
322- keyType = attr .getLong ();
323- }
324- }
325- if (keyType == CKK_RSA ) {
326- RSAPrivateKey rsaKey = sun .security .rsa .RSAPrivateCrtKeyImpl .newKey (
327- sun .security .rsa .RSAUtil .KeyType .RSA ,
328- "PKCS#8" ,
329- plainExportedKey );
330- for (CK_ATTRIBUTE attr : attributes ) {
331- if (attr .type == CKA_MODULUS ) {
332- attr .pValue = rsaKey .getModulus ().toByteArray ();
333- } else if (attr .type == CKA_PRIVATE_EXPONENT ) {
334- attr .pValue = rsaKey .getPrivateExponent ().toByteArray ();
335- }
336- }
337- } else if (keyType == CKK_DSA ) {
338- sun .security .provider .DSAPrivateKey dsaKey =
339- new sun .security .provider .DSAPrivateKey (plainExportedKey );
340- for (CK_ATTRIBUTE attr : attributes ) {
341- if (attr .type == CKA_VALUE ) {
342- attr .pValue = dsaKey .getX ().toByteArray ();
343- } else if (attr .type == CKA_PRIME ) {
344- attr .pValue = dsaKey .getParams ().getP ().toByteArray ();
345- } else if (attr .type == CKA_SUBPRIME ) {
346- attr .pValue = dsaKey .getParams ().getQ ().toByteArray ();
347- } else if (attr .type == CKA_BASE ) {
348- attr .pValue = dsaKey .getParams ().getG ().toByteArray ();
349- }
350- }
351- } else if (keyType == CKK_EC ) {
352- ECPrivateKey ecKey =
353- ECUtil .decodePKCS8ECPrivateKey (plainExportedKey );
354- for (CK_ATTRIBUTE attr : attributes ) {
355- if (attr .type == CKA_VALUE ) {
356- attr .pValue = ecKey .getS ().toByteArray ();
357- } else if (attr .type == CKA_EC_PARAMS ) {
358- attr .pValue = sun .security .util .CurveDB .lookup (
359- ecKey .getParams ()).getEncoded ();
360- }
361- }
362- } else {
363- throw new PKCS11Exception (CKR_GENERAL_ERROR ,
364- " fips key exporter" );
365- }
322+ exportPrivateKey (sensitiveAttrs , keyType , plainExportedKey );
366323 } else if (keyClass == CKO_SECRET_KEY ) {
367- for (CK_ATTRIBUTE attr : attributes ) {
368- if (attr .type == CKA_VALUE ) {
369- attr .pValue = plainExportedKey ;
370- break ;
371- }
372- }
324+ checkAttrs (sensitiveAttrs , "CKO_SECRET_KEY" , CKA_VALUE );
325+ // CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
326+ // size is greater than 0 and no invalid attributes exist
327+ sensitiveAttrs .get (CKA_VALUE ).pValue = plainExportedKey ;
373328 } else {
374329 throw new PKCS11Exception (CKR_GENERAL_ERROR ,
375330 " fips key exporter" );
@@ -385,6 +340,76 @@ static void exportKey(SunPKCS11 sunPKCS11, long hSession, long hObject,
385340 }
386341 }
387342
343+ private static void exportPrivateKey (
344+ Map <Long , CK_ATTRIBUTE > sensitiveAttrs , long keyType ,
345+ byte [] plainExportedKey ) throws Throwable {
346+ if (keyType == CKK_RSA ) {
347+ checkAttrs (sensitiveAttrs , "CKO_PRIVATE_KEY CKK_RSA" ,
348+ CKA_PRIVATE_EXPONENT , CKA_PRIME_1 , CKA_PRIME_2 ,
349+ CKA_EXPONENT_1 , CKA_EXPONENT_2 , CKA_COEFFICIENT );
350+ RSAPrivateKey rsaPKey = RSAPrivateCrtKeyImpl .newKey (
351+ RSAUtil .KeyType .RSA , "PKCS#8" , plainExportedKey
352+ );
353+ CK_ATTRIBUTE attr ;
354+ if ((attr = sensitiveAttrs .get (CKA_PRIVATE_EXPONENT )) != null ) {
355+ attr .pValue = rsaPKey .getPrivateExponent ().toByteArray ();
356+ }
357+ if (rsaPKey instanceof RSAPrivateCrtKey ) {
358+ RSAPrivateCrtKey rsaPCrtKey = (RSAPrivateCrtKey ) rsaPKey ;
359+ if ((attr = sensitiveAttrs .get (CKA_PRIME_1 )) != null ) {
360+ attr .pValue = rsaPCrtKey .getPrimeP ().toByteArray ();
361+ }
362+ if ((attr = sensitiveAttrs .get (CKA_PRIME_2 )) != null ) {
363+ attr .pValue = rsaPCrtKey .getPrimeQ ().toByteArray ();
364+ }
365+ if ((attr = sensitiveAttrs .get (CKA_EXPONENT_1 )) != null ) {
366+ attr .pValue = rsaPCrtKey .getPrimeExponentP ().toByteArray ();
367+ }
368+ if ((attr = sensitiveAttrs .get (CKA_EXPONENT_2 )) != null ) {
369+ attr .pValue = rsaPCrtKey .getPrimeExponentQ ().toByteArray ();
370+ }
371+ if ((attr = sensitiveAttrs .get (CKA_COEFFICIENT )) != null ) {
372+ attr .pValue = rsaPCrtKey .getCrtCoefficient ().toByteArray ();
373+ }
374+ } else {
375+ checkAttrs (sensitiveAttrs , "CKO_PRIVATE_KEY CKK_RSA" ,
376+ CKA_PRIVATE_EXPONENT );
377+ }
378+ } else if (keyType == CKK_DSA ) {
379+ checkAttrs (sensitiveAttrs , "CKO_PRIVATE_KEY CKK_DSA" , CKA_VALUE );
380+ // CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
381+ // size is greater than 0 and no invalid attributes exist
382+ sensitiveAttrs .get (CKA_VALUE ).pValue =
383+ new sun .security .provider .DSAPrivateKey (plainExportedKey )
384+ .getX ().toByteArray ();
385+ } else if (keyType == CKK_EC ) {
386+ checkAttrs (sensitiveAttrs , "CKO_PRIVATE_KEY CKK_EC" , CKA_VALUE );
387+ // CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
388+ // size is greater than 0 and no invalid attributes exist
389+ sensitiveAttrs .get (CKA_VALUE ).pValue =
390+ ECUtil .decodePKCS8ECPrivateKey (plainExportedKey )
391+ .getS ().toByteArray ();
392+ } else {
393+ throw new PKCS11Exception (CKR_GENERAL_ERROR ,
394+ " unsupported CKO_PRIVATE_KEY key type: " + keyType );
395+ }
396+ }
397+
398+ private static void checkAttrs (Map <Long , CK_ATTRIBUTE > sensitiveAttrs ,
399+ String keyName , long ... validAttrs )
400+ throws PKCS11Exception {
401+ int sensitiveAttrsCount = sensitiveAttrs .size ();
402+ if (sensitiveAttrsCount <= validAttrs .length ) {
403+ int validAttrsCount = 0 ;
404+ for (long validAttr : validAttrs ) {
405+ if (sensitiveAttrs .containsKey (validAttr )) validAttrsCount ++;
406+ }
407+ if (validAttrsCount == sensitiveAttrsCount ) return ;
408+ }
409+ throw new PKCS11Exception (CKR_GENERAL_ERROR ,
410+ " invalid attribute types for a " + keyName + " key object" );
411+ }
412+
388413 private static void createImporterKey (Token token ) {
389414 if (debug != null ) {
390415 debug .println ("Generating Importer Key..." );
0 commit comments