summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmagne <jmagne@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2011-09-16 02:34:02 +0000
committerjmagne <jmagne@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2011-09-16 02:34:02 +0000
commitf232790c48747fa5be3a75fbdfafa7f1a48d50ac (patch)
treed25f433977cd6f0464c51221cdf6d2c9af3d1782
parentb40d1828acdc04a6651697afbb62682dabf04e61 (diff)
downloadpki-f232790c48747fa5be3a75fbdfafa7f1a48d50ac.tar.gz
pki-f232790c48747fa5be3a75fbdfafa7f1a48d50ac.tar.xz
pki-f232790c48747fa5be3a75fbdfafa7f1a48d50ac.zip
Fix bugzilla #730162 - TPS/TKS token enrollment failure in FIPS mode (hsm+NSS) .
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/trunk@2205 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
-rw-r--r--pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java19
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java4
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java59
-rw-r--r--pki/base/symkey/src/com/netscape/symkey/EncryptData.cpp244
-rw-r--r--pki/base/symkey/src/com/netscape/symkey/SessionKey.cpp1608
-rw-r--r--pki/base/symkey/src/com/netscape/symkey/SessionKey.java27
-rw-r--r--pki/base/symkey/src/com/netscape/symkey/SymKey.cpp828
-rw-r--r--pki/base/symkey/src/com/netscape/symkey/SymKey.h12
-rw-r--r--pki/base/tks/shared/conf/CS.cfg.in2
-rw-r--r--pki/base/tps/doc/CS.cfg.in5
-rw-r--r--pki/base/tps/src/engine/RA.cpp241
-rw-r--r--pki/base/tps/src/include/engine/RA.h5
12 files changed, 1906 insertions, 1148 deletions
diff --git a/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java b/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
index 05337bd9..b030759f 100644
--- a/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
+++ b/pki/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
@@ -34,6 +34,8 @@ import com.netscape.certsrv.selftests.*;
import com.netscape.cms.selftests.*;
import java.util.*;
import com.netscape.symkey.*;
+import org.mozilla.jss.crypto.*;
+
//////////////////////
@@ -132,7 +134,7 @@ extends ASelfTest
if (mSessionKey == null) {
mSessionKey = SessionKey.ComputeSessionKey (mToken, mKeyName,
mCardChallenge, mHostChallenge,
- mKeyInfo, mCUID, mMacKey, mUseSoftToken);
+ mKeyInfo, mCUID, mMacKey, mUseSoftToken, null, null);
if (mSessionKey == null || mSessionKey.length != 16) {
mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
@@ -295,23 +297,21 @@ extends ASelfTest
throws ESelfTestException
{
String logMessage = null;
+ String keySet = "defKeySet";
byte[] sessionKey = SessionKey.ComputeSessionKey (mToken, mKeyName,
mCardChallenge, mHostChallenge,
- mKeyInfo, mCUID, mMacKey, mUseSoftToken);
+ mKeyInfo, mCUID, mMacKey, mUseSoftToken, keySet, null);
+
+ // Now we just see if we can successfully generate a session key.
+ // For FIPS compliance, the routine now returns a wrapped key, which can't be extracted and compared.
if (sessionKey == null) {
CMS.debug("TKSKnownSessionKey: generated no session key");
CMS.debug("TKSKnownSessionKey self test FAILED");
logMessage = CMS.getLogMessage ("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
mSelfTestSubsystem.log (logger, logMessage);
throw new ESelfTestException( logMessage );
- } else if (!Arrays.equals(mSessionKey, sessionKey)) {
- CMS.debug("TKSKnownSessionKey: generated invalid session key");
- CMS.debug("TKSKnownSessionKey self test FAILED");
- logMessage = CMS.getLogMessage ("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
- mSelfTestSubsystem.log (logger, logMessage);
- throw new ESelfTestException( logMessage );
- } else {
+ } else {
logMessage = CMS.getLogMessage ("SELFTESTS_TKS_SUCCEEDED", getSelfTestName(), getSelfTestName());
mSelfTestSubsystem.log (logger, logMessage);
CMS.debug("TKSKnownSessionKey self test SUCCEEDED");
@@ -320,4 +320,3 @@ extends ASelfTest
return;
}
}
-
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java
index 842f87b5..1a67cf12 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/CertRequestPanel.java
@@ -623,8 +623,8 @@ public class CertRequestPanel extends WizardPanelBase {
}
if (/*(certchains.length <= 1) &&*/
- (b64chain != null)) {
- CMS.debug("CertRequestPanel: cert might not have contained chain...calling importCertificateChain");
+ (b64chain != null && b64chain.length() != 0)) {
+ CMS.debug("CertRequestPanel: cert might not have contained chain...calling importCertificateChain: " + b64chain);
try {
CryptoUtil.importCertificateChain(
CryptoUtil.normalizeCertAndReq(b64chain));
diff --git a/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java b/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
index 9e0901a2..4cc2654b 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
@@ -61,7 +61,7 @@ import com.netscape.symkey.*;
*/
public class TokenServlet extends CMSServlet {
protected static final String PROP_ENABLED = "enabled";
-
+ protected static final String TRANSPORT_KEY_NAME ="sharedSecret";
private final static String INFO = "TokenServlet";
public static int ERROR = 1;
private ITKSAuthority mTKS = null;
@@ -251,6 +251,7 @@ public class TokenServlet extends CMSServlet {
String auditMessage = null;
String errorMsg = "";
String badParams = "";
+ String transportKeyName = "";
String rCUID = req.getParameter("CUID");
String keySet = req.getParameter("keySet");
@@ -261,7 +262,7 @@ public class TokenServlet extends CMSServlet {
boolean serversideKeygen = false;
byte[] drm_trans_wrapped_desKey = null;
- SymmetricKey desKey = null;
+ PK11SymKey desKey = null;
// PK11SymKey kek_session_key;
PK11SymKey kek_key;
@@ -311,6 +312,14 @@ public class TokenServlet extends CMSServlet {
} catch (EBaseException eee) {
}
+ try {
+ transportKeyName = sconfig.getString("tks.tksSharedSymKeyName",TRANSPORT_KEY_NAME);
+ } catch (EBaseException e) {
+ }
+
+ CMS.debug("TokenServlet: ComputeSessionKey(): tksSharedSymKeyName: " + transportKeyName);
+
+
String rcard_challenge = req.getParameter("card_challenge");
String rhost_challenge = req.getParameter("host_challenge");
String rKeyInfo = req.getParameter("KeyInfo");
@@ -407,7 +416,7 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet about to try ComputeSessionKey selectedToken=" + selectedToken + " keyNickName=" + keyNickName);
session_key = SessionKey.ComputeSessionKey(
selectedToken,keyNickName,card_challenge,
- host_challenge,keyInfo,CUID, macKeyArray, useSoftToken_s);
+ host_challenge,keyInfo,CUID, macKeyArray, useSoftToken_s, keySet, transportKeyName );
if(session_key == null)
{
@@ -419,7 +428,7 @@ public class TokenServlet extends CMSServlet {
byte encKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".auth_key"));
enc_session_key = SessionKey.ComputeEncSessionKey(
selectedToken,keyNickName,card_challenge,
- host_challenge,keyInfo,CUID, encKeyArray, useSoftToken_s);
+ host_challenge,keyInfo,CUID, encKeyArray, useSoftToken_s, keySet);
if(enc_session_key == null)
{
@@ -440,9 +449,13 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet: calling ComputeKekKey");
byte kekKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+
+
kek_key = SessionKey.ComputeKekKey(
selectedToken,keyNickName,card_challenge,
- host_challenge,keyInfo,CUID, kekKeyArray, useSoftToken_s);
+ host_challenge,keyInfo,CUID, kekKeyArray, useSoftToken_s,keySet);
+
+
CMS.debug("TokenServlet: called ComputeKekKey");
if(kek_key == null)
@@ -470,14 +483,14 @@ public class TokenServlet extends CMSServlet {
*/
/*generate it on whichever token the master key is at*/
if (useSoftToken_s.equals("true")) {
- CMS.debug("TokenServlet: key encryption key generated on internal");
+ CMS.debug("TokenServlet: key encryption key generated on internal");
//cfu audit here? sym key gen
- desKey = SessionKey.GenerateSymkey("internal");
+ desKey = SessionKey.GenerateSymkey("internal");
//cfu audit here? sym key gen done
- } else {
- CMS.debug("TokenServlet: key encryption key generated on " + selectedToken);
- desKey = SessionKey.GenerateSymkey(selectedToken);
- }
+ } else {
+ CMS.debug("TokenServlet: key encryption key generated on " + selectedToken);
+ desKey = SessionKey.GenerateSymkey(selectedToken);
+ }
if (desKey != null)
CMS.debug("TokenServlet: key encryption key generated for "+rCUID);
else {
@@ -492,7 +505,7 @@ public class TokenServlet extends CMSServlet {
*/
byte[] encDesKey =
SessionKey.ECBencrypt( kek_key,
- desKey.getKeyData());
+ desKey);
/*
CMS.debug("computeSessionKey:encrypted desKey size = "+encDesKey.length);
CMS.debug(encDesKey);
@@ -503,7 +516,7 @@ public class TokenServlet extends CMSServlet {
// get keycheck
byte[] keycheck =
- SessionKey.ComputeKeyCheck(desKey.getKeyData());
+ SessionKey.ComputeKeyCheck(desKey);
/*
CMS.debug("computeSessionKey:keycheck size = "+keycheck.length);
CMS.debug(keycheck);
@@ -525,11 +538,12 @@ public class TokenServlet extends CMSServlet {
drmTransCert = CryptoManager.getInstance().findCertByNickname(drmTransNickname);
// wrap kek session key with DRM transport public key
CryptoToken token = null;
- if (useSoftToken_s.equals("true")) {
- token = CryptoManager.getInstance().getTokenByName("Internal Key Storage Token");
- } else {
- token = CryptoManager.getInstance().getTokenByName(selectedToken);
- }
+ if (useSoftToken_s.equals("true")) {
+ //token = CryptoManager.getInstance().getTokenByName(selectedToken);
+ token = CryptoManager.getInstance().getInternalCryptoToken();
+ } else {
+ token = CryptoManager.getInstance().getTokenByName(selectedToken);
+ }
PublicKey pubKey = drmTransCert.getPublicKey();
String pubKeyAlgo = pubKey.getAlgorithm();
CMS.debug("Transport Cert Key Algorithm: " + pubKeyAlgo);
@@ -542,6 +556,7 @@ public class TokenServlet extends CMSServlet {
keyWrapper = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
keyWrapper.initWrap(pubKey, null);
}
+ CMS.debug("desKey token " + desKey.getOwningToken().getName() + " token: " + token.getName() );
drm_trans_wrapped_desKey = keyWrapper.wrap(desKey);
CMS.debug("computeSessionKey:desKey wrapped with drm transportation key.");
@@ -550,7 +565,7 @@ public class TokenServlet extends CMSServlet {
byte authKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".auth_key"));
host_cryptogram = SessionKey.ComputeCryptogram(
selectedToken,keyNickName,card_challenge,
- host_challenge,keyInfo,CUID,0, authKeyArray, useSoftToken_s);
+ host_challenge,keyInfo,CUID,0, authKeyArray, useSoftToken_s, keySet);
if(host_cryptogram == null)
{
@@ -560,7 +575,7 @@ public class TokenServlet extends CMSServlet {
}
card_crypto = SessionKey.ComputeCryptogram(
selectedToken,keyNickName,card_challenge,
- host_challenge,keyInfo,CUID,1, authKeyArray, useSoftToken_s);
+ host_challenge,keyInfo,CUID,1, authKeyArray, useSoftToken_s, keySet);
if(card_crypto == null)
{
@@ -880,7 +895,7 @@ public class TokenServlet extends CMSServlet {
byte kekKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
KeySetData = SessionKey.DiversifyKey(oldSelectedToken,
newSelectedToken, oldKeyNickName,
- newKeyNickName,rnewKeyInfo,CUID, kekKeyArray, useSoftToken_s);
+ newKeyNickName,rnewKeyInfo,CUID, kekKeyArray, useSoftToken_s, keySet);
if (KeySetData == null || KeySetData.length<=1) {
CMS.getLogger().log(ILogger.EV_AUDIT,
@@ -1084,7 +1099,7 @@ public class TokenServlet extends CMSServlet {
byte kekKeyArray[] = com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
encryptedData = SessionKey.EncryptData(
- selectedToken,keyNickName,data,keyInfo,CUID, kekKeyArray, useSoftToken_s);
+ selectedToken,keyNickName,data,keyInfo,CUID, kekKeyArray, useSoftToken_s, keySet);
CMS.getLogger().log(ILogger.EV_AUDIT,
ILogger.S_TKS,
diff --git a/pki/base/symkey/src/com/netscape/symkey/EncryptData.cpp b/pki/base/symkey/src/com/netscape/symkey/EncryptData.cpp
index ff9e91df..ccb817f7 100644
--- a/pki/base/symkey/src/com/netscape/symkey/EncryptData.cpp
+++ b/pki/base/symkey/src/com/netscape/symkey/EncryptData.cpp
@@ -41,94 +41,25 @@ extern "C"
PRFileDesc *d = NULL;
-/**
- * Encrypt 'cc_len' bytes of data in 'input' with key kek_key.
- * Result goes into buffer 'output'
- * Returns PR_FAILURE if there was an error
- */
-PRStatus EncryptData(const Buffer &kek_key, jbyte * input,int cc_len, Buffer &output)
+void GetKeyName(jbyte *keyVersion, char *keyname)
{
- PRStatus rv = PR_FAILURE;
-
- PK11SymKey *master = NULL;
- PK11SlotInfo *slot = PK11_GetInternalKeySlot();
- PK11Context *context = NULL;
- int i;
- SECStatus s = SECFailure;
- int len;
- static SECItem noParams = { siBuffer, 0, 0 };
-#ifdef DES2_WORKAROUND
- unsigned char masterKeyData[24];
-#else
- unsigned char masterKeyData[16];
-#endif
- SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
- unsigned char result[8];
-
-// convert 16-byte to 24-byte triple-DES key
- memcpy(masterKeyData, kek_key, 16);
-#ifdef DES2_WORKAROUND
- memcpy(masterKeyData+16, kek_key, 8);
-#endif
-
- master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
- if (master == NULL)
- {
- goto done;
- }
-
- context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
- &noParams);
- if (context == NULL)
- {
- goto done;
- }
-
- for(i = 0;i < (int)cc_len;i += 8)
- {
- s = PK11_CipherOp(context, result, &len, 8,
- (unsigned char *)(input+i), 8);
-
- if (s != SECSuccess)
- {
- goto done;
- }
- output.replace(i, result, 8);
- }
-
- rv = PR_SUCCESS;
+ int index=0;
-done:
- /* memset(masterKeyData, 0, sizeof masterKeyData); */
- if (context != NULL)
- {
- PK11_DestroyContext(context, PR_TRUE);
- context = NULL;
- }
- if (slot != NULL)
- {
- PK11_FreeSlot(slot);
- slot = NULL;
- }
- if (master != NULL)
- {
- PK11_FreeSymKey(master);
- master = NULL;
+ if( !keyname || !keyVersion ||
+ (strlen(keyname) < KEYNAMELENGTH)) {
+ return;
}
- return rv;
-}
-
-void GetKeyName(jbyte *keyVersion, char *keyname)
-{
- int index=0;
if(strlen(masterKeyPrefix)!=0)
{
index= strlen(masterKeyPrefix);
strcpy(keyname,masterKeyPrefix);
}
+
+ if( (index + 3) >= KEYNAMELENGTH) {
+ return;
+ }
+
keyname[index+0]='#';
sprintf(keyname+index+1,"%.2d", keyVersion[0]);
keyname[index+3]='#';
@@ -137,55 +68,112 @@ void GetKeyName(jbyte *keyVersion, char *keyname)
extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_EncryptData
-(JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring);
+(JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
extern "C" JNIEXPORT jbyteArray JNICALL
-Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstring j_tokenName, jstring j_keyName, jbyteArray j_in, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s)
+Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstring j_tokenName, jstring j_keyName, jbyteArray j_in, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s,jstring keySet)
{
- int status = PR_FAILURE;
- jbyte * kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
- jbyte * keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( j_in, NULL);
- int cc_len = (env)->GetArrayLength(j_in);
+ jbyte * kek_key = NULL;
- Buffer kek_buffer = Buffer((BYTE*)kek_key, 16);
- Buffer out = Buffer(16, (BYTE)0);
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *kekKey = NULL;
- /* generate kek key */
- /* identify the masterKey by KeyInfo in TKS */
+ Buffer out = Buffer(KEYLENGTH, (BYTE)0);
BYTE kekData[KEYLENGTH];
char keyname[KEYNAMELENGTH];
- GetDiversificationData(cuidValue,kekData,kek);
+
+ int status = PR_FAILURE;
+
+ jbyte *cc = NULL;
+ int cc_len = 0;
+ jbyte * cuidValue = NULL;
+
+ if( kekKeyArray != NULL) {
+ kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ } else {
+ return NULL;
+ }
PK11SlotInfo *slot = NULL;
- if(j_tokenName != NULL)
- {
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ Buffer kek_buffer = Buffer((BYTE*)kek_key, KEYLENGTH);
+ char *keySetStringChars = NULL;
+ if( keySet != NULL) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ) {
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if( j_in != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( j_in, NULL);
+ cc_len = (env)->GetArrayLength(j_in);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ GetDiversificationData(cuidValue,kekData,kek);
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: EncryptData! \n");
+
+ if(j_tokenName != NULL) {
char *tokenNameChars = (char *)(env)->GetStringUTFChars(j_tokenName, NULL);
slot = ReturnSlot(tokenNameChars);
(env)->ReleaseStringUTFChars(j_tokenName, (const char *)tokenNameChars);
tokenNameChars = NULL;
}
- if(j_keyName != NULL)
- {
+ if(j_keyName != NULL) {
char *keyNameChars= (char *)(env)->GetStringUTFChars(j_keyName, NULL);
strcpy(keyname,keyNameChars);
env->ReleaseStringUTFChars(j_keyName, (const char *)keyNameChars);
keyNameChars = NULL;
}
- else
- {
+ else {
GetKeyName(keyVersion,keyname);
}
- PK11SymKey *masterKey = NULL;
-
- if (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ||
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0) ||
(keyVersion[0] == -1 && strstr(keyname, "#FF") ))
{
/* default development keyset */
- status = EncryptData(kek_buffer, cc, cc_len, out);
+ Buffer devInput = Buffer((BYTE*)cc, cc_len);
+ Buffer empty = Buffer();
+
+ kekKey = ReturnDeveloperSymKey( internal, (char *) "kek", keySetString, empty);
+
+ if ( kekKey ) {
+ status = EncryptData(Buffer(),kekKey,devInput, out);
+ } else {
+ status = EncryptData(kek_buffer, NULL, devInput, out);
+ }
}
else
{
@@ -198,37 +186,45 @@ Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstr
*/
if (masterKey != NULL)
{
- PK11SymKey *kekKey = ComputeCardKeyOnToken(masterKey,kekData);
+ kekKey = ComputeCardKeyOnToken(masterKey,kekData);
if (kekKey != NULL)
{
Buffer input = Buffer((BYTE*)cc, cc_len);
- status = EncryptDataWithCardKey(kekKey, input, out);
-
- if (kekKey != NULL)
- {
- PK11_FreeSymKey( kekKey);
- kekKey = NULL;
- }
+ status = EncryptData(Buffer(), kekKey, input, out);
}
}
}
}
- if (masterKey != NULL)
- {
+done:
+
+ if (masterKey != NULL) {
PK11_FreeSymKey( masterKey);
masterKey = NULL;
}
- if( slot!= NULL )
- {
- PK11_FreeSlot( slot );
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot);
slot = NULL;
}
+ if( internal != NULL) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ if ( kekKey != NULL) {
+ PK11_FreeSymKey( kekKey);
+ kekKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
jbyteArray handleBA=NULL;
- if (status != PR_FAILURE && (out.size()>0) )
- {
+ if (status != PR_FAILURE && (out.size()>0) ) {
jbyte *handleBytes=NULL;
handleBA = (env)->NewByteArray( out.size());
handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
@@ -238,9 +234,17 @@ Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstr
handleBytes=NULL;
}
- env->ReleaseByteArrayElements(j_in, cc, JNI_ABORT);
- env->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
- env->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ if( cc != NULL) {
+ env->ReleaseByteArrayElements(j_in, cc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL) {
+ env->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if( cuidValue != NULL) {
+ env->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
return handleBA;
}
diff --git a/pki/base/symkey/src/com/netscape/symkey/SessionKey.cpp b/pki/base/symkey/src/com/netscape/symkey/SessionKey.cpp
index 735d904c..eb412f01 100644
--- a/pki/base/symkey/src/com/netscape/symkey/SessionKey.cpp
+++ b/pki/base/symkey/src/com/netscape/symkey/SessionKey.cpp
@@ -1,4 +1,4 @@
-// --- BEGIN COPYRIGHT BLOCK ---
+
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
@@ -27,6 +27,7 @@ extern "C"
#include <jni.h>
#include <assert.h>
#include <string.h>
+#include "secerr.h"
/*
#include <jss_exceptions.h>
@@ -66,6 +67,7 @@ extern "C"
#define SYM_KEY_PROXY_FIELD "keyProxy"
#define SYM_KEY_PROXY_SIG "Lorg/mozilla/jss/pkcs11/SymKeyProxy;"
+
/***********************************************************************
**
** J S S _ p t r T o B y t e A r r a y
@@ -298,8 +300,8 @@ JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr)
** }
*/
PRStatus
-JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, const char *proxyFieldName,
-const char *proxyFieldSig, void **ptr)
+JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, char* proxyFieldName,
+char *proxyFieldSig, void **ptr)
{
jclass ownerClass;
jfieldID proxyField;
@@ -343,23 +345,36 @@ JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr)
SYM_KEY_PROXY_SIG, (void**)ptr);
}
#endif //STEAL_JSS
-
-PK11SymKey *DeriveKeyWithCardKey(PK11SymKey *cardkey, const Buffer& hostChallenge, const Buffer& cardChallenge)
+// Function takes wither a symkey OR a keybuffer (for the default keyset case)
+// To derive a new key.
+PK11SymKey *DeriveKey(PK11SymKey *cardKey, const Buffer& hostChallenge, const Buffer& cardChallenge)
{
PK11SymKey *key = NULL, *master = NULL;
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
PK11Context *context = NULL;
- unsigned char derivationData[16];
+ unsigned char derivationData[KEYLENGTH];
#ifdef DES2_WORKAROUND
- unsigned char keyData[24];
+ unsigned char keyData[DES3_LENGTH];
#else
- unsigned char keyData[16];
+ unsigned char keyData[KEYLENGTH];
#endif
- int i;
- SECStatus s;
- int len;
- SECItem keyItem = { siBuffer, keyData, sizeof keyData };
- static SECItem noParams = { siBuffer, 0, 0 };
+ int i = 0;
+ SECStatus s = SECSuccess;
+ int len = 0;;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+
+ /* vars for PK11_Derive section */
+ SECItem param = { siBuffer, NULL, 0 };
+ CK_KEY_DERIVATION_STRING_DATA string;
+ PK11SymKey *tmp1 = NULL;
+ PK11SymKey *tmp2 = NULL;
+ PRBool invalid_mechanism = PR_FALSE;
+ CK_OBJECT_HANDLE keyhandle = 0;
+
+ PR_fprintf(PR_STDOUT,"In DeriveKey! \n");
+ master = cardKey;
+
+ if( ! master ) goto done;
for(i = 0;i < 4;i++)
{
@@ -368,102 +383,101 @@ PK11SymKey *DeriveKeyWithCardKey(PK11SymKey *cardkey, const Buffer& hostChalleng
derivationData[i+8] = cardChallenge[i];
derivationData[i+12] = hostChallenge[i+4];
}
- context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, cardkey,
- &noParams);
- if (!context) goto done;
- /* Part 1 */
- s = PK11_CipherOp(context, &keyData[0], &len, 8, &derivationData[0], 8);
- if (s != SECSuccess) goto done;
+ string.pData = &derivationData[0];
+ string.ulLen = EIGHT_BYTES;
+ param.data = (unsigned char*)&string;
+ param.len = sizeof(string);
- /* Part 2 */
- s = PK11_CipherOp(context, &keyData[8], &len, 8, &derivationData[8], 8);
- if (s != SECSuccess) goto done;
+ invalid_mechanism = PR_FALSE;
-#ifdef DES2_WORKAROUND
- /* Part 3 */
- for(i = 0;i < 8;i++)
- {
- keyData[i+16] = keyData[i];
+ tmp1 = PK11_Derive( master , CKM_DES_ECB_ENCRYPT_DATA , &param , CKM_CONCATENATE_BASE_AND_KEY , CKA_DERIVE, 0);
+
+ if ( tmp1 == NULL) {
+ if ( PR_GetError() == SEC_ERROR_NO_TOKEN)
+ invalid_mechanism = PR_TRUE;
+
+ PR_fprintf(PR_STDERR,"DeriveKey: Can't create key, using encrypt and derive method ! error %d \n", PR_GetError());
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: Successfully created key using encrypt and derive method! \n");
}
-#endif
- key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB, PK11_OriginGenerated,
- CKA_ENCRYPT, &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+ if ( invalid_mechanism == PR_FALSE) {
- done:
- memset(keyData, 0, sizeof keyData);
- if (context) PK11_DestroyContext(context, PR_TRUE);
- if (slot) PK11_FreeSlot(slot);
- if (master) PK11_FreeSymKey(master);
+ string.pData = &derivationData[EIGHT_BYTES];
+ string.ulLen = EIGHT_BYTES;
- return key;
-}
+ tmp2 = PK11_Derive( master , CKM_DES_ECB_ENCRYPT_DATA , &param , CKM_CONCATENATE_BASE_AND_KEY , CKA_DERIVE , 0);
+ if ( tmp2 == NULL) {
+ PR_fprintf(PR_STDERR,"DeriveKey: Can't derive key using CONCATENATE method! \n");
+ goto done;
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: Successfully created key using CONCATENATE method! \n");
+ }
-PK11SymKey *DeriveKey(const Buffer& permKey, const Buffer& hostChallenge, const Buffer& cardChallenge)
-{
- PK11SymKey *key = NULL, *master = NULL;
- PK11SlotInfo *slot = PK11_GetInternalKeySlot();
- PK11Context *context = NULL;
- unsigned char derivationData[16];
-#ifdef DES2_WORKAROUND
- unsigned char keyData[24];
-#else
- unsigned char keyData[16];
-#endif
- int i;
- SECStatus s;
- int len;
- SECItem keyItem = { siBuffer, keyData, sizeof keyData };
- static SECItem noParams = { siBuffer, 0, 0 };
- BYTE masterKeyData[24];
- SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ keyhandle = PK11_GetSymKeyHandle(tmp2);
- /* convert 16-byte to 24-byte triple-DES key */
- memcpy(masterKeyData, permKey, 16);
- memcpy(masterKeyData+16, permKey, 8);
+ param.data=(unsigned char *) &keyhandle;
+ param.len=sizeof(keyhandle);
- master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
- if( ! master ) goto done;
+ key = PK11_Derive ( tmp1 , CKM_CONCATENATE_BASE_AND_KEY , &param ,CKM_DES3_ECB , CKA_DERIVE , 16);
- for(i = 0;i < 4;i++)
- {
- derivationData[i] = cardChallenge[i+4];
- derivationData[i+4] = hostChallenge[i];
- derivationData[i+8] = cardChallenge[i];
- derivationData[i+12] = hostChallenge[i+4];
- }
- context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
- &noParams);
- if (!context) goto done;
+ if ( key == NULL) {
+ PR_fprintf(PR_STDERR,"DeriveKey: Can't create final derived key! \n");
+ goto done;
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: Successfully created final derived key! \n");
+ }
- /* Part 1 */
- s = PK11_CipherOp(context, &keyData[0], &len, 8, &derivationData[0], 8);
- if (s != SECSuccess) goto done;
+ } else { /* We don't have access to the proper derive mechanism, use primitive mechanisms now */
- /* Part 2 */
- s = PK11_CipherOp(context, &keyData[8], &len, 8, &derivationData[8], 8);
- if (s != SECSuccess) goto done;
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
-#ifdef DES2_WORKAROUND
- /* Part 3 */
- for(i = 0;i < 8;i++)
- {
- keyData[i+16] = keyData[i];
- }
-#endif
+ if (!context) goto done;
- key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB, PK11_OriginGenerated,
- CKA_ENCRYPT, &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+ s = PK11_CipherOp(context, &keyData[0], &len, EIGHT_BYTES, &derivationData[0], EIGHT_BYTES);
+ if (s != SECSuccess) goto done;
+
+ s = PK11_CipherOp(context, &keyData[EIGHT_BYTES], &len, 8, &derivationData[EIGHT_BYTES], EIGHT_BYTES);
+ if (s != SECSuccess) goto done;
+
+ for(i = 0;i < EIGHT_BYTES ;i++)
+ {
+ keyData[i+KEYLENGTH] = keyData[i];
+ }
+
+ key = CreateUnWrappedSymKeyOnToken( slot, master, &keyData[0] , DES3_LENGTH, PR_FALSE );
+
+ if ( key == NULL ) {
+ PR_fprintf(PR_STDERR,"DeriveKey: CreateUnWrappedSymKey failed! %d \n", PR_GetError());
+ } else {
+ PR_fprintf(PR_STDOUT,"DeriveKey: CreateUnWrappedSymKey succeeded! \n");
+ }
+ }
done:
memset(keyData, 0, sizeof keyData);
- if (context) PK11_DestroyContext(context, PR_TRUE);
- if (slot) PK11_FreeSlot(slot);
- if (master) PK11_FreeSymKey(master);
+ if ( context != NULL) {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+
+ if (slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if (tmp1) {
+ PK11_FreeSymKey(tmp1);
+ tmp1 = NULL;
+ }
+
+ if (tmp2) {
+ PK11_FreeSymKey(tmp2);
+ tmp2 = NULL;
+ }
return key;
}
@@ -473,84 +487,75 @@ extern "C"
{
#endif
JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeKeyCheck
- (JNIEnv *, jclass, jbyteArray);
+ (JNIEnv *, jclass, jobject deskeyObj);
#ifdef __cplusplus
}
#endif
extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_netscape_symkey_SessionKey_ComputeKeyCheck
-(JNIEnv* env, jclass this2, jbyteArray data)
+(JNIEnv* env, jclass this2, jobject deskeyObj)
{
jbyteArray handleBA=NULL;
- jint len;
- jbyte *bytes=NULL;
jbyte *handleBytes=NULL;
PK11SymKey *key = NULL;
- PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+// PK11SlotInfo *slot = PK11_GetInternalKeySlot();
PK11Context *context = NULL;
SECStatus s = SECFailure;
- int lenx;
- static SECItem noParams = { siBuffer, 0, 0 };
-#ifdef DES2_WORKAROUND
- unsigned char keyData[24];
-#else
- unsigned char keyData[16];
-#endif
- SECItem keyItem = {siBuffer, keyData, sizeof(keyData) };
- unsigned char value[8];
+ PRStatus r = PR_FAILURE;
+ int lenx = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
- len = (env)->GetArrayLength(data);
- bytes = (env)->GetByteArrayElements(data, NULL);
- if( bytes == NULL )
- {
- goto finish;
- }
+ unsigned char value[EIGHT_BYTES];
-/* convert 16-byte to 24-byte triple-DES key */
- memcpy(keyData, bytes, 16);
-#ifdef DES2_WORKAROUND
- memcpy(keyData+16, bytes, 8);
-#endif
memset(value, 0, sizeof value);
- key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &keyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
- if( ! key )
- {
+ r = JSS_PK11_getSymKeyPtr(env, deskeyObj, &key);
+
+ if (r != PR_SUCCESS) {
+ goto finish;
+ }
+
+ if ( ! key ) {
goto finish;
}
context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
&noParams);
- if (!context)
- {
+ if (!context) {
goto finish;
}
- s = PK11_CipherOp(context, &value[0], &lenx, 8, &value[0], 8);
+
+ s = PK11_CipherOp(context, &value[0], &lenx, EIGHT_BYTES, &value[0], EIGHT_BYTES);
if (s != SECSuccess)
{
goto finish;
}
handleBA = (env)->NewByteArray(3);
- if(handleBA == NULL )
- {
+ if(handleBA == NULL ) {
goto finish;
}
handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
- if(handleBytes==NULL)
- {
+ if(handleBytes==NULL) {
goto finish;
}
memcpy(handleBytes, value, 3);
- (env)->ReleaseByteArrayElements(handleBA, handleBytes, 0);
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements(handleBA, handleBytes, 0);
+ }
- finish:
- if (context) PK11_DestroyContext(context, PR_TRUE);
- if (slot) PK11_FreeSlot(slot);
- if (key) PK11_FreeSymKey(key);
+finish:
+
+ if ( context != NULL) {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+
+// if ( slot != NULL) {
+// PK11_FreeSlot(slot);
+// slot = NULL;
+// }
return handleBA;
}
@@ -567,28 +572,132 @@ extern "C"
* Signature: ([B[B[B[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKey
- (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring);
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring, jstring);
#ifdef __cplusplus
}
#endif
#define KEYLENGTH 16
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray macKeyArray, jstring useSoftToken_s)
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray macKeyArray, jstring useSoftToken_s, jstring keySet, jstring sharedSecretKeyName)
{
-/* hardcore permanent mac key */
- jbyte *mac_key = (jbyte*)(env)->GetByteArrayElements(macKeyArray, NULL);
- char input[16];
- int i;
+ /* hardcore permanent mac key */
+ jbyte *mac_key = NULL;
+ if (macKeyArray != NULL) {
+ mac_key = (jbyte*)(env)->GetByteArrayElements(macKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ char input[KEYLENGTH];
+ int i = 0;
+
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0};
+ SECItem noParams = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
+
+
+ char *keyNameChars=NULL;
+ char *tokenNameChars=NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ PK11SymKey *symkey = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ PK11SymKey *macSymKey = NULL;
+ PK11SymKey *symkey16 = NULL;
+ PK11SymKey *macKey = NULL;
+
+
+ BYTE macData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+
+ /* Derive vars */
+
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+
+ /* Java object return vars */
+
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ jbyte * cuidValue = NULL;
+
+ jbyte *cc = NULL;
+ int cc_len = 0;
+
+ int hc_len = 0;
+ jbyte *hc = NULL;
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+
+ Buffer macBuff( ( BYTE *) mac_key , KEYLENGTH );
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char *sharedSecretKeyNameChars = NULL;
+
+ if( sharedSecretKeyName != NULL ) {
+ sharedSecretKeyNameChars = (char *) (env)->GetStringUTFChars( sharedSecretKeyName, NULL);
+ }
+
+ char *sharedSecretKeyNameString = sharedSecretKeyNameChars;
+
+ if ( sharedSecretKeyNameString == NULL ) {
+ sharedSecretKeyNameString = (char *) TRANSPORT_KEY_NAME;
+ }
+
+ GetSharedSecretKeyName(sharedSecretKeyNameString);
+
+ if( card_challenge != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ cc_len = (env)->GetArrayLength(card_challenge);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ hc_len = (env)->GetArrayLength( host_challenge);
+ }
+
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
-//char icv[8];
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
- int cc_len = (env)->GetArrayLength(card_challenge);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
- jbyte *hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
- // .size();
- int hc_len = (env)->GetArrayLength( host_challenge);
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
- jbyte * keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ if ( CUID != NULL ) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
/* copy card and host challenge into input buffer */
for (i = 0; i < 8; i++)
@@ -599,15 +708,9 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
{
input[8+i] = hc[i];
}
- PK11SymKey *symkey = NULL;
-
- BYTE macData[KEYLENGTH];
- char keyname[KEYNAMELENGTH];
GetDiversificationData(cuidValue,macData,mac);//keytype is mac
- char *tokenNameChars;
- PK11SlotInfo *slot = NULL;
if(tokenName)
{
tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
@@ -615,102 +718,158 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
(env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
}
- char *keyNameChars=NULL;
-
if(keyName)
{
keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
- strcpy(keyname,keyNameChars);
+ strncpy(keyname,keyNameChars,KEYNAMELENGTH);
(env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
}else
GetKeyName(keyVersion,keyname);
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKey! \n");
-
- if (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0 ||
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0) ||
(keyVersion[0] == -1 && strstr(keyname, "#FF")))
{
-
/* default manufacturers key */
- symkey = DeriveKey( //Util::DeriveKey(
- Buffer((BYTE*)mac_key, KEYLENGTH), Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
- if( slot )
- PK11_FreeSlot( slot );
+ macSymKey = ReturnDeveloperSymKey(slot, (char *) "mac" , keySetString, macBuff);
+
+ if( macSymKey == NULL ) {
+ goto done;
+ }
+
+ symkey = DeriveKey( //Util::DeriveKey(
+ macSymKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
}else
{
- PK11SymKey * masterKey = ReturnSymKey( slot,keyname);
-
- /* We need to use internal so that the key
- * can be exported by using PK11_GetKeyData()
- */
+ masterKey = ReturnSymKey( slot,keyname);
if(masterKey == NULL)
{
-
- if(slot)
- PK11_FreeSlot(slot);
- return NULL;
+ goto done;
}
- PK11SymKey *macKey =ComputeCardKeyOnToken(masterKey,macData);
-
+ macKey =ComputeCardKeyOnToken(masterKey,macData);
if(macKey == NULL)
{
-
- if(slot)
- PK11_FreeSlot(slot);
-
- PK11_FreeSymKey(masterKey);
- return NULL;
+ goto done;
}
-
- symkey = DeriveKeyWithCardKey(macKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+
+ symkey = DeriveKey(macKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
if(symkey == NULL)
{
+ goto done;
+ }
+ }
+ //Now wrap the key for the trip back to TPS with shared secret transport key
- if(slot)
- PK11_FreeSlot(slot);
+ symkey16 = NULL;
+ transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ PR_fprintf(PR_STDERR, "Can't find shared secret transport key! \n");
+ goto done;
+ }
- PK11_FreeSymKey( masterKey);
- PK11_FreeSymKey( macKey);
+ handleBA = (env)->NewByteArray( KEYLENGTH);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
- return NULL;
- }
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
- if( slot )
- PK11_FreeSlot( slot );
+ symkey16 = PK11_Derive(symkey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+ if ( !symkey16 ) {
+ PR_fprintf(PR_STDERR,"Can't derive 16 byte key from 24 byte symkey! \n");
+ goto done;
+ }
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = KEYLENGTH;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, transportKey, symkey16, &wrappedKeyItem);
+
+ if(wrapStatus == SECFailure )
+ {
+ PR_fprintf(PR_STDERR, "Can't wrap session key! Error: %d \n", PR_GetError());
+ }
+
+done:
+
+ if( slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if( internal ) {
+ PK11_FreeSlot(internal);
+ internal = NULL;
+ }
+
+ if ( symkey ) {
+ PK11_FreeSymKey( symkey);
+ symkey = NULL;
+ }
+
+ if ( transportKey ) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ if ( symkey16 ) {
+ PK11_FreeSymKey( symkey16 );
+ symkey16 = NULL;
+ }
+
+ if( masterKey ) {
PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( macKey ) {
PK11_FreeSymKey( macKey);
+ macKey = NULL;
+ }
+
+ if( macSymKey ) {
+ PK11_FreeSymKey( macSymKey );
+ macSymKey = NULL;
+ }
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
}
- /* status = EncryptData(kek_key, Buffer(cc,cc_len),out); */
- jbyte * session_key = (jbyte *) (PK11_GetKeyData(symkey)->data);
+ if( sharedSecretKeyNameChars ) {
+ (env)->ReleaseStringUTFChars(sharedSecretKeyName, (const char *)sharedSecretKeyNameChars);
+ sharedSecretKeyNameChars = NULL;
+ }
- if(session_key == NULL)
- {
- PK11_FreeSymKey(symkey);
- return NULL;
+ if ( handleBA != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
}
- jbyteArray handleBA=NULL;
- jbyte *handleBytes=NULL;
- handleBA = (env)->NewByteArray( KEYLENGTH);
- handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
- memcpy(handleBytes, session_key,KEYLENGTH);
- PK11_FreeSymKey( symkey);
+ if ( cc != NULL) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
+
+ if ( hc != NULL) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
- (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ if( keyVersion != NULL) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
- (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
- (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ if ( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
- (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
- (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ if( mac_key != NULL) {
+ (env)->ReleaseByteArrayElements(macKeyArray, mac_key, JNI_ABORT);
+ }
return handleBA;
}
@@ -726,177 +885,115 @@ extern "C"
* Signature: ([B[B[B[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeEncSessionKey
- (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring);
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
#ifdef __cplusplus
}
#endif
#define KEYLENGTH 16
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeEncSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray encKeyArray, jstring useSoftToken_s)
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeEncSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray encKeyArray, jstring useSoftToken_s, jstring keySet)
{
/* hardcoded permanent enc key */
- jbyte *enc_key = (jbyte*)(env)->GetByteArrayElements(encKeyArray, NULL);
- char input[16];
- int i;
-//char icv[8];
+ jbyte *enc_key = NULL;
+ if(encKeyArray != NULL ) {
+ enc_key = (jbyte*)(env)->GetByteArrayElements(encKeyArray, NULL);
+ } else {
+ return NULL;
+ }
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
- int cc_len = (env)->GetArrayLength(card_challenge);
+ char input[KEYLENGTH];
+ int i = 0;
- jbyte *hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
- // .size();
- int hc_len = (env)->GetArrayLength( host_challenge);
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0};
+ SECItem noParams = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
- jbyte * keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ char *keyNameChars = NULL;
+ char *tokenNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
- /* copy card and host challenge into input buffer */
- for (i = 0; i < 8; i++)
- {
- input[i] = cc[i];
- }
- for (i = 0; i < 8; i++)
- {
- input[8+i] = hc[i];
- }
PK11SymKey *symkey = NULL;
+ PK11SymKey * transportKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ PK11SymKey *encSymKey = NULL;
+ PK11SymKey *encKey = NULL;
+ PK11SymKey *symkey16 = NULL;
BYTE encData[KEYLENGTH];
char keyname[KEYNAMELENGTH];
- GetDiversificationData(cuidValue,encData,enc);
- char *tokenNameChars;
- PK11SlotInfo *slot = NULL;
- if(tokenName)
- {
- tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
- slot = ReturnSlot(tokenNameChars);
- (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
- }
- char *keyNameChars=NULL;
- if(keyName)
- {
- keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
- strcpy(keyname,keyNameChars);
- (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
- }
- else
- {
- GetKeyName(keyVersion,keyname);
- }
+ /* Derive vars */
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
- if (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ||
- (keyVersion[0] == -1 && strstr(keyname, "#FF")))
- {
- /* default manufacturers key */
- symkey = DeriveKey( //Util::DeriveKey(
- Buffer((BYTE*)enc_key, KEYLENGTH), Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ /* Java object return vars */
- if( slot )
- PK11_FreeSlot( slot );
- }else
- {
- PK11SymKey * masterKey = ReturnSymKey( slot,keyname);
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
- /* We need to use internal so that the key
- * can be exported by using PK11_GetKeyData()
- */
- if(masterKey == NULL)
- {
- if(slot)
- PK11_FreeSlot(slot);
- return NULL;
+ jbyte * cuidValue = NULL;
- }
+ jbyte *cc = NULL;
+ int cc_len = 0;
- PK11SymKey *encKey =ComputeCardKeyOnToken(masterKey,encData);
- if(encKey == NULL)
- {
- if(slot)
- PK11_FreeSlot(slot);
+ int hc_len = 0;
+ jbyte *hc = NULL;
- PK11_FreeSymKey(masterKey);
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
- return NULL;
- }
+ Buffer encBuff( ( BYTE *) enc_key , KEYLENGTH );
- symkey = DeriveKeyWithCardKey(encKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ char *keySetStringChars = NULL;
- PK11_FreeSymKey( masterKey);
- PK11_FreeSymKey( encKey);
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
- if(slot)
- PK11_FreeSlot(slot);
+ char *keySetString = keySetStringChars;
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
}
- /* status = EncryptData(kek_key, Buffer(cc,cc_len),out); */
- if(symkey == NULL)
- {
- return NULL;
+ if( card_challenge != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ cc_len = (env)->GetArrayLength(card_challenge);
}
- jbyte * session_key = (jbyte *) (PK11_GetKeyData(symkey)->data);
-
- jbyteArray handleBA=NULL;
- jbyte *handleBytes=NULL;
- handleBA = (env)->NewByteArray( KEYLENGTH);
- handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
- memcpy(handleBytes, session_key,KEYLENGTH);
- PK11_FreeSymKey( symkey);
-
- (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
-
- (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
- (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
-
- (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
- (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
-
- return handleBA;
-}
+ if( cc == NULL) {
+ goto done;
+ }
+ if( host_challenge != NULL) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ hc_len = (env)->GetArrayLength( host_challenge);
+ }
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/*
- * Class: com_netscape_cms_servlet_tks_RASessionKey
- * Method: ComputeKekSessionKey
- * Signature: ([B[B[B[B)[B
- */
- JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekSessionKey
- (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring);
-#ifdef __cplusplus
-}
-#endif
-#define KEYLENGTH 16
-extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekSessionKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s)
-{
- /* hardcoded permanent kek key */
- jbyte *kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
- char input[16];
- int i;
-//char icv[8];
+ if( hc == NULL) {
+ goto done;
+ }
- PRFileDesc *debug_fd = NULL;
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
-#ifdef DRM_SUPPORT_DEBUG
- debug_fd = PR_Open("/tmp/debug1.cfu",
- PR_RDWR | PR_CREATE_FILE | PR_APPEND,
- 400 | 200);
- PR_fprintf(debug_fd,"ComputeKekSessionKey\n");
-#endif // DRM_SUPPORT_DEBUG
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
- int cc_len = (env)->GetArrayLength(card_challenge);
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
- jbyte *hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
- // .size();
- int hc_len = (env)->GetArrayLength( host_challenge);
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
- jbyte * keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ if( cuidValue == NULL) {
+ goto done;
+ }
/* copy card and host challenge into input buffer */
for (i = 0; i < 8; i++)
@@ -907,91 +1004,162 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute
{
input[8+i] = hc[i];
}
- PK11SymKey *symkey = NULL;
- BYTE kekData[KEYLENGTH];
- char keyname[KEYNAMELENGTH];
- GetDiversificationData(cuidValue,kekData,kek);//keytype is kek
- char *tokenNameChars;
- PK11SlotInfo *slot = NULL;
- if (tokenName)
+ GetDiversificationData(cuidValue,encData,enc);
+
+ if(tokenName)
{
tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
slot = ReturnSlot(tokenNameChars);
(env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
}
- char *keyNameChars=NULL;
- if (keyName)
+
+ if(keyName)
{
keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
- strcpy(keyname,keyNameChars);
+ strncpy(keyname,keyNameChars,KEYNAMELENGTH);
(env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
- } else {
+ }
+ else {
GetKeyName(keyVersion,keyname);
}
- if (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ||
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0) ||
(keyVersion[0] == -1 && strstr(keyname, "#FF")))
{
/* default manufacturers key */
+
+ encSymKey = ReturnDeveloperSymKey(slot, (char *) "auth" , keySetString, encBuff);
+
+ if( encSymKey == NULL ) {
+ goto done;
+ }
+
symkey = DeriveKey( //Util::DeriveKey(
- Buffer((BYTE*)kek_key, KEYLENGTH), Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
- } else {
- PK11SymKey * masterKey = ReturnSymKey( slot,keyname);
+ encSymKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+
+ }else
+ {
+ masterKey = ReturnSymKey( slot,keyname);
/* We need to use internal so that the key
* can be exported by using PK11_GetKeyData()
*/
- if(masterKey == NULL)
- {
- if(slot)
- PK11_FreeSlot(slot);
- return NULL;
+ if(masterKey == NULL) {
+ goto done;
}
- PK11SymKey *kekKey =ComputeCardKeyOnToken(masterKey,kekData);
- if (kekKey == NULL)
- {
- if(slot)
- PK11_FreeSlot(slot);
-
- PK11_FreeSymKey(masterKey);
- return NULL;
+ encKey =ComputeCardKeyOnToken(masterKey,encData);
+ if(encKey == NULL) {
+ goto done;
}
+ symkey = DeriveKey(encKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ }
+
+ if(symkey == NULL) {
+ goto done;
+ }
+
+ //Now wrap the key for the trip back to TPS with shared secret transport key
+ transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ goto done;
+ }
+
+ handleBA = (env)->NewByteArray( KEYLENGTH);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ symkey16 = PK11_Derive(symkey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, KEYLENGTH);
+
+ if ( !symkey16 ) {
+ PR_fprintf(PR_STDERR,"SessionKey: ComputeEncSessionKey - Can't derive 16 byte key from 24 byte symkey! \n");
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = KEYLENGTH;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, transportKey, symkey16, &wrappedKeyItem);
- symkey = DeriveKeyWithCardKey(kekKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ if ( wrapStatus == SECFailure ) {
+ PR_fprintf(PR_STDERR,"SessionKey: ComputeEncSessionKey - Can't wrap encSessionKey ! Error: %d \n", PR_GetError());
+ }
+done:
+
+ if ( slot ) {
+ PK11_FreeSlot ( slot );
+ slot = NULL;
+ }
+
+ if ( internal) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ if( symkey) {
+ PK11_FreeSymKey( symkey);
+ symkey = NULL;
+ }
+
+ if( transportKey) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ if( masterKey) {
PK11_FreeSymKey( masterKey);
- PK11_FreeSymKey( kekKey);
+ masterKey = NULL;
+ }
- if(slot)
- PK11_FreeSlot(slot);
+ if( symkey16) {
+ PK11_FreeSymKey( symkey16);
+ symkey16 = NULL;
+ }
+ if ( encSymKey ) {
+ PK11_FreeSymKey( encSymKey);
+ encSymKey = NULL;
+ }
+
+ if( encKey) {
+ PK11_FreeSymKey( encKey);
+ encKey = NULL;
}
- /* status = EncryptData(kek_key, Buffer(cc,cc_len),out); */
- if(symkey == NULL)
- {
- return NULL;
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
}
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekSessionKey: got kek session key\n");
+ if ( handleBytes != NULL ) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
- jobject keyObj = JSS_PK11_wrapSymKey(env, &symkey, debug_fd);
- if (keyObj == NULL)
- {
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekSessionKey called wrapSymKey, key NULL\n");
+ if( cc != NULL ) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
}
- else
- {
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekSessionKey called wrapSymKey, key not NULL\n");
+
+ if( hc != NULL ) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
+ if(keyVersion != NULL ) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if(cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ if( enc_key != NULL) {
+ (env)->ReleaseByteArrayElements(encKeyArray, enc_key, JNI_ABORT);
}
- return keyObj;
-}
+ return handleBA;
+}
#ifdef __cplusplus
extern "C"
@@ -1003,33 +1171,89 @@ extern "C"
* Signature: ([B[B[B[B)[B
*/
JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekKey
- (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring);
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
#ifdef __cplusplus
}
#endif
#define KEYLENGTH 16
-extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s)
+
+extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_ComputeKekKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s, jstring keySet)
{
/* hardcoded permanent kek key */
- jbyte *kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
- char input[16];
+ jbyte *kek_key = NULL;
+ if( kekKeyArray != NULL) {
+ kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ Buffer kekBuff( ( BYTE *) kek_key , KEYLENGTH );
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char input[KEYLENGTH];
int i;
-//char icv[8];
jobject keyObj = NULL;
- PRFileDesc *debug_fd = NULL;
+ jbyte *cc = NULL;
+ jbyte *hc = NULL;
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ jbyte * cuidValue = NULL;
-#ifdef DRM_SUPPORT_DEBUG
- debug_fd = PR_Open("/tmp/debug1.cfu",
- PR_RDWR | PR_CREATE_FILE | PR_APPEND,
- 400 | 200);
- PR_fprintf(debug_fd,"ComputeKekKey\n");
-#endif // DRM_SUPPORT_DEBUG
+ char *keyNameChars=NULL;
+ char *tokenNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+
+ PK11SymKey *kekKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ BYTE kekData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+ if( card_challenge != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ }
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
- jbyte *hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
- jbyte * keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
/* copy card and host challenge into input buffer */
for (i = 0; i < 8; i++)
@@ -1041,21 +1265,15 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute
input[8+i] = hc[i];
}
- PK11SlotInfo *internalSlot = NULL;
- PK11SymKey *masterKey = NULL;
- PK11SymKey *kekKey = NULL;
- BYTE kekData[KEYLENGTH];
- char keyname[KEYNAMELENGTH];
GetDiversificationData(cuidValue,kekData,kek);//keytype is kek
- char *tokenNameChars;
- PK11SlotInfo *slot = NULL;
+
if (tokenName)
{
tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
slot = ReturnSlot(tokenNameChars);
(env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
}
- char *keyNameChars=NULL;
+
if (keyName)
{
keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
@@ -1064,84 +1282,74 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute
}else
GetKeyName(keyVersion,keyname);
- if (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ||
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeKekKey! \n");
+
+ if (( keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ) ||
(keyVersion[0] == -1 && strcmp(keyname, "#FF")))
{
/* default manufacturers key */
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekKey shouldn't get here\n");
-
- BYTE masterKeyData[24];
- SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData)};
- memcpy(masterKeyData, (char*)kek_key, 16);
- memcpy(masterKeyData+16, (char*)kek_key, 8);
- if (debug_fd)
- PR_fprintf(debug_fd, "ComputeKekKey DRMproto before import\n");
- kekKey = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginUnwrap, CKA_ENCRYPT, &masterKeyItem,
- ALL_SYMKEY_OPS /*CKF_ENCRYPT*/, PR_FALSE, 0);
-
- if( slot )
- PK11_FreeSlot( slot );
+ kekKey = ReturnDeveloperSymKey(slot, (char *) "kek" , keySetString, kekBuff);
} else {
masterKey = ReturnSymKey( slot,keyname);
- /* We need to use internal so that the key
- * can be exported by using PK11_GetKeyData()
- */
+
if(masterKey == NULL)
{
- if(slot)
- PK11_FreeSlot(slot);
- return NULL;
+ goto done;
}
kekKey =ComputeCardKeyOnToken(masterKey,kekData);
}
- if(kekKey == NULL)
- {
- if(slot)
- PK11_FreeSlot(slot);
+ if(kekKey == NULL) {
+ goto done;
+ }
- if(masterKey)
- PK11_FreeSymKey(masterKey);
+ keyObj = JSS_PK11_wrapSymKey(env, &kekKey, NULL);
- return NULL;
- }
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekKey: got kek key\n");
+done:
- keyObj = JSS_PK11_wrapSymKey(env, &kekKey, debug_fd);
- if (keyObj == NULL)
- {
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekKey: keyObj is NULL\n");
- }
- else
- {
- if (debug_fd)
- PR_fprintf(debug_fd,"ComputeKekKey: keyObj is not NULL\n");
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
}
- if(masterKey)
+ if(masterKey) {
PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
- if(kekKey)
+ if(kekKey) {
PK11_FreeSymKey( kekKey);
+ kekKey = NULL;
+ }
- if(slot)
+ if(slot) {
PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if (cc != NULL) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
- if(internalSlot)
- PK11_FreeSlot(internalSlot);
+ if (hc != NULL) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL ) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if (cuidValue != NULL ) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
return keyObj;
}
-
PRStatus ComputeMAC(PK11SymKey *key, Buffer &x_input,
const Buffer &icv, Buffer &output)
{
@@ -1156,7 +1364,7 @@ const Buffer &icv, Buffer &output)
CK_ULONG macLen = sizeof result;
SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen };
#endif
- static SECItem noParams = { siBuffer, 0, 0 };
+ static SECItem noParams = { siBuffer, NULL, 0 };
static unsigned char macPad[] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -1289,66 +1497,136 @@ extern "C"
* Signature: ([B[B[B[B)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCryptogram
- (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, int, jbyteArray, jstring);
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, int, jbyteArray, jstring, jstring);
#ifdef __cplusplus
}
#endif
#define KEYLENGTH 16
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCryptogram(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, int type, jbyteArray authKeyArray, jstring useSoftToken_s)
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCryptogram(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray card_challenge, jbyteArray host_challenge, jbyteArray keyInfo, jbyteArray CUID, int type, jbyteArray authKeyArray, jstring useSoftToken_s, jstring keySet)
{
/* hardcore permanent mac key */
- jbyte *auth_key = (jbyte*)(env)->GetByteArrayElements(authKeyArray, NULL);
- char input[16];
+ jbyte *auth_key = NULL;
+ if( authKeyArray != NULL) {
+ auth_key = (jbyte*)(env)->GetByteArrayElements(authKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ Buffer authBuff( ( BYTE *) auth_key , KEYLENGTH );
+ Buffer icv = Buffer(EIGHT_BYTES, (BYTE)0);
+ Buffer output = Buffer(EIGHT_BYTES, (BYTE)0);
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char input[KEYLENGTH];
int i;
-//char icv[8];
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
- int cc_len = (env)->GetArrayLength(card_challenge);
- jbyte *hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
- // .size();
- int hc_len = (env)->GetArrayLength( host_challenge);
+ PR_fprintf(PR_STDOUT,"In SessionKey: ComputeCryptogram! \n");
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ jbyte *cc = NULL;
+ jbyte *hc = NULL;
+ int cc_len = 0;
+ int hc_len = 0;
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ jbyte * cuidValue = NULL;
+
+ char *tokenNameChars = NULL;
+ char *keyNameChars=NULL;
+ PK11SlotInfo *slot = NULL;
+
+ jbyte * session_key = NULL;
+ PK11SymKey *symkey = NULL;
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *authKey = NULL;
+ PK11SymKey *authSymKey = NULL;
- jbyte * keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ BYTE authData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+ Buffer input_x = Buffer(KEYLENGTH);
+
+ if( card_challenge != NULL ) {
+ cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
+ cc_len = (env)->GetArrayLength(card_challenge);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ if( host_challenge != NULL ) {
+ hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
+ hc_len = (env)->GetArrayLength( host_challenge);
+ }
+
+ if( hc == NULL) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
if (type == 0) // compute host cryptogram
{
/* copy card and host challenge into input buffer */
- for (i = 0; i < 8; i++)
+ for (i = 0; i < EIGHT_BYTES; i++)
{
input[i] = cc[i];
}
- for (i = 0; i < 8; i++)
+ for (i = 0; i < EIGHT_BYTES; i++)
{
- input[8+i] = hc[i];
+ input[EIGHT_BYTES +i] = hc[i];
}
} // compute card cryptogram
else if (type == 1)
{
- for (i = 0; i < 8; i++)
+ for (i = 0; i < EIGHT_BYTES; i++)
{
input[i] = hc[i];
}
- for (i = 0; i < 8; i++)
+ for (i = 0; i < EIGHT_BYTES; i++)
{
- input[8+i] = cc[i];
+ input[EIGHT_BYTES+i] = cc[i];
}
}
- PK11SymKey *symkey = NULL;
+ input_x.replace(0, (BYTE*) input, KEYLENGTH);
- BYTE authData[KEYLENGTH];
- char keyname[KEYNAMELENGTH];
GetDiversificationData(cuidValue,authData,enc);
- char *tokenNameChars;
- PK11SlotInfo *slot = NULL;
+
if (tokenName)
{
tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
slot = ReturnSlot(tokenNameChars);
(env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
}
- char *keyNameChars=NULL;
if (keyName)
{
@@ -1358,141 +1636,106 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
}else
GetKeyName(keyVersion,keyname);
- if (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ||
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 &&strcmp( keyname, "#01#01") == 0 ) ||
(keyVersion[0] == -1 && strstr(keyname, "#FF")))
{
+
/* default manufacturers key */
- symkey = DeriveKey( //Util::DeriveKey(
- Buffer((BYTE*)auth_key, KEYLENGTH), Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
- if( slot )
- PK11_FreeSlot( slot );
+ authSymKey = ReturnDeveloperSymKey(slot, (char *) "auth" , keySetString, authBuff);
+ if( authSymKey == NULL ) {
+ goto done;
+ }
+
+ symkey = DeriveKey(
+ authSymKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
}
else
{
- PK11SymKey * masterKey = ReturnSymKey( slot,keyname);
+ masterKey = ReturnSymKey( slot,keyname);
if (masterKey == NULL)
{
- if(slot)
- PK11_FreeSlot(slot);
-
- return NULL;
+ goto done;
}
- PK11SymKey *authKey = ComputeCardKeyOnToken(masterKey,authData);
+ authKey = ComputeCardKeyOnToken(masterKey,authData);
if (authKey == NULL)
{
- if(slot)
- PK11_FreeSlot(slot);
-
- PK11_FreeSymKey( masterKey);
- return NULL;
+ goto done;
}
- if(slot)
- PK11_FreeSlot(slot);
-
- symkey = DeriveKeyWithCardKey(authKey,
+ symkey = DeriveKey(authKey,
Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
- PK11_FreeSymKey( masterKey);
- PK11_FreeSymKey( authKey);
- }
-
- if(symkey == NULL)
- {
- return NULL;
}
- Buffer icv = Buffer(8, (BYTE)0);
- Buffer output = Buffer(8, (BYTE)0);
- Buffer input_x = Buffer((BYTE*)input, 16);
ComputeMAC(symkey, input_x, icv, output);
- jbyte * session_key = (jbyte *) (BYTE*)output;
+ session_key = (jbyte *) (BYTE*)output;
- jbyteArray handleBA=NULL;
- jbyte *handleBytes=NULL;
- handleBA = (env)->NewByteArray( 8);
+ handleBA = (env)->NewByteArray( EIGHT_BYTES);
handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
- memcpy(handleBytes, session_key,8);
- PK11_FreeSymKey( symkey);
- (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
- (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
- (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
- (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
- (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
-
- return handleBA;
-}
+ if( handleBytes ) {
+ memcpy(handleBytes, session_key, EIGHT_BYTES);
+ }
+done:
-//=================================================================================
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/*
- * Class: com_netscape_cms_servlet_tks_RASessionKey
- * Method: ComputeCardCryptogram
- * Signature: ([B[B[B[B)[B
- */
- JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCardCryptogram
- (JNIEnv *, jclass, jbyteArray, jbyteArray, jbyteArray);
-#ifdef __cplusplus
-}
-#endif
-#define KEYLENGTH 16
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeCardCryptogram(JNIEnv * env, jclass this2, jbyteArray auth_key, jbyteArray card_challenge, jbyteArray host_challenge)
-{
- char input[16];
- int i;
+ if( slot ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
- jbyte *ak = (jbyte*)(env)->GetByteArrayElements( auth_key, NULL);
- int ak_len = (env)->GetArrayLength(auth_key);
+ if( symkey ) {
+ PK11_FreeSymKey( symkey );
+ symkey = NULL;
+ }
- jbyte *cc = (jbyte*)(env)->GetByteArrayElements( card_challenge, NULL);
- int cc_len = (env)->GetArrayLength(card_challenge);
+ if( authSymKey ) {
+ PK11_FreeSymKey( authSymKey );
+ authSymKey = NULL;
+ }
+
+ if( authKey) {
+ PK11_FreeSymKey( authKey);
+ authKey = NULL;
+ }
- jbyte *hc = (jbyte*)(env)->GetByteArrayElements( host_challenge, NULL);
- // .size();
- int hc_len = (env)->GetArrayLength( host_challenge);
+ if( masterKey) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
- for (i = 0; i < 8; i++)
- {
- input[i] = hc[i];
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
}
- for (i = 0; i < 8; i++)
- {
- input[8+i] = cc[i];
+
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
}
- PK11SymKey *symkey = NULL;
+ if( cc != NULL) {
+ (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
+ }
- /* default manufacturers key */
- symkey = DeriveKey( //Util::DeriveKey(
- Buffer((BYTE*)ak, ak_len), Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
+ if( hc != NULL) {
+ (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ }
- Buffer icv = Buffer(8, (BYTE)0);
- Buffer output = Buffer(8, (BYTE)0);
- Buffer input_x = Buffer((BYTE*)input, 16);
- ComputeMAC(symkey, input_x, icv, output);
- jbyte * session_key = (jbyte *) (BYTE*)output;
+ if( keyVersion != NULL) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
- jbyteArray handleBA=NULL;
- jbyte *handleBytes=NULL;
- handleBA = (env)->NewByteArray( 8);
- handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
- memcpy(handleBytes, session_key,8);
- PK11_FreeSymKey( symkey);
- (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
- (env)->ReleaseByteArrayElements(auth_key, ak, JNI_ABORT);
- (env)->ReleaseByteArrayElements(card_challenge, cc, JNI_ABORT);
- (env)->ReleaseByteArrayElements(host_challenge, hc, JNI_ABORT);
+ if( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
return handleBA;
}
+//=================================================================================
+
#ifdef __cplusplus
extern "C"
{
@@ -1504,62 +1747,61 @@ extern "C"
*/
JNIEXPORT jbyteArray JNICALL
Java_com_netscape_symkey_SessionKey_ECBencrypt
- (JNIEnv*, jclass, jobject, jbyteArray);
+ (JNIEnv*, jclass, jobject, jobject);
#ifdef __cplusplus
}
#endif
extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_netscape_symkey_SessionKey_ECBencrypt
-(JNIEnv* env, jclass this2, jobject symkeyObj, jbyteArray data)
+(JNIEnv* env, jclass this2, jobject symkeyObj, jobject deskeyObj )
{
jbyteArray handleBA=NULL;
- jint datalen, i;
- jint dlen=16; // applet only supports 16 bytes
- jbyte *databytes=NULL;
+ jint dlen=KEYLENGTH; // applet only supports 16 bytes
jbyte *handleBytes=NULL;
PK11SymKey *symkey = NULL;
- PK11Context *context = NULL;
+ PK11SymKey *deskey = NULL;
+ PK11SymKey *newdeskey = NULL;
PRStatus r = PR_FAILURE;
- SECStatus s = SECFailure;
- int lenx;
- static SECItem noParams = { siBuffer, 0, 0 };
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ SECItem wrappedKeyItem = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
- unsigned char result[8];
-/*
- PRFileDesc *debug_fd = PR_Open("/tmp/debug.cfu",
- PR_RDWR | PR_CREATE_FILE | PR_APPEND,
- 400 | 200);
+ /* PK11_Derive vars. */
- PR_fprintf(debug_fd,"ECBencrypt\n");
-*/
- r = JSS_PK11_getSymKeyPtr(env, symkeyObj, &symkey);
- if (r != PR_SUCCESS)
- {
- goto finish;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_ULONG bitPosition = 0;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: ECBencrypt! \n");
+
+ if( !symkeyObj || !deskeyObj) {
+ goto finish;
}
- datalen = (jint)(env)->GetArrayLength(data);
- databytes = (jbyte*)(env)->GetByteArrayElements(data, NULL);
- if( databytes == NULL )
- {
+ r = JSS_PK11_getSymKeyPtr(env, symkeyObj, &symkey);
+ if (r != PR_SUCCESS) {
goto finish;
}
- if( ! symkey )
- {
+ r = JSS_PK11_getSymKeyPtr(env, deskeyObj, &deskey);
+ if (r != PR_SUCCESS) {
goto finish;
}
+ // Instead of playing with raw keys, let's derive the 16 byte des2 key from
+ // the 24 byte des2 key.
- context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, symkey,
- &noParams);
- if (!context)
- {
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ newdeskey = PK11_Derive(deskey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+
+ if ( ! newdeskey ) {
goto finish;
}
- if (datalen > 16)
- dlen = 16; // applet suports only 16 bytes
+ dlen = KEYLENGTH; // applet suports only 16 bytes
handleBA = (env)->NewByteArray(dlen);
if(handleBA == NULL )
@@ -1573,20 +1815,28 @@ Java_com_netscape_symkey_SessionKey_ECBencrypt
goto finish;
}
- for (i=0; i< dlen; i+=8)
- {
- s = PK11_CipherOp(context, result, &lenx, 8, (unsigned char *)&databytes[i], 8);
- if (s != SECSuccess)
- {
- goto finish;
- }
- memcpy(handleBytes+i, result, 8);
+ //Wrap the new 16 bit key with the input symkey.
+
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = dlen;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, symkey, newdeskey, &wrappedKeyItem);
+
+ if( wrapStatus == SECSuccess) {
+ PR_fprintf(PR_STDERR, "ECBencrypt wrapStatus %d wrappedKeySize %d \n", wrapStatus, wrappedKeyItem.len);
+ } else {
+ PR_fprintf(PR_STDERR, "ECBecrypt wrap failed! Error %d \n", PR_GetError());
}
- (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+finish:
- finish:
- if (context) PK11_DestroyContext(context, PR_TRUE);
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+
+ if ( newdeskey ) {
+ PK11_FreeSymKey( newdeskey );
+ newdeskey = NULL;
+ }
return handleBA;
}
@@ -1611,77 +1861,96 @@ extern "C" JNIEXPORT jobject JNICALL
Java_com_netscape_symkey_SessionKey_GenerateSymkey
(JNIEnv* env, jclass this2, jstring tokenName)
{
- jint keylen=24;
jobject keyObj = NULL;
-
PK11SymKey *okey = NULL;
- PK11SymKey *key = NULL;
- char *tokenNameChars;
+ PK11SymKey *okeyFirstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *finalKey = NULL;
+ char *tokenNameChars = NULL;
PK11SlotInfo *slot = NULL;
- SECStatus s = SECFailure;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_OBJECT_HANDLE keyhandle = 0;
- SECItem* okeyItem = NULL;
- unsigned char keyData[24];
- SECItem keyItem = {siBuffer, keyData, sizeof(keyData) };
-/*
-PRFileDesc *debug_fd = PR_Open("/tmp/debug.cfu",
- PR_RDWR | PR_CREATE_FILE | PR_APPEND,
- 400 | 200);
-
-PR_fprintf(debug_fd,"GenerateSymkey\n");
-*/
+ PR_fprintf(PR_STDOUT,"In SessionKey GenerateSymkey!\n");
if (tokenName)
{
tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
- slot = ReturnSlot(tokenNameChars);
+ if ( tokenNameChars && !strcmp(tokenNameChars, "internal")) {
+ slot = PK11_GetInternalSlot();
+ } else {
+ slot = ReturnSlot(tokenNameChars);
+ }
+
+ PR_fprintf(PR_STDOUT,"SessinKey: GenerateSymkey slot %p name %s tokenName %s \n",slot, PK11_GetSlotName(slot), PK11_GetTokenName(slot));
(env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
}
+ //Generate original 16 byte DES2 key
okey = PK11_TokenKeyGen(slot, CKM_DES2_KEY_GEN,0, 0, 0, PR_FALSE, NULL);
- if (okey == NULL)
+
+ if (okey == NULL) {
goto finish;
+ }
- s= PK11_ExtractKeyValue(okey);
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
- if (s != SECSuccess)
- goto finish;
+ okeyFirstEight = PK11_Derive(okey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+ if (okeyFirstEight == NULL ) {
+ goto finish;
+ }
- okeyItem = PK11_GetKeyData( okey);
+ //Concatenate 8 byte key to the end of the original key, giving new 24 byte key
+ keyhandle = PK11_GetSymKeyHandle(okeyFirstEight);
+ paramsItem.data=(unsigned char *) &keyhandle;
+ paramsItem.len=sizeof(keyhandle);
- if (okeyItem == NULL)
- goto finish;
+ concatKey = PK11_Derive ( okey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ if ( concatKey == NULL ) {
+ goto finish;
+ }
- memcpy(keyData, okeyItem->data, 16);
+ //Make sure we move this to the orig token, in case it got moved by NSS
+ //during the derive phase.
-// make the 3rd 8 bytes the same as the 1st
- if (keylen == 24)
- {
- memcpy(keyData+16, okeyItem->data, 8);
+ finalKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, concatKey);
+
+ /* wrap the symkey in java object. This sets symkey to NULL. */
+ keyObj = JSS_PK11_wrapSymKey(env, &finalKey, NULL);
- keyItem.len = keylen;
+finish:
+ if ( slot != NULL) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
}
- key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &keyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
- if( ! key )
- {
- goto finish;
+ if ( okey != NULL) {
+ PK11_FreeSymKey(okey);
+ okey = NULL;
}
- /* wrap the symkey in java object. This sets symkey to NULL. */
- keyObj = JSS_PK11_wrapSymKey(env, &key, NULL);
+ if ( okeyFirstEight != NULL) {
+ PK11_FreeSymKey(okeyFirstEight);
+ okeyFirstEight = NULL;
+ }
-finish:
- if (slot) PK11_FreeSlot(slot);
- if (okey) PK11_FreeSymKey(okey);
- if (key) PK11_FreeSymKey(key);
+ if ( concatKey != NULL) {
+ PK11_FreeSymKey(concatKey);
+ concatKey = NULL;
+ }
+
+ if ( finalKey != NULL) {
+ PK11_FreeSymKey(finalKey);
+ finalKey = NULL;
+ }
return keyObj;
}
-
// begin DRM proto
#ifdef __cplusplus
@@ -1716,7 +1985,10 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_bytes2P
memcpy(masterKeyData, (char*)symKeyBytes, 16);
memcpy(masterKeyData+16, (char*)symKeyBytes, 8);
- PR_fprintf(debug_fd, "DRMproto before import\n");
+
+ // ToDo: possibly get rid of whole function, not used
+ // For now , no need to get rid of PK11_ImportSymKeyWithFlags call.
+
symKey = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
PK11_OriginUnwrap, CKA_ENCRYPT, &masterKeyItem,
ALL_SYMKEY_OPS /*CKF_ENCRYPT*/, PR_FALSE, 0);
diff --git a/pki/base/symkey/src/com/netscape/symkey/SessionKey.java b/pki/base/symkey/src/com/netscape/symkey/SessionKey.java
index 11460105..a535a9fb 100644
--- a/pki/base/symkey/src/com/netscape/symkey/SessionKey.java
+++ b/pki/base/symkey/src/com/netscape/symkey/SessionKey.java
@@ -77,12 +77,9 @@ public class SessionKey
}
}
- // external calls from RA
- public static native byte[] ComputeKeyCheck( byte data[] );
- public static native byte[] ComputeCardCryptogram( byte[] raw_auth_key,
- byte[] card_challenge,
- byte[] host_challenge );
+ // external calls from RA
+ public static native byte[] ComputeKeyCheck(PK11SymKey desKey ); /* byte data[] ); */
public static native byte[] ComputeSessionKey( String tokenName,
String keyName,
@@ -91,7 +88,9 @@ public class SessionKey
byte[] keyInfo,
byte[] CUID,
byte[] macKeyArray,
- String useSoftToken );
+ String useSoftToken,
+ String keySet,
+ String sharedSecretKeyName );
public static native byte[] ComputeEncSessionKey( String tokenName,
String keyName,
@@ -100,7 +99,8 @@ public class SessionKey
byte[] keyInfo,
byte[] CUID,
byte[] encKeyArray,
- String useSoftToken );
+ String useSoftToken,
+ String keySet );
public static native PK11SymKey ComputeKekSessionKey( String tokenName,
String keyName,
@@ -109,7 +109,8 @@ public class SessionKey
byte[] keyInfo,
byte[] CUID,
byte[] kekKeyArray,
- String useSoftToken );
+ String useSoftToken,
+ String keySet );
public static native PK11SymKey ComputeKekKey( String tokenName,
String keyName,
@@ -118,10 +119,10 @@ public class SessionKey
byte[] keyInfo,
byte[] CUID,
byte[] kekKeyArray,
- String useSoftToken );
+ String useSoftToken, String keySet );
public static native byte[] ECBencrypt( PK11SymKey key,
- byte[] data );
+ PK11SymKey desKey ); //byte[] data );
public static native PK11SymKey GenerateSymkey( String tokenName );
@@ -139,7 +140,7 @@ public class SessionKey
byte[] CUID,
int type,
byte[] authKeyArray,
- String useSoftToken );
+ String useSoftToken, String keySet );
public static native byte[] EncryptData( String tokenName,
String keyName,
@@ -147,7 +148,7 @@ public class SessionKey
byte[] keyInfo,
byte[] CUID,
byte[] kekKeyArray,
- String useSoftToken );
+ String useSoftToken, String keySet );
public static native byte[] DiversifyKey( String tokenName,
String newTokenName,
@@ -156,7 +157,7 @@ public class SessionKey
String keyInfo,
byte[] CUIDValue,
byte[] kekKeyArray,
- String useSoftToken );
+ String useSoftToken, String keySet );
// internal calls from config TKS keys tab
public static native String GenMasterKey( String token,
diff --git a/pki/base/symkey/src/com/netscape/symkey/SymKey.cpp b/pki/base/symkey/src/com/netscape/symkey/SymKey.cpp
index 70a3dfbc..c300d1ad 100644
--- a/pki/base/symkey/src/com/netscape/symkey/SymKey.cpp
+++ b/pki/base/symkey/src/com/netscape/symkey/SymKey.cpp
@@ -52,7 +52,6 @@ extern "C"
#include "certdb.h"
#include "nss.h"
-#include "seccomon.h"
#include "nspr.h"
#ifdef __cplusplus
#include <jni.h>
@@ -87,6 +86,7 @@ typedef struct
char masterKeyPrefix[PREFIXLENGHT];
char masterKeyNickName[KEYNAMELENGTH];
char masterNewKeyNickName[KEYNAMELENGTH];
+char sharedSecretSymKeyName[KEYNAMELENGTH] = { 0 };
//=================================================================================
#ifdef __cplusplus
@@ -113,7 +113,7 @@ PK11SlotInfo *ReturnSlot(char *tokenNameChars)
}
PK11SlotInfo *slot=NULL;
- if(!strcmp( tokenNameChars, "internal" ) )
+ if(!strcmp( tokenNameChars, "internal" ) || !strcmp( tokenNameChars, "Internal Key Storage Token"))
{
slot = PK11_GetInternalKeySlot();
}
@@ -140,7 +140,7 @@ PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname)
pwdata.source = secuPWData::PW_NONE;
pwdata.data = (char *) NULL;
-
+ PR_fprintf(PR_STDOUT,"In ReturnSymKey name %s \n",keyname);
if (keyname == NULL)
{
goto cleanup;
@@ -151,7 +151,6 @@ PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname)
}
/* Initialize the symmetric key list. */
firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
-
/* scan through the symmetric key list for a key matching our nickname */
sk = firstSymKey;
while( sk != NULL )
@@ -414,7 +413,11 @@ PK11SymKey *ComputeCardKeyOnSoftToken(PK11SymKey *masterKey, unsigned char *data
{
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
PK11SymKey *key = ComputeCardKey(masterKey, data, slot);
- PK11_FreeSlot(slot);
+ if( slot != NULL) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
return key;
}
@@ -422,16 +425,16 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
{
PK11SymKey *key = NULL;
PK11Context *context = NULL;
- int keysize;
- keysize = 24;
+ int keysize = DES3_LENGTH;
unsigned char *keyData = NULL;
- SECStatus s;
+ SECStatus s = SECSuccess;
int i = 0;
- int len=0;
- static SECItem noParams = { siBuffer, 0, 0 };
+ int len = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
unsigned char *in = data;
PK11SymKey *tmpkey = NULL;
- unsigned char wrappedkey[24];
+ unsigned char wrappedkey[DES3_LENGTH];
+ SECItem wrappeditem = { siBuffer, NULL, 0 };
keyData = (unsigned char*)malloc(keysize);
@@ -440,9 +443,8 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
keyData[i] = 0x0;
}
- if (masterKey == NULL)
- {
- printf("ComputeCardKey: master key is null\n");
+ if (masterKey == NULL) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: master key is null.\n");
goto done;
}
@@ -450,34 +452,31 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
masterKey,
&noParams);
- if (context == NULL)
- {
- printf("failed to create context\n");
+ if (context == NULL) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to create context.\n");
goto done;
}
/* Part 1 */
s = PK11_CipherOp(context, &keyData[0], &len, 8, in, 8);
- if (s != SECSuccess)
- {
- printf("failed to encryp #1\n");
+ if (s != SECSuccess) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to encrypt #1\n");
goto done;
}
- pk11_FormatDESKey(&keyData[0], 8); /* set parity */
+ pk11_FormatDESKey(&keyData[0], EIGHT_BYTES); /* set parity */
/* Part 2 */
- s = PK11_CipherOp(context, &keyData[8], &len, 8, in+8, 8);
- if (s != SECSuccess)
- {
- printf("failed to encryp #2\n");
+ s = PK11_CipherOp(context, &keyData[EIGHT_BYTES], &len, EIGHT_BYTES, in+EIGHT_BYTES, EIGHT_BYTES);
+ if (s != SECSuccess) {
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to encryp #2.\n");
goto done;
}
- pk11_FormatDESKey(&keyData[8], 8);
+ pk11_FormatDESKey(&keyData[EIGHT_BYTES], EIGHT_BYTES);
/* Part 3 */
- for(i = 0;i < 8;i++)
+ for(i = 0;i < EIGHT_BYTES;i++)
{
- keyData[i+16] = keyData[i];
+ keyData[i+KEYLENGTH] = keyData[i];
}
#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL
@@ -489,7 +488,7 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
PR_FALSE, &pwdata);
if (tmpkey == NULL) {
- printf("failed to keygen \n");
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to keygen. \n");
goto done;
}
@@ -498,7 +497,7 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
&noParams);
if (context == NULL) {
- printf("failed to set context \n");
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to set context. \n");
goto done;
}
@@ -506,11 +505,10 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
s = PK11_CipherOp(context, wrappedkey, &len, 24, keyData, 24);
if (s != SECSuccess)
{
- printf("failed to encryp #3\n");
+ PR_fprintf(PR_STDERR,"ComputeCardKey: failed to encrypt #3.\n");
goto done;
}
- SECItem wrappeditem;
wrappeditem.data = wrappedkey;
wrappeditem.len = len;
@@ -533,123 +531,82 @@ done:
PK11_FreeSymKey(tmpkey);
tmpkey = NULL;
}
+
return key;
}
-
PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data)
{
PK11SlotInfo *slot = PK11_GetSlotFromKey(masterKey);
PK11SymKey *key = ComputeCardKey(masterKey, data, slot);
- PK11_FreeSlot(slot);
- return key;
-}
-
-
-PRStatus EncryptDataWithCardKey(PK11SymKey *card_key, Buffer &input, Buffer &output)
-{
- PRStatus rv = PR_FAILURE;
-
- PK11Context *context = NULL;
- int i;
- SECStatus s = SECFailure;
- int len;
- static SECItem noParams = { siBuffer, 0, 0 };
- unsigned char result[8];
-
- if (card_key == NULL) {
- printf("EncryptDataWithCardKey: card_key is null\n");
- goto done;
- }
-
- context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, card_key,
- &noParams);
- if (context == NULL)
- {
- goto done;
- }
-
- for(i = 0;i < (int)input.size();i += 8)
- {
- s = PK11_CipherOp(context, result, &len, 8,
- (unsigned char *)(((BYTE*)input)+i), 8);
- if (s != SECSuccess)
- {
- goto done;
- }
- output.replace(i, result, 8);
+ if( slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
}
- rv = PR_SUCCESS;
-
-done:
- if (context)
- {
- PK11_DestroyContext(context, PR_TRUE);
- context = NULL;
- }
- return rv;
+ return key;
}
-
-PRStatus EncryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+// Either encrypt data with a provided SymKey OR a key buffer array (for the Default keyset case).
+PRStatus EncryptData(const Buffer &kek_key,PK11SymKey *cardKey, Buffer &input, Buffer &output)
{
PRStatus rv = PR_FAILURE;
PK11SymKey *master = NULL;
+ PK11SymKey *transportKey = NULL;
PK11SlotInfo *slot = NULL;
PK11Context *context = NULL;
- int i;
+ int i = 0;
SECStatus s = SECFailure;
- int len;
- static SECItem noParams = { siBuffer, 0, 0 };
+ int len = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
#ifdef DES2_WORKAROUND
- unsigned char masterKeyData[24];
+ unsigned char masterKeyData[DES3_LENGTH];
#else
- unsigned char masterKeyData[16];
-#endif
- SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
- unsigned char result[8];
-
- /* convert 16-byte to 24-byte triple-DES key */
- memcpy(masterKeyData, (BYTE*)kek_key, 16);
-#ifdef DES2_WORKAROUND
- memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+ unsigned char masterKeyData[KEYLENGTH];
#endif
+ unsigned char result[EIGHT_BYTES];
slot = PK11_GetInternalKeySlot();
- if (slot == NULL)
- {
+
+ if (slot == NULL) {
goto done;
}
- master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
- if( master == NULL)
- {
- printf("EncryptData: master is null\n");
+ if ( cardKey == NULL ) { /* Developer key set mode.*/
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(masterKeyData, kek_key, 16);
+ memcpy(masterKeyData+16, kek_key, 8);
+
+ master = CreateUnWrappedSymKeyOnToken( slot, transportKey, masterKeyData, sizeof(masterKeyData), PR_FALSE);
+
+ } else {
+ master = cardKey;
+ }
+
+ if( master == NULL) {
goto done;
}
context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
&noParams);
- if (context == NULL)
- {
+
+ if (context == NULL) {
goto done;
}
- for(i = 0;i < (int)input.size();i += 8)
+ for(i = 0;i < (int)input.size();i += EIGHT_BYTES)
{
- s = PK11_CipherOp(context, result, &len, 8,
- (unsigned char *)(((BYTE*)input)+i), 8);
+ s = PK11_CipherOp(context, result, &len, EIGHT_BYTES,
+ (unsigned char *)(((BYTE*)input)+i), EIGHT_BYTES);
- if (s != SECSuccess)
- {
+ if (s != SECSuccess) {
goto done;
}
- output.replace(i, result, 8);
+ output.replace(i, result, EIGHT_BYTES);
}
rv = PR_SUCCESS;
@@ -667,7 +624,7 @@ done:
PK11_FreeSlot(slot);
slot = NULL;
}
- if (master)
+ if (master && cardKey == NULL)
{
PK11_FreeSymKey(master);
master = NULL;
@@ -676,37 +633,27 @@ done:
return rv;
}
-
-PRStatus ComputeKeyCheck(const Buffer& newKey, Buffer& output)
+PRStatus ComputeKeyCheckWithSymKey(PK11SymKey * newKey, Buffer& output)
{
PK11SymKey *key = NULL;
PRStatus status = PR_FAILURE ;
PK11SlotInfo *slot = NULL;
PK11Context *context = NULL;
SECStatus s = SECFailure;
- int len;
- static SECItem noParams = { siBuffer, 0, 0 };
-#ifdef DES2_WORKAROUND
- unsigned char keyData[24];
-#else
- unsigned char keyData[16];
-#endif
- SECItem keyItem = {siBuffer, keyData, sizeof(keyData) };
- unsigned char value[8];
- /* convert 16-byte to 24-byte triple-DES key */
- memcpy(keyData, newKey, 16);
-#ifdef DES2_WORKAROUND
- memcpy(keyData+16, newKey, 8);
-#endif
+ int len = 0;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ unsigned char value[EIGHT_BYTES];
+
+ if ( newKey == NULL ) {
+ return status;
+ }
memset(value, 0, sizeof value);
slot = PK11_GetInternalKeySlot();
if (slot != NULL)
{
- key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &keyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
+ key = newKey ;
if( key != NULL )
{
context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
@@ -723,94 +670,130 @@ PRStatus ComputeKeyCheck(const Buffer& newKey, Buffer& output)
}
PK11_DestroyContext(context, PR_TRUE);
context = NULL;
- memset(keyData, 0, sizeof keyData);
}
- PK11_FreeSymKey(key);
- key = NULL;
+ //PK11_FreeSymKey(key);
+ //key = NULL;
}
- PK11_FreeSlot(slot);
+ if( slot != NULL) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
}
return status;
}
-
-PRStatus CreateKeySetDataWithKey( Buffer &newMasterVer, PK11SymKey *old_kek_key, Buffer &new_auth_key, Buffer &new_mac_key, Buffer &new_kek_key, Buffer &output)
+// Create key set data with the help of either a provided old_keyk_ke2_sym key or key buffer (for the Default keyset case).
+PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek_key2, PK11SymKey *old_kek_key2_sym, PK11SymKey *new_auth_key, PK11SymKey *new_mac_key, PK11SymKey *new_kek_key, Buffer &output)
{
PRStatus rv = PR_FAILURE;
+ static SECItem noParams = { siBuffer, NULL, 0 };
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *wrappingKey = NULL;
+ BYTE masterKeyData[DES3_LENGTH];
+
+ /* Wrapping vars */
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0 };
+ SECStatus wrapStatus = SECFailure;
+ PK11SlotInfo *slot = NULL;
+ /* Extracting vars */
+
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ PK11SymKey *macKey16 = NULL;
+ PK11SymKey *authKey16 = NULL;
+ PK11SymKey *kekKey16 = NULL;
+
+ Buffer encrypted_auth_key(KEYLENGTH);
+ Buffer encrypted_mac_key(KEYLENGTH);
+ Buffer encrypted_kek_key(KEYLENGTH);
+ Buffer kc_auth_key(3);
+ Buffer kc_mac_key(3);
+ Buffer kc_kek_key(3);
Buffer result;
- if (old_kek_key == NULL)
- {
- result = new_auth_key + new_mac_key + new_kek_key + output ;
+
+ PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys!\n");
+
+ if ( new_auth_key == NULL || new_mac_key == NULL || new_kek_key == NULL) {
+ return rv;
}
- else
- {
- Buffer encrypted_auth_key(16);
- EncryptDataWithCardKey(old_kek_key, new_auth_key, encrypted_auth_key);
- Buffer kc_auth_key(3);
- ComputeKeyCheck(new_auth_key, kc_auth_key);
+ slot = PK11_GetSlotFromKey(new_auth_key);
+ if ( old_kek_key2_sym == NULL ) { /* perm key mode */
+ /* Find transport key, shared secret */
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ goto done;
+ }
- Buffer encrypted_mac_key(16);
- EncryptDataWithCardKey(old_kek_key, new_mac_key, encrypted_mac_key);
- Buffer kc_mac_key(3);
- ComputeKeyCheck(new_mac_key, kc_mac_key);
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(masterKeyData, old_kek_key2, KEYLENGTH);
+ memcpy(masterKeyData+16, old_kek_key2, EIGHT_BYTES);
- Buffer encrypted_kek_key(16);
- EncryptDataWithCardKey(old_kek_key, new_kek_key, encrypted_kek_key);
- Buffer kc_kek_key(3);
- ComputeKeyCheck(new_kek_key, kc_kek_key);
+ wrappingKey = CreateUnWrappedSymKeyOnToken( slot, transportKey, masterKeyData, sizeof(masterKeyData), PR_FALSE);
- result = newMasterVer +
- Buffer(1, (BYTE)0x81) +
- Buffer(1, (BYTE)0x10) +
- encrypted_auth_key +
- Buffer(1, (BYTE)0x03) +
- kc_auth_key +
- Buffer(1, (BYTE)0x81) +
- Buffer(1, (BYTE)0x10) +
- encrypted_mac_key +
- Buffer(1, (BYTE)0x03) +
- kc_mac_key +
- Buffer(1, (BYTE)0x81) +
- Buffer(1, (BYTE)0x10) +
- encrypted_kek_key +
- Buffer(1, (BYTE)0x03) +
- kc_kek_key;
+ } else { /* card key mode */
+ wrappingKey = old_kek_key2_sym;
}
- output = result;
- rv = PR_SUCCESS;
- return rv;
+ //Now derive 16 byte versions of the provided symkeys
+ authKey16 = PK11_Derive(new_auth_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
-} /* CreateKeySetDataWithKey */
+ if ( authKey16 == NULL ) {
+ PR_fprintf(PR_STDERR,"Error deriving authKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+ wrappedKeyItem.data = (unsigned char *) encrypted_auth_key;
+ wrappedKeyItem.len = encrypted_auth_key.size();
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, authKey16, &wrappedKeyItem);
+ if ( wrapStatus == SECFailure ) {
+ PR_fprintf(PR_STDERR,"Error wrapping authKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
-PRStatus CreateKeySetData( Buffer &newMasterVer, Buffer &old_kek_key2, Buffer &new_auth_key, Buffer &new_mac_key, Buffer &new_kek_key, Buffer &output)
-{
- PRStatus rv = PR_FAILURE;
+ macKey16 = PK11_Derive(new_mac_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT, CKA_DERIVE, 16);
- Buffer result;
- if(old_kek_key2 == Buffer((BYTE*)"#00#00", 6))
- {
- result = new_auth_key + new_mac_key + new_kek_key + output ;
- } else {
- Buffer encrypted_auth_key(16);
- EncryptData(old_kek_key2, new_auth_key, encrypted_auth_key);
- Buffer kc_auth_key(3);
- ComputeKeyCheck(new_auth_key, kc_auth_key);
+ if ( macKey16 == NULL ) {
+ PR_fprintf(PR_STDERR,"Error deriving macKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) encrypted_mac_key;
+ wrappedKeyItem.len = encrypted_mac_key.size();
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, macKey16, &wrappedKeyItem);
+ if ( wrapStatus == SECFailure) {
+ PR_fprintf(PR_STDERR,"Error wrapping macKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ kekKey16 = PK11_Derive(new_kek_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+
+ if ( kekKey16 == NULL ) {
+ goto done;
+ PR_fprintf(PR_STDERR,"Error deriving kekKey16. Error %d \n", PR_GetError());
+ }
- Buffer encrypted_mac_key(16);
- EncryptData(old_kek_key2, new_mac_key, encrypted_mac_key);
- Buffer kc_mac_key(3);
- ComputeKeyCheck(new_mac_key, kc_mac_key);
+ wrappedKeyItem.data = (unsigned char *) encrypted_kek_key;
+ wrappedKeyItem.len = encrypted_mac_key.size();
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, kekKey16, &wrappedKeyItem);
+ if ( wrapStatus == SECFailure) {
+ PR_fprintf(PR_STDERR,"Error wrapping kekKey16. Error %d \n", PR_GetError());
+ goto done;
+ }
+
+ ComputeKeyCheckWithSymKey(new_auth_key, kc_auth_key);
- Buffer encrypted_kek_key(16);
- EncryptData(old_kek_key2, new_kek_key, encrypted_kek_key);
- Buffer kc_kek_key(3);
- ComputeKeyCheck(new_kek_key, kc_kek_key);
+ ComputeKeyCheckWithSymKey(new_mac_key, kc_mac_key);
+
+ ComputeKeyCheckWithSymKey(new_kek_key, kc_kek_key);
result = newMasterVer +
Buffer(1, (BYTE)0x81) +
@@ -828,16 +811,46 @@ PRStatus CreateKeySetData( Buffer &newMasterVer, Buffer &old_kek_key2, Buffer &n
encrypted_kek_key +
Buffer(1, (BYTE)0x03) +
kc_kek_key;
- }
output = result;
rv = PR_SUCCESS;
+
+done:
+
+ if ( kekKey16 != NULL) {
+ PK11_FreeSymKey( kekKey16);
+ kekKey16 = NULL;
+ }
+
+ if ( authKey16 != NULL) {
+ PK11_FreeSymKey( authKey16);
+ authKey16 = NULL;
+ }
+
+ if ( macKey16 != NULL) {
+ PK11_FreeSymKey( macKey16);
+ macKey16 = NULL;
+ }
+
+ if ( slot != NULL ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if ( transportKey != NULL ) {
+ PK11_FreeSymKey( transportKey);
+ transportKey = NULL;
+ }
+
return rv;
}
-
void GetDiversificationData(jbyte *cuidValue,BYTE *KDC,keyType keytype)
{
+ if( ( cuidValue == NULL) || ( KDC == NULL)) {
+ return;
+ }
+
BYTE *lastTwoBytesOfAID = (BYTE *)cuidValue;
// BYTE *ICFabricationDate = (BYTE *)cuidValue + 2;
BYTE *ICSerialNumber = (BYTE *)cuidValue + 4;
@@ -881,6 +894,10 @@ void GetDiversificationData(jbyte *cuidValue,BYTE *KDC,keyType keytype)
static int getMasterKeyVersion(char *newMasterKeyNameChars)
{
+ if( newMasterKeyNameChars == NULL ||
+ strlen( newMasterKeyNameChars) < 3) {
+ return 0;
+ }
char masterKeyVersionNumber[3];
masterKeyVersionNumber[0]=newMasterKeyNameChars[1];
@@ -890,12 +907,25 @@ static int getMasterKeyVersion(char *newMasterKeyNameChars)
return newMasterKeyVesion;
}
+char *GetSharedSecretKeyName(char *newKeyName) {
+ if ( newKeyName && strlen( newKeyName ) > 0 ) {
+ if( strlen( sharedSecretSymKeyName) == 0) {
+ strncpy( sharedSecretSymKeyName, newKeyName, KEYNAMELENGTH);
+ }
+ }
+
+ return (char *) sharedSecretSymKeyName ;
+}
void getFullName(char * fullMasterKeyName, char * masterKeyNameChars )
{
+ if( fullMasterKeyName == NULL || masterKeyNameChars == NULL
+ || ( strlen(fullMasterKeyName) + strlen(masterKeyNameChars)) > KEYNAMELENGTH) {
+ return;
+ }
fullMasterKeyName[0]='\0';
if(strlen(masterKeyPrefix)>0)
- strcpy(fullMasterKeyName,masterKeyPrefix);
+ strncpy(fullMasterKeyName,masterKeyPrefix, KEYNAMELENGTH);
strcat(fullMasterKeyName,masterKeyNameChars);
}
@@ -906,9 +936,9 @@ void getFullName(char * fullMasterKeyName, char * masterKeyNameChars )
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)[B
*/
extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey
-(JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jbyteArray, jbyteArray, jstring);
+(JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jbyteArray, jbyteArray, jstring, jstring);
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey( JNIEnv * env, jclass this2, jstring tokenName,jstring newTokenName, jstring oldMasterKeyName, jstring newMasterKeyName, jstring keyInfo, jbyteArray CUIDValue, jbyteArray kekKeyArray, jstring useSoftToken_s)
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey( JNIEnv * env, jclass this2, jstring tokenName,jstring newTokenName, jstring oldMasterKeyName, jstring newMasterKeyName, jstring keyInfo, jbyteArray CUIDValue, jbyteArray kekKeyArray, jstring useSoftToken_s, jstring keySet)
{
PK11SymKey *encKey = NULL;
PK11SymKey *macKey = NULL;
@@ -923,22 +953,17 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
char fullNewMasterKeyName[KEYNAMELENGTH];
PRBool specified_key_is_present = PR_TRUE;
PK11SymKey *old_kek_sym_key = NULL;
- SECStatus s;
- jbyte * cuidValue = (jbyte*)(env)->GetByteArrayElements( CUIDValue, NULL);
-
- BYTE *encKeyData = NULL;
- BYTE *macKeyData = NULL;
- BYTE *kekKeyData = NULL;
-
- BYTE KDCenc[KEYLENGTH];
- BYTE KDCmac[KEYLENGTH];
- BYTE KDCkek[KEYLENGTH];
- jbyte * old_kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ char *keySetStringChars = NULL;
+ if ( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
- GetDiversificationData(cuidValue,KDCenc,enc);
- GetDiversificationData(cuidValue,KDCmac,mac);
- GetDiversificationData(cuidValue,KDCkek,kek);
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
jbyteArray handleBA=NULL;
jbyte *handleBytes=NULL;
@@ -946,44 +971,87 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
/* find slot */
char *tokenNameChars = NULL;
+ char * newMasterKeyNameChars = NULL;
PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ Buffer output;
+ PK11SlotInfo *newSlot =NULL;
+ char * newTokenNameChars = NULL;
+ char *keyInfoChars = NULL;
+
+ jbyte * cuidValue = NULL;
+ jbyte * old_kek_key = NULL;
+
+ PK11SymKey * masterKey = NULL;
+ PK11SymKey * oldMasterKey = NULL;
+
+ BYTE KDCenc[KEYLENGTH];
+ BYTE KDCmac[KEYLENGTH];
+ BYTE KDCkek[KEYLENGTH];
+
+ if( CUIDValue != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUIDValue, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if( kekKeyArray != NULL) {
+ old_kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ }
+
+ if( old_kek_key == NULL) {
+ goto done;
+ }
+
+ PR_fprintf(PR_STDOUT,"In SessionKey.DiversifyKey! \n");
+
+ GetDiversificationData(cuidValue,KDCenc,enc);
+ GetDiversificationData(cuidValue,KDCmac,mac);
+ GetDiversificationData(cuidValue,KDCkek,kek);
if(tokenName)
{
tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
slot = ReturnSlot(tokenNameChars);
- (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ PR_fprintf(PR_STDOUT,"DiversifyKey: tokenNameChars %s slot %p \n", tokenNameChars,slot);
+ if( tokenNameChars != NULL) {
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
}
- /* find masterkey */
- char * newMasterKeyNameChars = NULL;
if(newMasterKeyName)
{
/* newMasterKeyNameChars #02#01 */
newMasterKeyNameChars= (char *)(env)->GetStringUTFChars(newMasterKeyName, NULL);
}
-
/* fullNewMasterKeyName - no prefix #02#01 */
getFullName(fullNewMasterKeyName,newMasterKeyNameChars);
- Buffer output;
- PK11SlotInfo *newSlot =NULL;
- char * newTokenNameChars = NULL;
+ PR_fprintf(PR_STDOUT,"DiversifyKey: fullNewMasterKeyName %s . \n", fullNewMasterKeyName);
+
if(newTokenName)
{
newTokenNameChars = (char *)(env)->GetStringUTFChars(newTokenName, NULL);
newSlot = ReturnSlot(newTokenNameChars);
- (env)->ReleaseStringUTFChars(newTokenName, (const char *)newTokenNameChars);
+ PR_fprintf(PR_STDOUT,"DiversifyKey: newTokenNameChars %s newSlot %p . \n", newTokenNameChars,newSlot);
+ if( newTokenNameChars != NULL) {
+ (env)->ReleaseStringUTFChars(newTokenName, (const char *)newTokenNameChars);
+ }
}
- PK11SymKey * masterKey = ReturnSymKey(newSlot,fullNewMasterKeyName);
- if(newMasterKeyNameChars)
- {
+ masterKey = ReturnSymKey(newSlot,fullNewMasterKeyName);
+
+ if(newMasterKeyNameChars) {
(env)->ReleaseStringUTFChars(newMasterKeyName, (const char *)newMasterKeyNameChars);
}
/* packing return */
- char *keyInfoChars;
- keyInfoChars = (char *)(env)->GetStringUTFChars(keyInfo, NULL);
+ if( keyInfo != NULL) {
+ keyInfoChars = (char *)(env)->GetStringUTFChars(keyInfo, NULL);
+ }
+
newMasterKeyVesion = getMasterKeyVersion(keyInfoChars);
if(keyInfoChars)
@@ -996,40 +1064,60 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
if(oldMasterKeyName)
{
oldMasterKeyNameChars = (char *)(env)->GetStringUTFChars(oldMasterKeyName, NULL);
+ PR_fprintf(PR_STDOUT,"DiversifyKey oldMasterKeyNameChars %s \n", oldMasterKeyNameChars);
}
getFullName(fullMasterKeyName,oldMasterKeyNameChars);
-
- if(newSlot == NULL)
- {
+ PR_fprintf(PR_STDOUT,"DiversifyKey fullMasterKeyName %s \n", fullMasterKeyName);
+ if(newSlot == NULL) {
newSlot = slot;
}
if(strcmp( oldMasterKeyNameChars, "#01#01") == 0 || strcmp( oldMasterKeyNameChars, "#FF#01") == 0)
{
- old_kek_key_buff = Buffer((BYTE*)old_kek_key, 16);
+ old_kek_key_buff = Buffer((BYTE*)old_kek_key, KEYLENGTH);
}else if(strcmp( oldMasterKeyNameChars, "#00#00") == 0)
{
-
/* print Debug message - do not create real keysetdata */
old_kek_key_buff = Buffer((BYTE*)"#00#00", 6);
- output = Buffer((BYTE*)old_kek_key, 16);
+ output = Buffer((BYTE*)old_kek_key, KEYLENGTH);
}
else
{
- PK11SymKey * oldMasterKey = ReturnSymKey(slot,fullMasterKeyName);
+ oldMasterKey = ReturnSymKey(slot,fullMasterKeyName);
old_kek_sym_key = ComputeCardKeyOnToken(oldMasterKey,KDCkek);
- if (oldMasterKey)
+ if (oldMasterKey) {
PK11_FreeSymKey( oldMasterKey );
+ oldMasterKey = NULL;
+ }
}
- if(oldMasterKeyNameChars)
+ if(oldMasterKeyNameChars) {
(env)->ReleaseStringUTFChars(oldMasterKeyName, (const char *)oldMasterKeyNameChars);
+ }
/* special case #01#01 */
if (fullNewMasterKeyName != NULL && strcmp(fullNewMasterKeyName, "#01#01") == 0)
{
- encKeyData = (BYTE*)old_kek_key;
- macKeyData = (BYTE*)old_kek_key;
- kekKeyData = (BYTE*)old_kek_key;
+ Buffer empty = Buffer();
+
+ encKey = ReturnDeveloperSymKey(internal,(char *) "auth", keySetString, empty);
+
+ if ( encKey == NULL ) {
+ goto done;
+ }
+ PR_fprintf(PR_STDOUT, "Special case dev key set for DiversifyKey!\n");
+
+ macKey = ReturnDeveloperSymKey(internal, (char *) "mac", keySetString, empty);
+ if ( macKey == NULL ) {
+ goto done;
+ }
+
+ kekKey = ReturnDeveloperSymKey(internal, (char *) "kek", keySetString, empty);
+
+ if ( kekKey == NULL ) {
+ goto done;
+ }
+
} else {
+ PR_fprintf(PR_STDOUT,"DiversifyKey: Compute card key on token case ! \n");
/* compute card key */
encKey = ComputeCardKeyOnSoftToken(masterKey, KDCenc);
macKey = ComputeCardKeyOnSoftToken(masterKey, KDCmac);
@@ -1039,73 +1127,65 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
* is not present -- for each portion of the key, check if
* the PK11SymKey is NULL before sending it to PK11_GetKeyData()!
*/
- if( encKey != NULL)
- {
- s = PK11_ExtractKeyValue(encKey);
- encKeyData = (BYTE*)(PK11_GetKeyData(encKey)->data);
- }
- else
- {
+ if( encKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't create encKey in DiversifyKey! \n");
specified_key_is_present = PR_FALSE;
goto done;
}
- if( macKey != NULL)
- {
- s = PK11_ExtractKeyValue(macKey);
- macKeyData = (BYTE*)(PK11_GetKeyData(macKey)->data);
- }
- else
- {
+ if( macKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't create macKey in DiversifyKey! \n");
specified_key_is_present = PR_FALSE;
goto done;
}
- if( kekKey != NULL)
- {
- s = PK11_ExtractKeyValue(kekKey);
- kekKeyData = (BYTE*)(PK11_GetKeyData(kekKey)->data);
- }
- else
- {
+ if( kekKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't create kekKey in DiversifyKey! \n");
specified_key_is_present = PR_FALSE;
goto done;
}
-
}
- encKeyBuff = Buffer(encKeyData, 16);
- macKeyBuff = Buffer(macKeyData, 16);
- kekKeyBuff = Buffer(kekKeyData, 16);
-
- /* decide to whether to create the new key set by using a sym key or
- a buffered key */
- if (old_kek_sym_key != NULL)
- {
- CreateKeySetDataWithKey(newMasterKeyBuffer,
+ if (old_kek_sym_key != NULL) {
+ CreateKeySetDataWithSymKeys(newMasterKeyBuffer, Buffer(),
old_kek_sym_key,
- encKeyBuff,
- macKeyBuff,
- kekKeyBuff,
- output);
- }
- else
- {
- CreateKeySetData(newMasterKeyBuffer,
- old_kek_key_buff,
- encKeyBuff,
- macKeyBuff,
- kekKeyBuff,
+ encKey,
+ macKey,
+ kekKey,
+ output); }
+ else {
+ old_kek_sym_key = ReturnDeveloperSymKey(slot, (char *) "kek", keySetString, old_kek_key_buff);
+ CreateKeySetDataWithSymKeys(newMasterKeyBuffer, Buffer(),
+ old_kek_sym_key,
+ encKey,
+ macKey,
+ kekKey,
output);
}
done:
- if (masterKey != NULL)
+ if (masterKey != NULL) {
PK11_FreeSymKey( masterKey);
- if (encKey != NULL)
+ masterKey = NULL;
+ }
+
+ if (encKey != NULL) {
PK11_FreeSymKey( encKey );
- if (macKey != NULL)
+ encKey = NULL;
+ }
+
+ if (macKey != NULL) {
PK11_FreeSymKey( macKey );
- if (kekKey != NULL)
+ macKey = NULL;
+ }
+
+ if (kekKey != NULL) {
PK11_FreeSymKey( kekKey );
+ kekKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
if( specified_key_is_present )
{
@@ -1116,20 +1196,188 @@ done:
handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
memcpy(handleBytes, (BYTE*)output,output.size());
- (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ if( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+ }
+
+ if( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUIDValue, cuidValue, JNI_ABORT);
+ }
+
+ if( kekKeyArray != NULL) {
+ (env)->ReleaseByteArrayElements(kekKeyArray, old_kek_key, JNI_ABORT);
}
- (env)->ReleaseByteArrayElements(CUIDValue, cuidValue, JNI_ABORT);
+ if((newSlot != slot) && newSlot) {
+ PK11_FreeSlot( newSlot);
+ newSlot = NULL;
+ }
- if((newSlot != slot)&& newSlot)
- PK11_FreeSlot( newSlot );
- if( slot )
- PK11_FreeSlot( slot );
+ if( slot ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if( internal) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
return handleBA;
+}
+
+PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey, BYTE *keyToBeUnWrapped, int sizeOfKeyToBeUnWrapped, PRBool isPerm)
+{
+ PK11SymKey * unWrappedSymKey = NULL;
+ int bufSize = 48;
+ unsigned char outbuf[bufSize];
+ int final_len = 0;
+ SECStatus s = SECSuccess;
+ PK11Context * EncContext = NULL;
+ SECItem unWrappedKeyItem = { siBuffer, NULL, 0};
+ PK11SymKey *unwrapper = NULL;
+
+ PR_fprintf( PR_STDOUT,
+ "Creating UnWrappedSymKey on token. \n");
+
+ if ( (slot == NULL) || (unWrappingKey == NULL) ||
+ (keyToBeUnWrapped == NULL) ||
+ (sizeOfKeyToBeUnWrapped != DES3_LENGTH)
+ ) {
+ return NULL;
+ }
+
+ PK11SlotInfo *unwrapKeySlot = PK11_GetSlotFromKey( unWrappingKey );
+
+ if ( unwrapKeySlot != slot ) {
+ unwrapper = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, unWrappingKey);
+ }
+
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ if ( SecParam == NULL) {
+ goto done;
+ }
+
+ EncContext = PK11_CreateContextBySymKey(CKM_DES3_ECB,
+ CKA_ENCRYPT,
+ unWrappingKey, SecParam);
+
+ if ( EncContext == NULL) {
+ goto done;
+ }
+
+ s = PK11_CipherOp(EncContext, outbuf, &final_len, sizeof( outbuf), keyToBeUnWrapped,
+ sizeOfKeyToBeUnWrapped);
+
+ if ( s != SECSuccess) {
+ goto done;
+ }
+
+ if ( final_len != DES3_LENGTH ) {
+ goto done;
+ }
+
+ unWrappedKeyItem.data = outbuf;
+ unWrappedKeyItem.len = final_len;
+
+
+ /* Now try to unwrap our key into the token */
+ unWrappedSymKey = PK11_UnwrapSymKeyWithFlagsPerm(unwrapper ? unwrapper : unWrappingKey,
+ CKM_DES3_ECB,SecParam, &unWrappedKeyItem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ sizeOfKeyToBeUnWrapped, 0, isPerm );
+
+done:
+
+ if( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+ if( EncContext != NULL ) {
+ PK11_DestroyContext(EncContext, PR_TRUE);
+ EncContext = NULL;
+ }
+
+ if( unwrapper != NULL ) {
+ PK11_FreeSymKey( unwrapper );
+ unwrapper = NULL;
+ }
+
+ if( unwrapKeySlot != NULL) {
+ PK11_FreeSlot( unwrapKeySlot);
+ unwrapKeySlot = NULL;
+ }
+
+ PR_fprintf( PR_STDOUT,
+ "UnWrappedSymKey on token result: %p \n",unWrappedSymKey);
+
+ return unWrappedSymKey;
}
+//Return default keyset developer key. Either auth, mac, or kek
+PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySet, Buffer &inputKey)
+{
+ const int maxKeyNameSize = 56;
+ PK11SymKey *devSymKey = NULL;
+ PK11SymKey *transportKey = NULL;
+ char devKeyName[maxKeyNameSize];
+
+ SECStatus rv = SECSuccess;
+
+ BYTE sessionKey[DES3_LENGTH];
+ if( slot == NULL || keyType == NULL || keySet == NULL) {
+ return NULL;
+ }
+
+ snprintf(devKeyName,maxKeyNameSize,"%s-%sKey", keySet, keyType);
+
+ devSymKey = ReturnSymKey( slot, devKeyName );
+
+ // Try to create the key once and leave it there.
+ if( devSymKey == NULL ) {
+ PR_fprintf(PR_STDOUT, "Can't find devSymKey, try to create it on token. \n");
+ if ( inputKey.size() == DES2_LENGTH ) { //Any other size ignored
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+
+ if( transportKey == NULL) {
+ PR_fprintf(PR_STDERR,"Can't get transport key in ReturnDeveloperSymKey! \n");
+ goto done;
+ }
+
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(sessionKey, inputKey, DES2_LENGTH);
+ memcpy(sessionKey+ DES2_LENGTH, inputKey, EIGHT_BYTES);
+
+ //Unwrap this thing on there as permanent, so we don't have to create it again for a given keySet.
+ if( transportKey) {
+ devSymKey = CreateUnWrappedSymKeyOnToken( slot, transportKey, sessionKey, sizeof(sessionKey), PR_TRUE);
+ }
+
+ PR_fprintf(PR_STDERR,"Tried to create devSymKey %p \n",devSymKey);
+
+ rv = SECSuccess;
+ if( devSymKey ) {
+ rv = PK11_SetSymKeyNickname( devSymKey, devKeyName );
+
+ if ( rv != SECSuccess ) {
+ PR_fprintf(PR_STDERR, "Can't set the nickname of just written devKey! \n");
+ }
+ }
+ }
+ }
+
+done:
+ if( transportKey ) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ // Dont' free slot , let the caller.
+ return devSymKey;
+}
/*
* Class: com_netscape_cms_servlet_tks_RASessionKey
diff --git a/pki/base/symkey/src/com/netscape/symkey/SymKey.h b/pki/base/symkey/src/com/netscape/symkey/SymKey.h
index 2f98d044..5a53d48c 100644
--- a/pki/base/symkey/src/com/netscape/symkey/SymKey.h
+++ b/pki/base/symkey/src/com/netscape/symkey/SymKey.h
@@ -28,17 +28,27 @@ typedef enum {
} keyType;
#define KEYLENGTH 16
#define PREFIXLENGHT 128
+#define DES2_LENGTH 16
+#define DES3_LENGTH 24
+#define EIGHT_BYTES 8
#define KEYNAMELENGTH PREFIXLENGHT+7
+#define TRANSPORT_KEY_NAME "sharedSecret"
+#define DEFKEYSET_NAME "defKeySet"
extern char masterKeyPrefix[PREFIXLENGHT];
+extern char sharedSecretSymKeyName[KEYNAMELENGTH];
void GetDiversificationData(jbyte *cuidValue,BYTE *KDC,keyType keytype);
PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname);
void GetKeyName(jbyte *keyVersion,char *keyname);
PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data);
-PRStatus EncryptDataWithCardKey(PK11SymKey *card_key, Buffer &input, Buffer &output);
+PRStatus EncryptData(const Buffer &kek_key, PK11SymKey *card_key, Buffer &input, Buffer &output);
PK11SlotInfo *ReturnSlot(char *tokenNameChars);
PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot);
+PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey, BYTE *keyToBeUnWrapped, int sizeOfKeyToBeUnWrapped, PRBool isPerm);
+PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySet, Buffer &inputKey);
+
+char *GetSharedSecretKeyName(char *newKeyName);
#define DES2_WORKAROUND
#endif /* _TKSSYMKEY_H_ */
diff --git a/pki/base/tks/shared/conf/CS.cfg.in b/pki/base/tks/shared/conf/CS.cfg.in
index fbe2d24c..f06b2c5d 100644
--- a/pki/base/tks/shared/conf/CS.cfg.in
+++ b/pki/base/tks/shared/conf/CS.cfg.in
@@ -313,10 +313,12 @@ tks._000=##
tks._001=## TKS
tks._002=##
tks._003=##
+tks._004=##
tks.debug=false
tks.defaultSlot=Internal Key Storage Token
tks.drm_transport_cert_nickname=
tks.master_key_prefix=
+tks.tksSharedSymKeyName=sharedSecret
tks.useDefaultSlot=true
usrgrp._000=##
usrgrp._001=## User/Group
diff --git a/pki/base/tps/doc/CS.cfg.in b/pki/base/tps/doc/CS.cfg.in
index 7ec1e287..5fecf354 100644
--- a/pki/base/tps/doc/CS.cfg.in
+++ b/pki/base/tps/doc/CS.cfg.in
@@ -177,7 +177,9 @@ conn.tks1._022=# - enable keep alive or not
conn.tks1._023=#
conn.tks1._024=# where
conn.tks1._025=# <n> - TKS connection ID
-conn.tks1._026=#########################################
+conn.tks1._026=# conn.tks<n>.tksSharedSymKeyName:
+conn.tks1._027=# - set shared secret key name
+conn.tks1._028=#########################################
conn.tks1.hostport=[TKS_HOST]:[TKS_PORT]
conn.tks1.clientNickname=[HSM_LABEL][NICKNAME]
conn.tks1.servlet.computeSessionKey=/tks/agent/tks/computeSessionKey
@@ -191,6 +193,7 @@ conn.tks1.SSLOn=true
conn.tks1.keepAlive=false
conn.tks1.keySet=defKeySet
conn.tks1.serverKeygen=[SERVER_KEYGEN]
+conn.tks1.tksSharedSymKeyName=sharedSecret
conn.drm1._000=#########################################
conn.drm1._001=# DRM connection
conn.drm1._002=#
diff --git a/pki/base/tps/src/engine/RA.cpp b/pki/base/tps/src/engine/RA.cpp
index 0491b6db..19c445f9 100644
--- a/pki/base/tps/src/engine/RA.cpp
+++ b/pki/base/tps/src/engine/RA.cpp
@@ -61,6 +61,19 @@ extern "C"
#include "main/RollingLogFile.h"
#include "selftests/SelfTest.h"
+typedef struct
+{
+ enum
+ {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+
static ConfigStore *m_cfg = NULL;
static LogFile* m_debug_log = (LogFile *)NULL;
static LogFile* m_error_log = (LogFile *)NULL;
@@ -1501,6 +1514,10 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
const char *connId)
{
PK11SymKey *symKey = NULL;
+ PK11SymKey *symKey24 = NULL;
+ PK11SymKey *encSymKey24 = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *encSymKey16 = NULL;
char body[MAX_BODY_LEN];
char configname[256];
char * cardc = NULL;
@@ -1511,6 +1528,8 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
PSHttpResponse *response = NULL;
HttpConnection *tksConn = NULL;
RA_pblock *ra_pb = NULL;
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ char* transportKeyName = NULL;
RA::Debug(LL_PER_PDU, "Start ComputeSessionKey", "");
tksConn = RA::GetTKSConn(connId);
@@ -1621,6 +1640,21 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
}
}
+ // Now unwrap the session keys with shared secret transport key
+
+ PR_snprintf((char *)configname, 256, "conn.%s.tksSharedSymKeyName", connId);
+
+ transportKeyName = (char *) m_cfg->GetConfigAsString(configname, TRANSPORT_KEY_NAME);
+
+ RA::Debug(LL_PER_PDU,"RA:ComputeSessionKey","Shared Secret key name: %s.", transportKeyName);
+
+ transportKey = FindSymKeyByName( slot, transportKeyName);
+
+ if ( transportKey == NULL ) {
+ RA::Debug(LL_PER_PDU,"RA::ComputeSessionKey","fail getting transport key");
+ goto loser;
+ }
+
sessionKey_s = ra_pb->find_val_s(TKS_RESPONSE_SessionKey);
if (sessionKey_s == NULL) {
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no sessionKey_b");
@@ -1632,21 +1666,24 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "decodekey len=%d",decodeKey->size());
- BYTE masterKeyData[24];
- SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData)};
BYTE *keyData = (BYTE *)*decodeKey;
- memcpy(masterKeyData, (char*)keyData, 16);
- memcpy(masterKeyData+16, (char*)keyData, 8);
+ SECItem wrappeditem = {siBuffer , keyData, 16 };
- symKey = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
+ symKey = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( symKey ) {
+ symKey24 = CreateDesKey24Byte(slot, symKey);
+ }
if( decodeKey != NULL ) {
delete decodeKey;
decodeKey = NULL;
}
- if (symKey == NULL)
+ if (symKey24 == NULL)
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "MAC Session key is NULL");
@@ -1662,27 +1699,30 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey",
"decodeEnckey len=%d",decodeEncKey->size());
- BYTE masterEncKeyData[24];
- SECItem masterEncKeyItem =
- {siBuffer, masterEncKeyData, sizeof(masterEncKeyData)};
BYTE *EnckeyData = (BYTE *)*decodeEncKey;
- memcpy(masterEncKeyData, (char*)EnckeyData, 16);
- memcpy(masterEncKeyData+16, (char*)EnckeyData, 8);
+ wrappeditem.data = (unsigned char *) EnckeyData;
+ wrappeditem.len = 16;
+
+ encSymKey16 = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( encSymKey16 ) {
+ encSymKey24 = CreateDesKey24Byte(slot, encSymKey16);
+ }
- *encSymKey =
- PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterEncKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
+ *encSymKey = encSymKey24;
if( decodeEncKey != NULL ) {
delete decodeEncKey;
decodeEncKey = NULL;
}
- if (encSymKey == NULL)
+ if (encSymKey24 == NULL)
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "encSessionKey is NULL");
-
if (serverKeygen) {
char * tmp= NULL;
tmp = ra_pb->find_val_s(TKS_RESPONSE_DRM_Trans_DesKey);
@@ -1761,13 +1801,28 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
response = NULL;
}
+ if ( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
if (ra_pb != NULL) {
delete ra_pb;
}
+
+ if ( symKey != NULL ) {
+ PK11_FreeSymKey( symKey );
+ symKey = NULL;
+ }
+
+ if ( encSymKey16 != NULL ) {
+ PK11_FreeSymKey( encSymKey16 );
+ encSymKey16 = NULL;
+ }
+
// in production, if TKS is unreachable, symKey will be NULL,
// and this will signal error to the caller.
- return symKey;
-
+ return symKey24;
}
Buffer *RA::ComputeHostCryptogram(Buffer &card_challenge,
@@ -3420,3 +3475,147 @@ TPS_PUBLIC bool RA::verifySystemCerts() {
return rv;
}
+
+PK11SymKey *RA::FindSymKeyByName( PK11SlotInfo *slot, char *keyname) {
+char *name = NULL;
+ PK11SymKey *foundSymKey= NULL;
+ PK11SymKey *firstSymKey= NULL;
+ PK11SymKey *sk = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ secuPWData pwdata;
+
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ if (keyname == NULL)
+ {
+ goto cleanup;
+ }
+ if (slot== NULL)
+ {
+ goto cleanup;
+ }
+ /* Initialize the symmetric key list. */
+ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
+ /* scan through the symmetric key list for a key matching our nickname */
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ /* get the nickname of this symkey */
+ name = PK11_GetSymKeyNickname( sk );
+
+ /* if the name matches, make a 'copy' of it */
+ if ( name != NULL && !strcmp( keyname, name ))
+ {
+ if (foundSymKey == NULL)
+ {
+ foundSymKey = PK11_ReferenceSymKey(sk);
+ }
+ PORT_Free(name);
+ }
+
+ sk = PK11_GetNextSymKey( sk );
+ }
+
+ /* We're done with the list now, let's free all the keys in it
+ It's okay to free our key, because we made a copy of it */
+
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ nextSymKey = PK11_GetNextSymKey(sk);
+ PK11_FreeSymKey(sk);
+ sk = nextSymKey;
+ }
+
+ cleanup:
+ return foundSymKey;
+}
+
+PK11SymKey *RA::CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey)
+{
+ PK11SymKey *newKey = NULL;
+ PK11SymKey *firstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *internalOrigKey = NULL;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_OBJECT_HANDLE keyhandle = 0;
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "entering.");
+
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ if ( slot == NULL || origKey == NULL || internal == NULL)
+ goto loser;
+
+ if( internal != slot ) { //Make sure we do this on the NSS Generic Crypto services because concatanation
+ // only works there.
+ internalOrigKey = PK11_MoveSymKey( internal, CKA_ENCRYPT, 0, PR_FALSE, origKey );
+ }
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ if ( internalOrigKey)
+ firstEight = PK11_Derive(internalOrigKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+ else
+ firstEight = PK11_Derive(origKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+
+ if (firstEight == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error deriving 8 byte portion of key.");
+ goto loser;
+ }
+
+ //Concatenate 8 byte key to the end of the original key, giving new 24 byte key
+ keyhandle = PK11_GetSymKeyHandle(firstEight);
+
+ paramsItem.data=(unsigned char *) &keyhandle;
+ paramsItem.len=sizeof(keyhandle);
+
+ if ( internalOrigKey ) {
+ concatKey = PK11_Derive ( internalOrigKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ } else {
+ concatKey = PK11_Derive ( origKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ }
+
+ if ( concatKey == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error concatenating 8 bytes on end of key.");
+ goto loser;
+ }
+
+ //Make sure we move this to the proper token, in case it got moved by NSS
+ //during the derive phase.
+
+ newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, concatKey);
+
+ if ( newKey == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error moving key to original slot.");
+ }
+
+loser:
+
+ if ( concatKey != NULL ) {
+ PK11_FreeSymKey( concatKey );
+ concatKey = NULL;
+ }
+
+ if ( firstEight != NULL ) {
+ PK11_FreeSymKey ( firstEight );
+ firstEight = NULL;
+ }
+
+ if ( internalOrigKey != NULL ) {
+ PK11_FreeSymKey ( internalOrigKey );
+ internalOrigKey = NULL;
+ }
+
+ if ( internal != NULL ) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ return newKey;
+}
diff --git a/pki/base/tps/src/include/engine/RA.h b/pki/base/tps/src/include/engine/RA.h
index 8e860160..9e7db985 100644
--- a/pki/base/tps/src/include/engine/RA.h
+++ b/pki/base/tps/src/include/engine/RA.h
@@ -91,6 +91,8 @@ enum RA_Log_Level {
/* status of RA::Initialize( char *cfg_path, RA_Context *ctx ). */
#define RA_INITIALIZATION_SUCCESS 1
+#define TRANSPORT_KEY_NAME "sharedSecret"
+
typedef char NSSUTF8;
class RA
@@ -135,6 +137,9 @@ class RA
char **wrappedPrivateKey_s, const char *connId, char **ivParam_s);
static Buffer *ComputeHostCryptogram(Buffer &card_challenge, Buffer &host_challenge);
+
+ static PK11SymKey *FindSymKeyByName( PK11SlotInfo *slot, char *keyname);
+ static PK11SymKey *CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey);
public:
TPS_PUBLIC static ConfigStore *GetConfigStore();
TPS_PUBLIC static bool match_comma_list(const char* item, char *list);