Skip to content

Commit 3bd0dfc

Browse files
committed
Address- Investigate and fix CA installation is failing in exporting the admin certificate at pk12util command in FIPS mode.
https://issues.redhat.com/browse/RHCS-5222 The fix to follow addresses the part of the above issue with respect to how PKI through JSS creates p12 files. This patch modifies the procedure to include higher rated algs for things such as the MAC of the entire PFX and the HMAC and possible algs allowed when creating the encrypted private key info blob to place in the private key safe bag. Currently we support our own version of PK11_ExportEncryptedPrivKeyInfoV2 that , to this point has served two purposes: 1. Allow us to use the new AES key wrap KWP algs. 2. In the case of fips mode, we have added a routine that moves a key between slots when needed, which doesn't currently work in the current nss routine. The fix implements changes that alows the routine to support the various AES_CBC enc algs as well as KWP. KWP is called by the pki kra when creating p12 files, if so configured to do so. Alternatively we have a pkcs12 related comand utility that specifies AES_256_CBC. The fix to JSS simply upgrades some defaults at this point. If we want to get more involved, we could also modify the cmd line tools to be able to specify the algs in question through params.
1 parent 2e9695e commit 3bd0dfc

File tree

3 files changed

+60
-28
lines changed

3 files changed

+60
-28
lines changed

base/src/main/java/org/mozilla/jss/pkcs12/PFX.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
import java.io.IOException;
1212
import java.io.InputStream;
1313
import java.io.OutputStream;
14+
1415
import java.security.DigestException;
16+
import java.security.NoSuchAlgorithmException;
1517

1618
import org.mozilla.jss.CryptoManager;
1719
import org.mozilla.jss.NotInitializedException;
@@ -28,10 +30,12 @@
2830
import org.mozilla.jss.asn1.Tag;
2931
import org.mozilla.jss.crypto.JSSSecureRandom;
3032
import org.mozilla.jss.crypto.PBEAlgorithm;
33+
import org.mozilla.jss.crypto.DigestAlgorithm;
3134
import org.mozilla.jss.crypto.TokenException;
3235
import org.mozilla.jss.pkcs7.ContentInfo;
3336
import org.mozilla.jss.pkcs7.DigestInfo;
3437
import org.mozilla.jss.pkix.cert.Certificate;
38+
import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
3539
import org.mozilla.jss.pkix.primitive.Attribute;
3640
import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo;
3741
import org.mozilla.jss.pkix.primitive.PrivateKeyInfo;
@@ -211,11 +215,14 @@ public PFX( AuthenticatedSafes authSafes ) {
211215
*/
212216
public void computeMacData(Password password,
213217
byte[] salt, int iterationCount)
214-
throws NotInitializedException, DigestException,
218+
throws NotInitializedException, DigestException,NoSuchAlgorithmException,
215219
TokenException, CharConversionException
216220
{
221+
222+
//Make this alg the default mac alg.
223+
AlgorithmIdentifier algID = new AlgorithmIdentifier(DigestAlgorithm.SHA256.toOID());
217224
macData = new MacData( password, salt, iterationCount,
218-
ASN1Util.encode(authSafes) );
225+
ASN1Util.encode(authSafes), algID );
219226
}
220227

221228

native/src/main/native/org/mozilla/jss/pkcs11/PK11Store.c

+12-18
Original file line numberDiff line numberDiff line change
@@ -794,28 +794,22 @@ Java_org_mozilla_jss_pkcs11_PK11Store_getEncryptedPrivateKeyInfo(
794794
goto finish;
795795
}
796796

