summaryrefslogtreecommitdiffstats
path: root/base/tps
diff options
context:
space:
mode:
authorJack Magne <jmagne@dhcp-16-206.sjc.redhat.com>2016-06-01 10:23:33 -0700
committerJack Magne <jmagne@dhcp-16-206.sjc.redhat.com>2017-03-14 15:25:34 -0700
commit6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb (patch)
tree666adf630ac8316eb509bd9b32c7a36d12056879 /base/tps
parent648361bac96996e76339b9390b8a8882dcde8ad7 (diff)
downloadpki-6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb.tar.gz
pki-6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb.tar.xz
pki-6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb.zip
First cut of scp03 support. Supports the g&d smartcafe out of the box.
Developer keyset token operations and key change over supported. Caveats. -The diversification step going from master key to card key uses DES3 as required for the token. -After that point, everything is scp03 to the spec with minor excpetions so far. Supports 128 bit AES for now. Will resolve this. Minor config tweaks: TPS Symmetric Key Changeover Use this applet for scp03: RSA/KeyRecovery/GP211/SCP02/SCP03 applet : 1.5.558cdcff.ijc TKS: Symmetric Key Changeover tks.mk_mappings.#02#03=internal:new_master tks.defKeySet.mk_mappings.#02#03=internal:new_master Use the uncommented one because scp03 returns a different key set data string. ToDo: -Support the rest of the AES sizes other than 128. -Support optional RMAC apdu. -Test and adjust the config capability for other tokens. -Support AES master key. Right now the standard key ends up creating AES card and session keys.
Diffstat (limited to 'base/tps')
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java8
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java234
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/cms/TKSComputeSessionKeyResponse.java8
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java157
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java58
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java10
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java162
7 files changed, 576 insertions, 61 deletions
diff --git a/base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java b/base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java
index e5f38e108..e1de8f23d 100644
--- a/base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java
+++ b/base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java
@@ -62,6 +62,14 @@ public class PlatformAndSecChannelProtoInfo {
}
return false;
}
+
+ public boolean isSCP03() {
+ if(protocol == SecureChannel.SECURE_PROTO_03) {
+ return true;
+ }
+ return false;
+ }
+
public void setProtocol(byte protocol) {
this.protocol = protocol;
}
diff --git a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
index f2e32368f..fc5472c79 100644
--- a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
+++ b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
@@ -65,15 +65,22 @@ public class SecureChannel {
public TPSProcessor processor;
private PK11SymKey sessionKey;
- //SCP01 or SCP02 key
+ //SCP01 or SCP02 or SCP03 key
private PK11SymKey encSessionKey;
+
//SCP02 session keys
private PK11SymKey cmacSessionKey;
//Used for security level we do not yet suport.
+
+
+
private PK11SymKey rmacSessionKey;
private PK11SymKey dekSessionKey;
+ //SCP03
+ private PK11SymKey macSessionKey;
+
private TPSBuffer dekSessionKeyWrapped;
private TPSBuffer drmDesKey;
@@ -112,11 +119,65 @@ public class SecureChannel {
public final static byte[] GP201_GET_DATA_CPLC_WHOLE_CPLC = { (byte) 0x9F, (byte) 0x7F };
public final static byte[] GP211_GET_DATA_CPLC_WHOLE_CPLC = { (byte) 0x9F, (byte) 0x7F };
+ // SCP02
public final static byte[] C_MACDerivationConstant = { 0x01, 0x01 };
public final static byte[] ENCDerivationConstant = { (byte) 0x01, (byte) 0x82 };
public final static byte[] DEKDerivationConstant = { 0x01, (byte) 0x81 };
public final static byte[] R_MACDerivationConstant = { 0x01, 0x02 };
+ //SCP03 encryption counter
+
+ private TPSBuffer encryptionCounter;
+
+
+ //For SCP03
+
+ public SecureChannel(TPSProcessor processor, PK11SymKey encSessionKey, PK11SymKey macSessionKey, PK11SymKey dekSessionKey,
+ TPSBuffer drmDesKey,TPSBuffer kekDesKey,
+ TPSBuffer keyCheck, TPSBuffer keyDiversificationData, TPSBuffer cardChallenge,
+ TPSBuffer cardCryptogram, TPSBuffer hostChallenge, TPSBuffer hostCryptogram, TPSBuffer keyInfoData,
+ PlatformAndSecChannelProtoInfo platformInfo)
+ throws TPSException {
+
+ if (processor == null || encSessionKey == null || keyDiversificationData == null
+ || cardChallenge == null || cardCryptogram == null || hostChallenge == null || hostCryptogram == null
+ || keyInfoData == null) {
+ throw new TPSException("SecureChannel.SecureChannel: Invalid data in constructor!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("SecureChannel.SecureChannel: For SCP03. : ");
+
+ CMS.debug("kekDesKey: " + kekDesKey.toHexString());
+ CMS.debug("keyCheck: " + keyCheck.toHexString());
+
+ this.platProtInfo = platformInfo;
+ this.processor = processor;
+ this.encSessionKey = encSessionKey;
+ this.macSessionKey = macSessionKey;
+ this.dekSessionKey = dekSessionKey;
+
+ this.drmDesKey = drmDesKey;
+ this.setKekDesKey(kekDesKey);
+
+ this.keyCheck = keyCheck;
+ this.keyDiversificationData = keyDiversificationData;
+ this.cardChallenge = cardChallenge;
+ this.cardCryptogram = cardCryptogram;
+ this.hostChallenge = hostChallenge;
+ this.hostCryptogram = hostCryptogram;
+
+ //16 bytes of chaining value
+ this.icv = new TPSBuffer(16);
+
+ this.keyInfoData = keyInfoData;
+
+ this.secLevel = SecurityLevel.SECURE_MSG_NONE;
+ this.secLevelGP211 = ExternalAuthenticateAPDUGP211.SecurityLevel.CDEC_CMAC;
+ encryptionCounter = new TPSBuffer(16);
+
+ }
+
//For SCP01
public SecureChannel(TPSProcessor processor, PK11SymKey sessionKey, PK11SymKey encSessionKey, TPSBuffer drmDesKey,
TPSBuffer kekDesKey, TPSBuffer keyCheck, TPSBuffer keyDiversificationData, TPSBuffer cardChallenge,
@@ -345,12 +406,46 @@ public class SecureChannel {
public void externalAuthenticate() throws TPSException, IOException {
- CMS.debug("SecureChannel.externalAuthenticate: entering. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
+ String method = "SecureChannel.externalAuthenticate.";
+ CMS.debug(method + ": entering. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
- if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
+ TPSBuffer calculatedCardCryptogram = null;
+ if(platProtInfo.isSCP03()) {
+ CMS.debug("SecureChannel.externalAuthenticate: Attempting an External Authenticate for SCP03!");
+
+ TPSBuffer context = new TPSBuffer(hostChallenge);
+ context.add(cardChallenge);
+ try {
+ calculatedCardCryptogram = Util.compute_AES_CMAC_Cryptogram(macSessionKey, context, Util.CARD_CRYPTO_KDF_CONSTANT_SCP03);
+ } catch (EBaseException e) {
+ throw new TPSException(method + "Failed to calculate card cryptogram!", TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug(method + " dumped macSessionKey: " + new TPSBuffer(macSessionKey.getEncoded()).toHexString() );
+
+ CMS.debug(method + " actual card cryptogram " + cardCryptogram.toHexString());
+ CMS.debug(method + " calculated card cryptogram " + calculatedCardCryptogram.toHexString());
+
+ ExternalAuthenticateAPDUGP211 externalAuth = new ExternalAuthenticateAPDUGP211(hostCryptogram,
+ /* secLevel */secLevelGP211);
+
+ computeAPDUMacSCP03(externalAuth);
+
+ APDUResponse response = processor.handleAPDURequest(externalAuth);
+
+ if (!response.checkResult()) {
+ throw new TPSException(
+ "SecureChannel.eternalAuthenticate SCP03. Failed to external authenticate to token.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ }
+
+
+ if (platProtInfo.isSCP02()) {
CMS.debug("SecureChannel.externalAuthenticate: Attempting an External Authenticate for SCP02!");
- TPSBuffer calculatedCardCryptogram = computeCardCryptogramSCP02(encSessionKey);
+ calculatedCardCryptogram = computeCardCryptogramSCP02(encSessionKey);
if (false == cardCryptogram.equals(calculatedCardCryptogram)) {
@@ -383,7 +478,7 @@ public class SecureChannel {
CMS.debug("SecureChannel.externalAuthenticate: SCP02 external authenticate returns Success!!!");
- } else { //SCP01
+ } else if(platProtInfo.isSCP01()){ //SCP01
ExternalAuthenticateAPDU externalAuth = new ExternalAuthenticateAPDU(hostCryptogram,
/* secLevel */ExternalAuthenticateAPDU.SecurityLevel.SECURE_MSG_MAC_ENC);
@@ -410,15 +505,20 @@ public class SecureChannel {
CMS.debug("SecureChannel.computeAPDU: entering..");
+ if (apdu == null) {
+ throw new TPSException("SecureChannel.computeAPDU: bad input apdu!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
if (isSCP02()) {
computeAPDU_SCP02(apdu);
return;
}
- if (apdu == null) {
- throw new TPSException("SecureChannel.computeAPDU: bad input apdu!",
- TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ if (isSCP03() ) {
+ computeAPDU_SCP03(apdu);
+ return;
}
computeAPDUMac(apdu);
@@ -436,6 +536,60 @@ public class SecureChannel {
}
}
+ private void computeAPDU_SCP03(APDU apdu) throws TPSException {
+ String method = "SecureChannel.computeAPDU_SCP03:";
+
+ CMS.debug(method + "entering..");
+ if (apdu == null) {
+ throw new TPSException(method + " bad input apdu!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ if (secLevelGP211 == ExternalAuthenticateAPDUGP211.SecurityLevel.CDEC_CMAC) {
+ try {
+ //CMS.debug("SecureChannel.computeAPDU_SCP03: Before encryption data value: "
+ // + apdu.getData().toHexString());
+ this.incrementBuffer(encryptionCounter);
+ TPSBuffer currentEncryptionCounter = new TPSBuffer(encryptionCounter);
+ apdu.secureMessageSCP03(encSessionKey,currentEncryptionCounter);
+ ;
+ //CMS.debug("SecureChannel.computeAPDU_SCP03: After encryption data value: "
+ // + apdu.getData().toHexString());
+ } catch (EBaseException e) {
+ throw new TPSException("SecureChannel.computeAPDU_SCP03: Can't encrypt outgoing data! " + e);
+ }
+
+ CMS.debug("SecureChannel.computeAPDU_SCP03: Successfully encrypted apdu data.");
+ }
+
+ computeAPDUMacSCP03(apdu);
+ }
+
+ //Assume the whole buffer is to be incremented
+ //Used for SCP03 encrypted apdu messages
+ public void incrementBuffer(TPSBuffer buffer) {
+
+ if(buffer == null)
+ return;
+
+ int len = buffer.size();
+
+ if (len < 1)
+ return;
+ int offset = 0;
+ for (short i = (short) (offset + len - 1); i >= offset; i--) {
+ byte cur = buffer.at(i);
+ if (cur != (byte) 0xFF) {
+ cur++;
+ buffer.setAt(i, cur);
+ break;
+ } else
+ buffer.setAt(i,(byte) 0x00);
+ }
+
+ System.out.println("enc buffer: " + buffer.toHexString());
+ }
+
private void computeAPDU_SCP02(APDU apdu) throws TPSException {
CMS.debug("SecureChannel.computeAPDU_SCP02: entering..");
@@ -448,11 +602,11 @@ public class SecureChannel {
if (secLevelGP211 == ExternalAuthenticateAPDUGP211.SecurityLevel.CDEC_CMAC) {
try {
- CMS.debug("SecureChannel.computeAPDU_SCP02: Before encryption data value: "
- + apdu.getData().toHexString());
+ //CMS.debug("SecureChannel.computeAPDU_SCP02: Before encryption data value: "
+ // + apdu.getData().toHexString());
apdu.secureMessageSCP02(encSessionKey);
- CMS.debug("SecureChannel.computeAPDU_SCP02: After encryption data value: "
- + apdu.getData().toHexString());
+ //CMS.debug("SecureChannel.computeAPDU_SCP02: After encryption data value: "
+ // + apdu.getData().toHexString());
} catch (EBaseException e) {
throw new TPSException("SecureChannel.computeAPDU_SCP02: Can't encrypt outgoing data! " + e);
}
@@ -462,6 +616,48 @@ public class SecureChannel {
}
+ private void computeAPDUMacSCP03(APDU apdu) throws TPSException {
+ TPSBuffer newMac = null;
+ TPSBuffer data = null;
+
+ if (apdu == null) {
+ throw new TPSException("SecureChannel.computeAPDUMacSCP03: bad input apdu!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ data = apdu.getDataToMAC();
+
+ //CMS.debug("SecureChannel.computeAPDUMacSCP03: data To MAC: " + data.toHexString() + " incoming icv: "
+ // + icv.toHexString());
+
+ try {
+
+ CMS.debug("SecureChannel.computeAPDUMacSCP03: No ecnrypton of ICV.");
+
+ TPSBuffer dataToMac = new TPSBuffer(icv);
+ /// Prepend the chaining value to the data to be maced.
+ dataToMac.add(data);
+
+ //CMS.debug("SecureChannel.computeAPDUMacSCP03: final data To MAC: " + dataToMac.toHexString() + " incoming icv: "
+ // + icv.toHexString());
+
+ newMac = Util.computeAES_CMAC(macSessionKey, dataToMac);
+
+
+ } catch (EBaseException e) {
+ CMS.debug("SecureChannel.computeAPDUMacSCP03: Can't compute mac. " + e);
+ throw new TPSException("SecureChannel.compuatAPDUMacSCP03: Can't compute mac.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("SecureChannel.computeAPDUMacSCP03: computed MAC: " /* + newMac.toHexString() */);
+
+ apdu.setMAC(newMac.substr(0,8));
+
+ icv.set(newMac);
+
+ }
+
private void computeAPDUMacSCP02(APDU apdu) throws TPSException {
TPSBuffer newMac = null;
@@ -571,7 +767,7 @@ public class SecureChannel {
public void installLoad(TPSBuffer packageAID, TPSBuffer sdAID, int fileLength) throws TPSException, IOException {
CMS.debug("SecureChannel.installLoad: entering ... packageAID: " + packageAID.toHexString() + " sdAID: "
- + sdAID.toHexString());
+ + sdAID.toHexString() + " fileLength: " + fileLength);
if (packageAID == null || sdAID == null || fileLength <= 0) {
throw new TPSException("SecureChannel.insallLoad bad input parameters!",
@@ -1363,14 +1559,15 @@ public class SecureChannel {
PutKeyAPDU putKey = new PutKeyAPDU(keyVersion, (byte) 0x81, keySetData);
- if (isSCP02()) {
+ if (isSCP02() || isSCP03()) {
+ CMS.debug("SecureChannel.putKeys: adding trailing 0 byte");
TPSBuffer trailer = new TPSBuffer(1);
putKey.setTrailer(trailer);
}
computeAPDU(putKey);
- int kill = 0;
+ int kill = 0;
if (kill == 1) {
throw new TPSException("putKeys end of progress.");
}
@@ -1503,6 +1700,13 @@ public class SecureChannel {
}
+ public boolean isSCP03() {
+ if (platProtInfo.isSCP03())
+ return true;
+ else
+ return false;
+ }
+
public boolean isSCP02() {
if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
diff --git a/base/tps/src/org/dogtagpki/server/tps/cms/TKSComputeSessionKeyResponse.java b/base/tps/src/org/dogtagpki/server/tps/cms/TKSComputeSessionKeyResponse.java
index 2fe382539..910294e53 100644
--- a/base/tps/src/org/dogtagpki/server/tps/cms/TKSComputeSessionKeyResponse.java
+++ b/base/tps/src/org/dogtagpki/server/tps/cms/TKSComputeSessionKeyResponse.java
@@ -62,4 +62,12 @@ public class TKSComputeSessionKeyResponse extends RemoteResponse
public TPSBuffer getKekWrappedDesKey() {
return (TPSBuffer) nameValTable.get(IRemoteRequest.TKS_RESPONSE_KEK_DesKey);
}
+
+ public TPSBuffer getKekSessionKey() {
+ return (TPSBuffer) nameValTable.get(IRemoteRequest.TKS_RESPONSE_KekSessionKey);
+ }
+
+ public TPSBuffer getMacSessionKey() {
+ return (TPSBuffer) nameValTable.get(IRemoteRequest.TKS_RESPONSE_MacSessionKey);
+ }
}
diff --git a/base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java b/base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java
index f38d7def5..65d0ed0ac 100644
--- a/base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java
+++ b/base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java
@@ -226,6 +226,157 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
}
}
+ public TKSComputeSessionKeyResponse computeSessionKeysSCP03(
+ TPSBuffer kdd
+ ,TPSBuffer cuid,
+ TPSBuffer keyInfo,
+ TPSBuffer card_challenge,
+ TPSBuffer card_cryptogram,
+ TPSBuffer host_challenge,
+ String tokenType) throws EBaseException {
+
+ String method = "TKSRemoteRequestHandler: computeSessionKeysSCP03()";
+
+ CMS.debug(method + " Entering: ");
+
+ if (cuid == null || kdd == null || keyInfo == null || card_challenge == null ||
+ card_cryptogram == null || host_challenge == null || tokenType == null
+
+ ) {
+ throw new EBaseException(method + " invalid input!");
+ }
+
+ IConfigStore conf = CMS.getConfigStore();
+
+ boolean serverKeygen =
+ conf.getBoolean("op.enroll." +
+ tokenType + ".keyGen.encryption.serverKeygen.enable",
+ false);
+ if (keySet == null)
+ keySet = conf.getString("tps.connector." + connid + ".keySet", "defKeySet");
+
+ TPSSubsystem subsystem =
+ (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID);
+ HttpConnector conn =
+ (HttpConnector) subsystem.getConnectionManager().getConnector(connid);
+
+ String requestString = IRemoteRequest.SERVER_SIDE_KEYGEN + "=" + serverKeygen +
+ "&" + IRemoteRequest.TOKEN_KDD + "=" + Util.specialURLEncode(kdd) +
+ "&" + IRemoteRequest.TOKEN_CUID + "=" + Util.specialURLEncode(cuid) +
+ "&" + IRemoteRequest.TOKEN_CARD_CHALLENGE + "=" + Util.specialURLEncode(card_challenge) +
+ "&" + IRemoteRequest.TOKEN_HOST_CHALLENGE + "=" + Util.specialURLEncode(host_challenge) +
+ "&" + IRemoteRequest.TOKEN_KEYINFO + "=" + Util.specialURLEncode(keyInfo) +
+ "&" + IRemoteRequest.CHANNEL_PROTOCOL + "=" + SecureChannel.SECURE_PROTO_03 +
+ "&" + IRemoteRequest.TOKEN_CARD_CRYPTOGRAM + "="
+ + Util.specialURLEncode(card_cryptogram.toBytesArray()) +
+ "&" + IRemoteRequest.TOKEN_KEYSET + "=" + keySet;
+
+ HttpResponse resp =
+ conn.send("computeSessionKey",
+ requestString
+ );
+
+ String content = resp.getContent();
+
+ if (content != null && !content.equals("")) {
+ Hashtable<String, Object> response =
+ parseResponse(content);
+
+ /*
+ * When a value is not found in response, keep going so we know
+ * what else is missing
+ * Note: serverKeygen and !serverKeygen returns different set of
+ * response values so "missing" might not be bad
+ */
+ Integer ist = new Integer(IRemoteRequest.RESPONSE_STATUS_NOT_FOUND);
+ String value = (String) response.get(IRemoteRequest.RESPONSE_STATUS);
+ if (value == null) {
+ CMS.debug(method + " status not found.");
+ //CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): got content = " + content);
+ } else {
+ CMS.debug(method + " got status = " + value);
+ ist = Integer.parseInt(value);
+ }
+ response.put(IRemoteRequest.RESPONSE_STATUS, ist);
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_EncSessionKey);
+ if (value == null) {
+ CMS.debug(method + " response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_EncSessionKey);
+ } else {
+ CMS.debug(method+ "got IRemoteRequest.TKS_RESPONSE_EncSessionKey");
+ response.put(IRemoteRequest.TKS_RESPONSE_EncSessionKey, Util.specialDecode(value));
+ }
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_DRM_Trans_DesKey);
+ if (value == null) {
+ CMS.debug(method + " response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_DRM_Trans_DesKey);
+ } else {
+ CMS.debug(method + "got IRemoteRequest.TKS_RESPONSE_DRM_Trans_DesKey");
+ response.put(IRemoteRequest.TKS_RESPONSE_DRM_Trans_DesKey, Util.specialDecode(value));
+ }
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_MacSessionKey);
+ if (value == null) {
+ CMS.debug(method + "response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_MacSessionKey);
+ } else {
+ CMS.debug(method + " got IRemoteRequest.TKS_RESPONSE_MacSessionKey");
+ response.put(IRemoteRequest.TKS_RESPONSE_MacSessionKey, Util.specialDecode(value));
+
+ }
+
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_KekSessionKey);
+ if (value == null) {
+ CMS.debug(method + "response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_KekSessionKey);
+ } else {
+ CMS.debug(method + " got IRemoteRequest.TKS_RESPONSE_KekSessionKey");
+ response.put(IRemoteRequest.TKS_RESPONSE_KekSessionKey, Util.specialDecode(value));
+ }
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_KEK_DesKey);
+ if (value == null) {
+ CMS.debug(method + "response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_KEK_DesKey);
+ } else {
+ CMS.debug(method + " got IRemoteRequest.TKS_RESPONSE_KEK_DesKey");
+ response.put(IRemoteRequest.TKS_RESPONSE_KEK_DesKey, Util.specialDecode(value));
+
+ }
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_KeyCheck);
+
+ if (value == null) {
+ CMS.debug(method + "response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_KeyCheck);
+
+ } else {
+ CMS.debug(method + " got IRemoteRequest.TKS_RESPONSE_KeyCheck");
+ response.put(IRemoteRequest.TKS_RESPONSE_KeyCheck, Util.specialDecode(value));
+ }
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_HostCryptogram);
+ if ( value == null ) {
+ CMS.debug(method + " response missing name-value pair for: " + IRemoteRequest.TKS_RESPONSE_HostCryptogram);
+ } else {
+ CMS.debug(method + " got " + IRemoteRequest.TKS_RESPONSE_HostCryptogram);
+ response.put(IRemoteRequest.TKS_RESPONSE_HostCryptogram, Util.specialDecode(value));
+ }
+
+ CMS.debug(method + " ends.");
+
+ return new TKSComputeSessionKeyResponse(response);
+
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): no response content.");
+ throw new EBaseException("TKSRemoteRequestHandler: computeSessionKeySCP02(): no response content.");
+ }
+
+ }
+
/*
* computeSessionKey
*
@@ -559,7 +710,7 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
TPSBuffer kdd,
TPSBuffer cuid,
TPSBuffer version,
- TPSBuffer inData)
+ TPSBuffer inData,int protocol)
throws EBaseException {
CMS.debug("TKSRemoteRequestHandler: encryptData(): begins.");
if (cuid == null || kdd == null || version == null || inData == null) {
@@ -582,7 +733,9 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
"&" + IRemoteRequest.TOKEN_CUID + "=" + Util.specialURLEncode(cuid) +
"&" + IRemoteRequest.TOKEN_KDD + "=" + Util.specialURLEncode(kdd) +
"&" + IRemoteRequest.TOKEN_KEYINFO + "=" + Util.specialURLEncode(version) +
- "&" + IRemoteRequest.TOKEN_KEYSET + "=" + keySet);
+ "&" + IRemoteRequest.TOKEN_KEYSET + "=" + keySet +
+ "&" + IRemoteRequest.CHANNEL_PROTOCOL + "=" + protocol
+ );
String content = resp.getContent();
diff --git a/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java b/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java
index 319ff67b5..540da4019 100644
--- a/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java
+++ b/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java
@@ -250,6 +250,48 @@ public class TPSEngine {
}
+ // Compute 3 session keys enc, mac, and kek / dek in one shot and return the results
+ public TKSComputeSessionKeyResponse computeSessionKeysSCP03(TPSBuffer kdd, TPSBuffer cuid,
+ TPSBuffer keyInfo,
+ TPSBuffer card_challenge,
+ TPSBuffer host_challenge,
+ TPSBuffer card_cryptogram,
+ String connId,
+ String tokenType, String inKeySet) throws TPSException {
+
+ if (cuid == null || kdd == null || keyInfo == null || card_challenge == null || host_challenge == null
+ || card_cryptogram == null || connId == null || tokenType == null) {
+
+ throw new TPSException("TPSEngine.computeSessionKeySCP03: Invalid input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSEngine.computeSessionKeysSCP03");
+
+ TKSRemoteRequestHandler tks = null;
+
+ TKSComputeSessionKeyResponse resp = null;
+ try {
+ tks = new TKSRemoteRequestHandler(connId, inKeySet);
+ resp = tks.computeSessionKeysSCP03(kdd, cuid, keyInfo, card_challenge, card_cryptogram, host_challenge,
+ tokenType);
+ } catch (EBaseException e) {
+ throw new TPSException("TPSEngine.computeSessionKeysSCP03: Error computing session keys!" + e,
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ int status = resp.getStatus();
+ if (status != 0) {
+ CMS.debug("TPSEngine.computeSessionKeysSCP03: Non zero status result: " + status);
+ throw new TPSException("TPSEngine.computeSessionKeysSCP03: invalid returned status: " + status);
+
+ }
+
+ return resp;
+
+ }
+
+
public TKSComputeSessionKeyResponse computeSessionKey(TPSBuffer kdd, TPSBuffer cuid,
TPSBuffer keyInfo,
TPSBuffer card_challenge,
@@ -378,10 +420,12 @@ public class TPSEngine {
public TPSBuffer createKeySetData(TPSBuffer newMasterVersion, TPSBuffer oldVersion, int protocol, TPSBuffer cuid, TPSBuffer kdd, TPSBuffer wrappedDekSessionKey, String connId, String inKeyset)
throws TPSException {
- CMS.debug("TPSEngine.createKeySetData. entering...");
+
+ String method = "TPSEngine.createKeySetData:";
+ CMS.debug(method + " entering...");
if (newMasterVersion == null || oldVersion == null || cuid == null || kdd == null || connId == null) {
- throw new TPSException("TPSEngine.createKeySetData: Invalid input data",
+ throw new TPSException(method + " Invalid input data",
TPSStatus.STATUS_ERROR_KEY_CHANGE_OVER);
}
@@ -394,14 +438,14 @@ public class TPSEngine {
resp = tks.createKeySetData(newMasterVersion, oldVersion, cuid, kdd, protocol,wrappedDekSessionKey);
} catch (EBaseException e) {
- throw new TPSException("TPSEngine.createKeySetData, failure to get key set data from TKS",
+ throw new TPSException(method + " failure to get key set data from TKS",
TPSStatus.STATUS_ERROR_KEY_CHANGE_OVER);
}
int status = resp.getStatus();
if (status != 0) {
- CMS.debug("TPSEngine.createKeySetData: Non zero status result: " + status);
- throw new TPSException("TPSEngine.computeSessionKey: invalid returned status: " + status,
+ CMS.debug(method + " Non zero status result: " + status);
+ throw new TPSException(method + " invalid returned status: " + status,
TPSStatus.STATUS_ERROR_KEY_CHANGE_OVER);
}
@@ -409,8 +453,8 @@ public class TPSEngine {
TPSBuffer keySetData = resp.getKeySetData();
if (keySetData == null) {
- CMS.debug("TPSEngine.createKeySetData: No valid key set data returned.");
- throw new TPSException("TPSEngine.createKeySetData: No valid key set data returned.",
+ CMS.debug(method + " No valid key set data returned.");
+ throw new TPSException(method + " No valid key set data returned.",
TPSStatus.STATUS_ERROR_KEY_CHANGE_OVER);
}
diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
index 8b6370337..672f53d83 100644
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
@@ -378,8 +378,10 @@ public class TPSEnrollProcessor extends TPSProcessor {
String tksConnId = getTKSConnectorID();
TPSBuffer plaintextChallenge = computeRandomData(16, tksConnId);
+ CMS.debug(method + " plaintextChallenge: " + plaintextChallenge.toHexString());
+
//These will be used shortly
- TPSBuffer wrappedChallenge = encryptData(appletInfo, channel.getKeyInfoData(), plaintextChallenge, tksConnId);
+ TPSBuffer wrappedChallenge = encryptData(appletInfo, channel.getKeyInfoData(), plaintextChallenge, tksConnId,this.getProtocol());
PKCS11Obj pkcs11objx = null;
try {
@@ -3006,7 +3008,7 @@ public class TPSEnrollProcessor extends TPSProcessor {
//CMS.debug("TPSEnrollProcessor.importPrivateKeyPKCS8 : keyCheck: " + keyCheck.toHexString());
CMS.debug("TPSEnrollProcessor.importPrivateKeyPKCS8 : got keyCheck");
- // String ivParams = ssKeyGenResponse.getIVParam();
+ //String ivParams = ssKeyGenResponse.getIVParam();
//CMS.debug("TPSEnrollProcessor.importPrivateKeyPKCS8: ivParams: " + ivParams);
TPSBuffer ivParamsBuff = new TPSBuffer(Util.uriDecodeFromHex(ivParams));
@@ -3019,7 +3021,7 @@ public class TPSEnrollProcessor extends TPSProcessor {
TPSBuffer kekWrappedDesKey = channel.getKekDesKey();
if (kekWrappedDesKey != null) {
- //CMS.debug("TPSEnrollProcessor.importPrivateKeyPKCS8: keyWrappedDesKey: " + kekWrappedDesKey.toHexString());
+ CMS.debug("TPSEnrollProcessor.importPrivateKeyPKCS8: keyWrappedDesKey: " + kekWrappedDesKey.toHexString());
CMS.debug("TPSEnrollProcessor.importPrivateKeyPKCS8: got keyWrappedDesKey");
} else
CMS.debug("TPSEnrollProcessor.iportPrivateKeyPKC8: null kekWrappedDesKey!");
@@ -3041,7 +3043,7 @@ public class TPSEnrollProcessor extends TPSProcessor {
}
data.add((byte) ivParamsBuff.size());
data.add(ivParamsBuff);
- //CMS.debug("TPSEnrollProcessor.importprivateKeyPKCS8: key data outgoing: " + data.toHexString());
+ CMS.debug("TPSEnrollProcessor.importprivateKeyPKCS8: key data outgoing: " + data.toHexString());
int pe1 = (cEnrollInfo.getKeyUser() << 4) + cEnrollInfo.getPrivateKeyNumber();
int pe2 = (cEnrollInfo.getKeyUsage() << 4) + cEnrollInfo.getPublicKeyNumber();
diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
index 825df3f23..7d17f36b7 100644
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
@@ -33,6 +33,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import netscape.security.x509.RevocationReason;
+
import org.dogtagpki.server.tps.TPSSession;
import org.dogtagpki.server.tps.TPSSubsystem;
import org.dogtagpki.server.tps.authentication.AuthUIParameter;
@@ -99,8 +101,6 @@ import com.netscape.cms.servlet.tks.SecureChannelProtocol;
import com.netscape.cmsutil.crypto.CryptoUtil;
import com.netscape.symkey.SessionKey;
-import netscape.security.x509.RevocationReason;
-
public class TPSProcessor {
public static final int RESULT_NO_ERROR = 0;
@@ -111,10 +111,14 @@ public class TPSProcessor {
public static final int CPLC_MSN_SIZE = 4;
public static final int INIT_UPDATE_DATA_SIZE = 28;
+ public static final int INIT_UPDATE_DATA_SIZE_02 = 29;
+ public static final int INIT_UPDATE_DATA_SIZE_03 = 32;
public static final int DIVERSIFICATION_DATA_SIZE = 10;
public static final int CARD_CRYPTOGRAM_OFFSET = 20;
+ public static final int CARD_CRYPTOGRAM_OFFSET_GP211_SC03 = 21;
public static final int CARD_CRYPTOGRAM_SIZE = 8;
public static final int CARD_CHALLENGE_SIZE_GP211_SC02 = 6;
+ public static final int CARD_CHALLENGE_OFFSET_GP211_SC03 = 13 ;
public static final int SEQUENCE_COUNTER_OFFSET_GP211_SC02 = 12;
public static final int SEQUENCE_COUNTER_SIZE_GP211_SC02 = 2;
public static final int CARD_CHALLENGE_OFFSET = 12;
@@ -431,7 +435,7 @@ public class TPSProcessor {
protected TPSBuffer encryptData(AppletInfo appletInfo, TPSBuffer keyInfo, TPSBuffer plaintextChallenge,
- String connId) throws TPSException {
+ String connId,int protocol) throws TPSException {
TKSRemoteRequestHandler tks = null;
@@ -439,7 +443,7 @@ public class TPSProcessor {
try {
tks = new TKSRemoteRequestHandler(connId, getSelectedKeySet());
- data = tks.encryptData(appletInfo.getKDD(),appletInfo.getCUID(), keyInfo, plaintextChallenge);
+ data = tks.encryptData(appletInfo.getKDD(),appletInfo.getCUID(), keyInfo, plaintextChallenge,protocol);
} catch (EBaseException e) {
throw new TPSException("TPSProcessor.encryptData: Erorr getting wrapped data from TKS!",
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
@@ -482,7 +486,9 @@ public class TPSProcessor {
protected TPSBuffer initializeUpdate(byte keyVersion, byte keyIndex, TPSBuffer randomData) throws IOException,
TPSException {
- CMS.debug("In TPS_Processor.initializeUpdate.");
+ String method = "TPSProcessor.initializeUpdate:";
+
+ CMS.debug(method + " Entering...");
InitializeUpdateAPDU initUpdate = new InitializeUpdateAPDU(keyVersion, keyIndex, randomData);
int done = 0;
@@ -500,7 +506,10 @@ public class TPSProcessor {
TPSBuffer data = resp.getResultDataNoCode();
- if (data.size() != INIT_UPDATE_DATA_SIZE) {
+ CMS.debug(method + " data.size() " + data.size());
+
+ if ((data.size() != INIT_UPDATE_DATA_SIZE) && (data.size() != INIT_UPDATE_DATA_SIZE_02)
+ && (data.size() != INIT_UPDATE_DATA_SIZE_03)) {
throw new TPSException("TPSBuffer.initializeUpdate: Invalid response from token!",
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
@@ -550,12 +559,22 @@ public class TPSProcessor {
TPSBuffer initUpdateResp = initializeUpdate(keyVersion, keyIndex, randomData);
+ CMS.debug("TPSProcessor.setupSecureChanne: initUpdateResponse: " + initUpdateResp.toHexString());
+
TPSBuffer key_diversification_data = initUpdateResp.substr(0, DIVERSIFICATION_DATA_SIZE);
appletInfo.setKDD(key_diversification_data);
CMS.debug("TPSProcessor.setupSecureChannel: diversification data: " + key_diversification_data.toHexString());
- TPSBuffer key_info_data = initUpdateResp.substr(DIVERSIFICATION_DATA_SIZE, 2);
+ TPSBuffer key_info_data = null;
+
+ if (platProtInfo.isSCP03()) {
+ key_info_data = initUpdateResp.substr(DIVERSIFICATION_DATA_SIZE, 3);
+ } else {
+ key_info_data = initUpdateResp.substr(DIVERSIFICATION_DATA_SIZE, 2);
+ }
+
+
CMS.debug("TPSProcessor.setupSecureChannel: key info data: " + key_info_data.toHexString());
TokenRecord tokenRecord = getTokenRecord();
@@ -564,19 +583,13 @@ public class TPSProcessor {
TPSBuffer card_cryptogram = null;
TPSBuffer sequenceCounter = null;
- boolean isGp211scp02 = false;
-
- if (platProtInfo.getPlatform().equals(SecureChannel.GP211)) {
- isGp211scp02 = true;
- }
-
card_cryptogram = initUpdateResp.substr(CARD_CRYPTOGRAM_OFFSET, CARD_CRYPTOGRAM_SIZE);
//CMS.debug("TPSProcessor.setupSecureChannel: card cryptogram: " + card_cryptogram.toHexString());
CMS.debug("TPSProcessor.setupSecureChannel: card cryptogram: extracted");
TPSBuffer card_challenge = null;
- if (isGp211scp02) {
+ if (platProtInfo.isSCP02()) {
sequenceCounter = initUpdateResp.substr(SEQUENCE_COUNTER_OFFSET_GP211_SC02, 2);
{
@@ -602,7 +615,15 @@ public class TPSProcessor {
tokenRecord.setKeyInfo(key_info_data.toHexStringPlain());
+ } else if (platProtInfo.isSCP03()) {
+ card_challenge = initUpdateResp.substr(CARD_CHALLENGE_OFFSET_GP211_SC03,CARD_CHALLENGE_SIZE);
+ card_cryptogram = initUpdateResp.substr(CARD_CRYPTOGRAM_OFFSET_GP211_SC03, CARD_CRYPTOGRAM_SIZE);
+
+ CMS.debug("TPSProcessor.setupSecureChannel 03: card cryptogram: " + card_cryptogram.toHexString());
+ CMS.debug("TPSProcessor.setupSecureChannel 03: card challenge: " + card_challenge.toHexString());
+ CMS.debug("TPSProcessor.setupSecureChannel 03: host challenge: " + randomData.toHexString());
} else {
+
card_challenge = initUpdateResp.substr(CARD_CHALLENGE_OFFSET, CARD_CHALLENGE_SIZE);
}
//CMS.debug("TPSProcessor.setupSecureChannel: card challenge: " + card_challenge.toHexString());
@@ -628,6 +649,8 @@ public class TPSProcessor {
TPSBuffer sequenceCounter,AppletInfo appletInfo)
throws EBaseException, TPSException, IOException {
+ String method = "TPSProcessor.generateSecureChannel:";
+
if (connId == null || keyDiversificationData == null || keyInfoData == null || cardChallenge == null
|| cardCryptogram == null || hostChallenge == null || appletInfo == null) {
throw new TPSException("TPSProcessor.generateSecureChannel: Invalid input data!",
@@ -654,6 +677,11 @@ public class TPSProcessor {
PK11SymKey cmacSessionKeySCP02 = null;
PK11SymKey rmacSessionKeySCP02 = null;
+ PK11SymKey encSessionKeySCP03 = null;
+ PK11SymKey macSessionKeySCP03 = null;
+ PK11SymKey kekSessionKeySCP03 = null;
+ PK11SymKey rmacSessionKeySCP03 = null;
+
SymmetricKey sharedSecret = null;
//Sanity checking
@@ -680,7 +708,14 @@ public class TPSProcessor {
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
- SecureChannelProtocol protocol = new SecureChannelProtocol();
+ SecureChannelProtocol protocol = null; //new SecureChannelProtocol();
+
+
+ if(platProtInfo.isSCP01() || platProtInfo.isSCP02() ) {
+ protocol = new SecureChannelProtocol(1);
+ } else if (platProtInfo.isSCP03()) {
+ protocol = new SecureChannelProtocol(3);
+ }
String tokenName = CryptoUtil.INTERNAL_TOKEN_FULL_NAME;
@@ -715,7 +750,6 @@ public class TPSProcessor {
if (hostCryptogram == null) {
throw new TPSException("TPSProcessor.generateSecureChannel: No host cryptogram returned from token!",
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
-
}
try {
@@ -725,9 +759,7 @@ public class TPSProcessor {
/* sessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, (PK11SymKey) sharedSecret,
sessionKeyWrapped.toBytesArray()); */
-
- sessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret, sessionKeyWrapped.toBytesArray(), false);
-
+ sessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret, sessionKeyWrapped.toBytesArray(), false,SymmetricKey.DES3);
if (sessionKey == null) {
CMS.debug("TPSProcessor.generateSecureChannel: Can't extract session key!");
@@ -740,7 +772,7 @@ public class TPSProcessor {
/* encSessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName,(PK11SymKey) sharedSecret,
encSessionKeyWrapped.toBytesArray()); */
- encSessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,encSessionKeyWrapped.toBytesArray(),false);
+ encSessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,encSessionKeyWrapped.toBytesArray(),false,SymmetricKey.DES3);
if (encSessionKey == null) {
CMS.debug("TPSProcessor.generateSecureChannel: Can't extract enc session key!");
@@ -781,7 +813,7 @@ public class TPSProcessor {
}
- if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
+ if (platProtInfo.isSCP02()) {
//Generate the 4 keys we need for SCP02, Impl 15
if (sequenceCounter == null) {
@@ -805,8 +837,8 @@ public class TPSProcessor {
}
respCMac02 = engine.computeSessionKeySCP02(keyDiversificationData, appletInfo.getCUID(), keyInfoData,
- sequenceCounter, new TPSBuffer(SecureChannel.C_MACDerivationConstant),
- connId, getSelectedTokenType(), getSelectedKeySet());
+ sequenceCounter, new TPSBuffer(SecureChannel.C_MACDerivationConstant), connId,
+ getSelectedTokenType(), getSelectedKeySet());
TPSBuffer cmacSessionKeyWrappedSCP02 = respCMac02.getSessionKey();
@@ -875,6 +907,43 @@ public class TPSProcessor {
}
+ if (platProtInfo.isSCP03()) {
+ CMS.debug("TPSProcessor.generateSecureChannel Trying secure channel protocol 03");
+
+ resp = engine.computeSessionKeysSCP03(keyDiversificationData, appletInfo.getCUID(), keyInfoData,
+ cardChallenge, hostChallenge, cardCryptogram, connId, getSelectedTokenType(), getSelectedKeySet());
+
+ TPSBuffer encSessionKeyBuff = resp.getEncSessionKey();
+ TPSBuffer kekSessionKeyBuff = resp.getKekSessionKey();
+ TPSBuffer macSessionKeyBuff = resp.getMacSessionKey();
+ TPSBuffer hostCryptogramBuff = resp.getHostCryptogram();
+ TPSBuffer keyCheckBuff = resp.getKeyCheck();
+
+ TPSBuffer drmDesKeyBuff = resp.getDRM_Trans_DesKey();
+ TPSBuffer kekDesKeyBuff = resp.getKekWrappedDesKey();
+
+ CMS.debug(method + " encSessionKeyBuff: " + encSessionKeyBuff.toHexString());
+ CMS.debug(method + " kekSessionKeyBuff: " + kekSessionKeyBuff.toHexString());
+ CMS.debug(method + " macSessionKeyBuff: " + macSessionKeyBuff.toHexString());
+ CMS.debug(method + " hostCryptogramBuff: " + hostCryptogramBuff.toHexString());
+ CMS.debug(method + " keyCheckBuff: " + keyCheckBuff.toHexString());
+ CMS.debug(method + " drmDessKeyBuff: " + drmDesKeyBuff.toHexString());
+ CMS.debug(method + " kekDesKeyBuff: " + kekDesKeyBuff.toHexString());
+
+ encSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
+ encSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
+ macSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
+ macSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
+ kekSessionKeySCP03 = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,
+ kekSessionKeyBuff.toBytesArray(), false, SymmetricKey.AES);
+
+ channel = new SecureChannel(this, encSessionKeySCP03, macSessionKeySCP03, kekSessionKeySCP03,
+ drmDesKeyBuff, kekDesKeyBuff,
+ keyCheckBuff, keyDiversificationData, cardChallenge,
+ cardCryptogram, hostChallenge, hostCryptogramBuff, keyInfoData,
+ platProtInfo);
+ }
+
if (channel == null) {
throw new TPSException(
"TPSProcessor.generateSecureChannel: Can't create Secure Channel, possibly invalid secure channel protocol requested.",
@@ -3141,9 +3210,6 @@ public class TPSProcessor {
The second byte is the key offset, which is always 1
*/
- byte[] nv = { (byte) requiredVersion, 0x01 };
- TPSBuffer newVersion = new TPSBuffer(nv);
-
// GetKeyInfoData will return a buffer which is bytes 11,12 of
// the data structure on page 89 of Cyberflex Access Programmer's
// Guide
@@ -3157,8 +3223,21 @@ public class TPSProcessor {
int protocol = 1;
if (channel.isSCP02()) {
protocol = 2;
+ } if (channel.isSCP03()) {
+ protocol = 3;
}
+ byte[] nv = null;
+
+ if(protocol == 3) {
+ nv = new byte[] { (byte) requiredVersion,curKeyInfo.at(1),curKeyInfo.at(2) };
+
+ } else {
+ nv = new byte[] { (byte) requiredVersion, 0x01 };
+ }
+
+ TPSBuffer newVersion = new TPSBuffer(nv);
+
//Sanity checking
boolean cuidOK = checkCUIDMatchesKDD(appletInfo.getCUIDhexStringPlain(), appletInfo.getKDDhexStringPlain());
@@ -3574,14 +3653,21 @@ public class TPSProcessor {
try {
gp211GetSecureChannelProtocolDetails();
} catch (TPSException e) {
+
+ if(platProtInfo.getProtocol() == SecureChannel.SECURE_PROTO_03) {
+ CMS.debug("PSProcessor.acquireChannelPlatformProtocolInfo: card is reporting SCP03, bail, we don't yet support!");
+ throw e;
+ }
+
CMS.debug("TPSProcessor.acquireChannelPlatformProtocolInfo: Error getting gp211 protocol data, assume scp01 "
+ e);
+
platProtInfo.setPlatform(SecureChannel.GP201);
platProtInfo.setProtocol(SecureChannel.SECURE_PROTO_01);
}
- if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
+ if (platProtInfo.isSCP02()) {
// We only support impl 15, the most common, at this point.
if (platProtInfo.getImplementation() != SecureChannel.GP211_SCP02_IMPL_15) {
@@ -3690,16 +3776,17 @@ public class TPSProcessor {
byte protocol = oidSecureChannelProtocol.at(length - 2);
byte implementation = oidSecureChannelProtocol.at(length - 1);
- if (protocol == SecureChannel.SECURE_PROTO_03) {
- throw new TPSException("TPSProcessor.gp211GetSecureChannelProtocolDetails: No support for SCP03 as of yet, bailing.",
- TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
- }
+
platProtInfo.setProtocol(protocol);
platProtInfo.setImplementation(implementation);
platProtInfo.setKeysetInfoData(keyData);
- if (protocol == SecureChannel.SECURE_PROTO_02)
+ if (protocol == SecureChannel.SECURE_PROTO_03) {
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: Found protocol 03!");
+ }
+
+ if ((protocol == SecureChannel.SECURE_PROTO_02) || (protocol == SecureChannel.SECURE_PROTO_03))
platProtInfo.setPlatform(SecureChannel.GP211);
else
platProtInfo.setPlatform(SecureChannel.GP201);
@@ -3714,6 +3801,12 @@ public class TPSProcessor {
return platProtInfo;
}
+ public int getProtocol() {
+ if(platProtInfo == null)
+ return SecureChannel.SECURE_PROTO_01;
+ return platProtInfo.getProtocol();
+ }
+
boolean checkCardGPKeyVersionIsInRange(String CUID, String KDD, String keyInfoData) throws TPSException {
boolean result = true;
@@ -3772,11 +3865,14 @@ public class TPSProcessor {
CMS.debug(method + " minVersion: " + minVersion + " maxVersion: " + maxVersion);
- if (keyInfoData.length() != 4) {
+ if( keyInfoData.length() != 4 && keyInfoData.length() != 6) {
result = false;
} else {
+
+
// Actually check the version range;
+
String keyInfoVer = keyInfoData.substring(0, 2);
CMS.debug(method + " Version reported from key Info Data: " + keyInfoVer);