797-
// export the epki
798-
epki = PK11_ExportEncryptedPrivKeyInfo(
799-
slot, algTag, pwItem, privk, iterations, NULL /*wincx*/);
800-
if (epki == NULL) {
801-
//try our own version for the new AES KWP algs.
802-
803-
epki = JSS_ExportEncryptedPrivKeyInfoV2(
797+
// Call our JSS version of the newer V2 version of PK11_ExportEncryptedPrivateKeyInfoV2
798+
epki = JSS_ExportEncryptedPrivKeyInfoV2(
804799
slot,
805-
algTag, /* PBE algorithm to encrypt the key with */
806-
SEC_OID_UNKNOWN, /* Encryption algorithm to Encrypt the key with */
807-
SEC_OID_UNKNOWN, /* Hash algorithm for PRF */
808-
pwItem, /* password for PBE encryption */
809-
privk, /* encrypt this private key */
810-
iterations, /* interations for PBE alg */
811-
NULL);
812-
813-
if(epki == NULL) {
814-
JSS_throwMsgPrErr(
800+
algTag, /* PBE algorithm to encrypt the key with */
801+
SEC_OID_UNKNOWN, /* Encryption algorithm to Encrypt the key with */
802+
SEC_OID_HMAC_SHA256, /* Hash algorithm for PRF, make this upgraded to SHA256, we can make configurable in future. */
803+
pwItem, /* password for PBE encryption */
804+
privk, /* encrypt this private key */
805+
iterations, /* interations for PBE alg */
806+
NULL);
807+
808+
if(epki == NULL) {
809+
JSS_throwMsgPrErr(
815810
env, TOKEN_EXCEPTION, "Failed to export EncryptedPrivateKeyInfo");
816811
goto finish;
817812
}
818-
}
819813

820814
// DER-encode the epki
821815
if (SEC_ASN1EncodeItem(NULL, &epkiItem, epki,

native/src/main/native/org/mozilla/jss/util/jssutil.c

+39-8
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,9 @@ JSS_ExportEncryptedPrivKeyInfoV2(
945945
SECKEYEncryptedPrivateKeyInfo *epki = NULL;
946946
PLArenaPool *arena = NULL;
947947
SECAlgorithmID *algid;
948-
SECOidTag pbeAlgTag = SEC_OID_UNKNOWN;
948+
// Make this alg set to what the routine sec_pkcs5CreateAlgorithmID sets it to.
949+
// From here we can't get to this lower level routine, using PK11_CreatePBEV2AlgorithmID.
950+
SECOidTag pbeAlgTag = SEC_OID_PKCS5_PBKDF2;
949951
SECItem *crypto_param = NULL;
950952
PK11SymKey *key = NULL;
951953
PK11SymKey *finalKey = NULL;
@@ -955,7 +957,6 @@ JSS_ExportEncryptedPrivKeyInfoV2(
955957
CK_MECHANISM_TYPE pbeMechType;
956958
CK_MECHANISM_TYPE cryptoMechType;
957959
CK_MECHANISM cryptoMech;
958-
SECItem *iv = NULL;
959960

960961
if (!pwitem || !pk) {
961962
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -964,6 +965,7 @@ JSS_ExportEncryptedPrivKeyInfoV2(
964965

965966
algid = PK11_CreatePBEV2AlgorithmID(pbeAlg, encAlg, prfAlg,
966967
0,iteration , NULL);
968+
967969
if (algid == NULL) {
968970
return NULL;
969971
}
@@ -986,6 +988,7 @@ JSS_ExportEncryptedPrivKeyInfoV2(
986988
* pbe key gen, generate the key in the private key slot so we don't have
987989
* to move it later */
988990
pbeMechType = PK11_AlgtagToMechanism(pbeAlgTag);
991+
989992
if (slot != pk->pkcs11Slot) {
990993
if (PK11_DoesMechanism(pk->pkcs11Slot, pbeMechType)) {
991994
slot = pk->pkcs11Slot;
@@ -1000,12 +1003,14 @@ JSS_ExportEncryptedPrivKeyInfoV2(
10001003
}
10011004

10021005
cryptoMechType = PK11_GetPBECryptoMechanism(algid, &crypto_param, pwitem);
1006+
10031007
if (cryptoMechType == CKM_INVALID_MECHANISM) {
10041008
rv = SECFailure;
10051009
goto loser;
10061010
}
10071011

10081012
cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMechType);
1013+
10091014
cryptoMech.pParameter = crypto_param ? crypto_param->data : NULL;
10101015
cryptoMech.ulParameterLen = crypto_param ? crypto_param->len : 0;
10111016

@@ -1050,26 +1055,52 @@ JSS_ExportEncryptedPrivKeyInfoV2(
10501055
* pkcs8/pkcs5.
10511056
*/
10521057

1053-
/* Allocate a large buffer to make sure we can fit the wrapped key */
1054-
encBufLen = 16384;
1058+
encBufLen = 0;
1059+
1060+
epki->encryptedData.data = NULL;
1061+
epki->encryptedData.len = 0; // Just get the len we need
1062+
1063+
// Modify behavior for KWP since NULL is not returned for crypto_param
1064+
// from PK11_GetPBECryptoMechanism. It returns some default 8 byte iv, which is incorrect.
1065+
int isKeyWrapKWP = 0;
1066+
if(cryptoMech.mechanism == CKM_AES_KEY_WRAP_KWP) {
1067+
isKeyWrapKWP = 1;
1068+
}
1069+
1070+
//First call to get get the size.
1071+
crv = PK11_WrapPrivKey(pk->pkcs11Slot, finalKey,
1072+
pk, cryptoMech.mechanism,
1073+
isKeyWrapKWP ? NULL : crypto_param, &epki->encryptedData, NULL);
10551074

1075+
if (crv != CKR_OK) {
1076+
rv = SECFailure;
1077+
goto loser;
1078+
}
1079+
1080+
// If KWP increase buffer size by 8
1081+
// The size value from the first PK11_WrapPrivKey does not account for AES_BLOCK_SIZE
1082+
1083+
if(isKeyWrapKWP) {
1084+
epki->encryptedData.len += 8;
1085+
}
1086+
1087+
encBufLen = epki->encryptedData.len;
10561088
epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen);
1089+
10571090
if (!epki->encryptedData.data) {
10581091
rv = SECFailure;
10591092
goto loser;
10601093
}
1061-
epki->encryptedData.len = (unsigned int)encBufLen;
10621094

10631095
if (!epki->encryptedData.len) {
10641096
rv = SECFailure;
10651097
goto loser;
10661098
}
10671099

10681100
crv = PK11_WrapPrivKey(pk->pkcs11Slot, finalKey,
1069-
pk, cryptoMechType,
1070-
iv, &epki->encryptedData, NULL);
1101+
pk, cryptoMech.mechanism,
1102+
isKeyWrapKWP ? NULL : crypto_param, &epki->encryptedData, NULL);
10711103

1072-
/* crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, &cryptoMech, key->objectID, pk->pkcs11ID, NULL, &encBufLen); */
10731104
if (crv != CKR_OK) {
10741105
rv = SECFailure;
10751106
goto loser;

0 commit comments

Comments
 (0)