summaryrefslogtreecommitdiffstats
path: root/base/tps/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'base/tps/src/org')
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java108
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java536
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java159
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java66
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java14
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java532
6 files changed, 1268 insertions, 147 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
new file mode 100644
index 000000000..e5f38e108
--- /dev/null
+++ b/base/tps/src/org/dogtagpki/server/tps/channel/PlatformAndSecChannelProtoInfo.java
@@ -0,0 +1,108 @@
+package org.dogtagpki.server.tps.channel;
+
+import org.dogtagpki.tps.main.TPSBuffer;
+
+public class PlatformAndSecChannelProtoInfo {
+
+ private String platform ;
+ private byte protocol;
+ private TPSBuffer oidCardRecognitionData;
+ private TPSBuffer oidCardManagementTypeAndVer;
+ private TPSBuffer oidCardIdentificationScheme;
+ private TPSBuffer keysetInfoData;
+
+ private byte implementation;
+ public PlatformAndSecChannelProtoInfo(String platform, byte protocol, byte implementation) {
+ // TODO Auto-generated constructor stub
+ this.platform = platform;
+ this.protocol = protocol;
+ this.implementation = implementation;
+ }
+ public PlatformAndSecChannelProtoInfo() {
+ setPlatform(SecureChannel.GP201);
+ setProtocol(SecureChannel.SECURE_PROTO_01);
+ setImplementation((byte)0);
+ }
+ public String getPlatform() {
+ return platform;
+ }
+ public void setPlatform(String platform) {
+ this.platform = platform;
+ }
+ public byte getProtocol() {
+ return protocol;
+ }
+
+ public boolean isGP201() {
+ if(SecureChannel.GP201.equals(platform)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isGP211() {
+ if(SecureChannel.GP211.equals(platform)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isSCP01() {
+ if(protocol == SecureChannel.SECURE_PROTO_01) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isSCP02() {
+ if(protocol == SecureChannel.SECURE_PROTO_02) {
+ return true;
+ }
+ return false;
+ }
+ public void setProtocol(byte protocol) {
+ this.protocol = protocol;
+ }
+ public void setOidCardRecognitionData(TPSBuffer oidCardRecognitionData) {
+ // TODO Auto-generated method stub
+ this.oidCardRecognitionData = oidCardRecognitionData;
+
+ }
+
+ public TPSBuffer getOidCardRecognitionData() {
+ return oidCardRecognitionData;
+ }
+ public void setOidCardManagementTypeAndVer(TPSBuffer oidCardManagementTypeAndVer) {
+ // TODO Auto-generated method stub
+ this.oidCardManagementTypeAndVer = oidCardManagementTypeAndVer;
+ }
+
+ public TPSBuffer getOidCardManagementTypeAndVer() {
+ return oidCardManagementTypeAndVer;
+ }
+ public void setOidCardIdentificationScheme(TPSBuffer oidCardIdentificationScheme) {
+ this.oidCardIdentificationScheme = oidCardIdentificationScheme;
+
+ }
+
+ public TPSBuffer getOidCardIdentificationScheme() {
+ return oidCardIdentificationScheme;
+ }
+
+ public void setImplementation(byte implementation) {
+ this.implementation = implementation;
+ }
+
+ public byte getImplementation() {
+ return implementation;
+ }
+ public TPSBuffer getKeysetInfoData() {
+ return keysetInfoData;
+ }
+ public void setKeysetInfoData(TPSBuffer keysetInfoData) {
+ this.keysetInfoData = keysetInfoData;
+ }
+
+}
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 7c3a01ba7..95cf26c2f 100644
--- a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
+++ b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
@@ -19,21 +19,27 @@ package org.dogtagpki.server.tps.channel;
import java.io.IOException;
+import org.dogtagpki.server.tps.engine.TPSEngine;
import org.dogtagpki.server.tps.processor.TPSProcessor;
import org.dogtagpki.tps.apdu.APDU;
import org.dogtagpki.tps.apdu.APDUResponse;
import org.dogtagpki.tps.apdu.CreateObjectAPDU;
import org.dogtagpki.tps.apdu.CreatePinAPDU;
import org.dogtagpki.tps.apdu.DeleteFileAPDU;
+import org.dogtagpki.tps.apdu.DeleteFileGP211APDU;
import org.dogtagpki.tps.apdu.ExternalAuthenticateAPDU;
import org.dogtagpki.tps.apdu.ExternalAuthenticateAPDU.SecurityLevel;
+import org.dogtagpki.tps.apdu.ExternalAuthenticateAPDUGP211;
import org.dogtagpki.tps.apdu.GenerateKeyAPDU;
import org.dogtagpki.tps.apdu.GenerateKeyECCAPDU;
import org.dogtagpki.tps.apdu.ImportKeyEncAPDU;
import org.dogtagpki.tps.apdu.InstallAppletAPDU;
+import org.dogtagpki.tps.apdu.InstallAppletAPDUGP211;
import org.dogtagpki.tps.apdu.InstallLoadAPDU;
+import org.dogtagpki.tps.apdu.InstallLoadGP211APDU;
import org.dogtagpki.tps.apdu.LifecycleAPDU;
import org.dogtagpki.tps.apdu.LoadFileAPDU;
+import org.dogtagpki.tps.apdu.LoadFileAPDUGP211;
import org.dogtagpki.tps.apdu.PutKeyAPDU;
import org.dogtagpki.tps.apdu.ReadObjectAPDU;
import org.dogtagpki.tps.apdu.SetIssuerInfoAPDU;
@@ -55,10 +61,23 @@ public class SecureChannel {
// Have not written all code to use all of these as of yet.
- private TPSProcessor processor;
+ public TPSProcessor processor;
private PK11SymKey sessionKey;
+
+ //SCP01 or SCP02 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;
+
+ private TPSBuffer dekSessionKeyWrapped;
+
private TPSBuffer drmDesKey;
+
+ //SCP01 kek key
private TPSBuffer kekDesKey;
private TPSBuffer keyCheck;
private TPSBuffer keyDiversificationData;
@@ -68,7 +87,10 @@ public class SecureChannel {
private TPSBuffer hostCryptogram;
private TPSBuffer icv;
private TPSBuffer keyInfoData;
- private SecurityLevel secLevel;
+ private TPSBuffer sequenceCounter;
+ private ExternalAuthenticateAPDU.SecurityLevel secLevel;
+ private PlatformAndSecChannelProtoInfo platProtInfo;
+ private ExternalAuthenticateAPDUGP211.SecurityLevel secLevelGP211;
public enum TokenKeyType {
KEY_TYPE_ENCRYPTION,
@@ -76,9 +98,29 @@ public class SecureChannel {
KEY_TYPE_SIGNING_AND_ENCRYPTION
}
+ public final static byte GP211_SCP02_IMPL_15 = 0x15;
+ public final static String GP201 = "2.0.1";
+ public final static String GP211 = "2.1.1";
+
+ public final static byte SECURE_PROTO_01 = 1;
+ public final static byte SECURE_PROTO_02 = 2;
+ public final static byte SECURE_PROTO_03 = 3;
+
+ public final static byte[] GP211_GET_DATA_CARD_DATA = { 0x00, (byte) 0x66 };
+ public final static byte[] GP211_GET_DATA_KEY_INFO = { 0x00, (byte) 0xe0 };
+ 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 };
+
+ 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 };
+
+ //For SCP01
public SecureChannel(TPSProcessor processor, PK11SymKey sessionKey, PK11SymKey encSessionKey, TPSBuffer drmDesKey,
TPSBuffer kekDesKey, TPSBuffer keyCheck, TPSBuffer keyDiversificationData, TPSBuffer cardChallenge,
- TPSBuffer cardCryptogram, TPSBuffer hostChallenge, TPSBuffer hostCryptogram, TPSBuffer keyInfoData)
+ TPSBuffer cardCryptogram, TPSBuffer hostChallenge, TPSBuffer hostCryptogram, TPSBuffer keyInfoData,
+ PlatformAndSecChannelProtoInfo platformInfo)
throws TPSException {
if (processor == null || sessionKey == null | encSessionKey == null || keyDiversificationData == null
@@ -88,6 +130,9 @@ public class SecureChannel {
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
+ CMS.debug("SecureChannel.SecureChannel: For SCP01. ");
+
+ this.platProtInfo = platformInfo;
this.processor = processor;
this.sessionKey = sessionKey;
this.encSessionKey = encSessionKey;
@@ -103,11 +148,105 @@ public class SecureChannel {
this.keyInfoData = keyInfoData;
this.secLevel = SecurityLevel.SECURE_MSG_MAC_ENC;
- //ToDo: Write method that reads this from the config
}
- public static void main(String[] args) {
+ //For SCP02
+ public SecureChannel(TPSProcessor processor, PK11SymKey encSessionKey, PK11SymKey cmacSessionKey,
+ PK11SymKey rmacSessionKey, PK11SymKey dekSessionKey, TPSBuffer drmDesKey,
+ TPSBuffer kekDesKey, TPSBuffer keyCheck,
+ TPSBuffer keyDiversificationData,
+ TPSBuffer keyInfoData, TPSBuffer sequenceCounter, TPSBuffer hostChallenge, TPSBuffer cardChallenge,
+ TPSBuffer cardCryptogram, PlatformAndSecChannelProtoInfo platformInfo)
+ throws TPSException {
+
+ if (processor == null || encSessionKey == null | cmacSessionKey == null || rmacSessionKey == null
+ || dekSessionKey == null || keyDiversificationData == null || hostChallenge == null
+ || cardChallenge == null || cardCryptogram == null
+ || keyInfoData == null || platformInfo == null) {
+ throw new TPSException("SecureChannel.SecureChannel: Invalid data in constructor!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ this.sequenceCounter = sequenceCounter;
+ this.platProtInfo = platformInfo;
+ this.processor = processor;
+
+ this.encSessionKey = encSessionKey;
+ this.cmacSessionKey = cmacSessionKey;
+ this.setRmacSessionKey(rmacSessionKey);
+
+ this.keyDiversificationData = keyDiversificationData;
+
+ this.icv = new TPSBuffer(8);
+ this.keyInfoData = keyInfoData;
+ this.cardChallenge = cardChallenge;
+ this.cardCryptogram = cardCryptogram;
+ this.hostChallenge = hostChallenge;
+ this.drmDesKey = drmDesKey;
+ this.kekDesKey = kekDesKey;
+
+ //SCP02
+ this.secLevelGP211 = ExternalAuthenticateAPDUGP211.SecurityLevel.CDEC_CMAC;
+ this.keyCheck = keyCheck;
+
+ byte finalKeyIndex = gp211CalculateLatestKeySet(platformInfo.getKeysetInfoData());
+
+ CMS.debug("SecureChannel.SecureChannel: For SCP02: calculated latest key index: " + finalKeyIndex);
+
+ }
+
+ private byte gp211CalculateLatestKeySet(TPSBuffer keysetInfoData) throws TPSException {
+
+ if (keysetInfoData == null) {
+
+ throw new TPSException("SecureChannel.gp211calculateKeyInfoData invalid input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+
+ }
+
+ CMS.debug("SecureChannel.gp211calculateKeyInfoData: input keysetInfoData: " + keysetInfoData.toHexString());
+
+ int pos = 0;
+ byte next = keysetInfoData.at(pos++);
+
+ if (next != (byte) 0xE0) {
+ throw new TPSException("SecureChannel.gp211calculateKeyInfoData: malformed input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ next = keysetInfoData.at(pos++);
+
+ int numKeys = (next) / 6;
+
+ int remainder = (next) % 6;
+
+ if (remainder != 0) {
+ throw new TPSException("SecureChannel.gp211calculateKeyInfoData: malformed input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("SecureChannel.gp211calculateKeyInfoData: number of keys: " + numKeys);
+
+ int numKeySets = numKeys / 3; //Three keys per set
+
+ CMS.debug("SecureChannel.gp211calculateKeyInfoData: number of keysets: " + numKeySets);
+
+ int offset = (numKeySets - 1) * 6 * 3 + 3;
+
+ CMS.debug("SecureChannel.gp211calculateKeyInfoData: offset " + offset);
+
+ offset += pos;
+
+ if (offset > keysetInfoData.size()) {
+ throw new TPSException("SecureChannel.gp211calculateKeyInfoData: malformed input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ byte finalKeyIndex = keysetInfoData.at(offset);
+
+ return finalKeyIndex;
+
}
public void appendPKCS11Attribute(TPSBuffer buffer, long type, TPSBuffer attribute) {
@@ -204,29 +343,77 @@ public class SecureChannel {
public void externalAuthenticate() throws TPSException, IOException {
- CMS.debug("SecureChannel.externalAuthenticate: entering.");
+ CMS.debug("SecureChannel.externalAuthenticate: entering. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
- ExternalAuthenticateAPDU externalAuth = new ExternalAuthenticateAPDU(hostCryptogram,
- secLevel);
+ if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
+ CMS.debug("SecureChannel.externalAuthenticate: Attempting an External Authenticate for SCP02!");
- computeAPDUMac(externalAuth);
+ TPSBuffer calculatedCardCryptogram = computeCardCryptogramSCP02(encSessionKey);
- APDUResponse response = processor.handleAPDURequest(externalAuth);
+ if (false == cardCryptogram.equals(calculatedCardCryptogram)) {
+
+ CMS.debug("SecureChannel.eternalAuthenticate. Failed to match calculated to returned card cryptogram!. cardCryptogram: "
+ + cardCryptogram.toHexString()
+ + " calculatedCardCrytpogram: "
+ + calculatedCardCryptogram.toHexString());
+ throw new TPSException(
+ "SecureChannel.eternalAuthenticate. Failed to match calculated to returned card cryptogram!.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+
+ }
+
+ TPSBuffer calculatedHostCryptogram = computeHostCryptogramSCP02(encSessionKey);
+ this.hostCryptogram = calculatedHostCryptogram;
+
+ ExternalAuthenticateAPDUGP211 externalAuth = new ExternalAuthenticateAPDUGP211(hostCryptogram,
+ /* secLevel */secLevelGP211);
+
+ CMS.debug("SecureChannel.externalAuthenticate: about to call computeAPDUMacSCP02. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
+ computeAPDUMacSCP02(externalAuth);
+
+ APDUResponse response = processor.handleAPDURequest(externalAuth);
+
+ if (!response.checkResult()) {
+ throw new TPSException(
+ "SecureChannel.eternalAuthenticate SCP02. Failed to external authenticate to token.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("SecureChannel.externalAuthenticate: SCP02 external authenticate returns Success!!!");
+
+ } else { //SCP01
+
+ ExternalAuthenticateAPDU externalAuth = new ExternalAuthenticateAPDU(hostCryptogram,
+ /* secLevel */ExternalAuthenticateAPDU.SecurityLevel.SECURE_MSG_MAC_ENC);
+
+ CMS.debug("SecureChannel.externalAuthenticate: about to call computeAPDUMac. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
+ computeAPDUMac(externalAuth);
+
+ APDUResponse response = processor.handleAPDURequest(externalAuth);
+
+ if (!response.checkResult()) {
+ throw new TPSException(
+ "SecureChannel.eternalAuthenticate SCP01. Failed to external authenticate to token.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
- if (!response.checkResult()) {
- throw new TPSException("SecureChannel.eternalAuthenticate. Failed to external authenticate to token.",
- TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
CMS.debug("SecureChannel.externalAuthenticate: Successfully completed, exiting ...");
-
}
//This method computes the mac AND encryption if needed.
+ // Handle SCP02 if required.
private void computeAPDU(APDU apdu) throws TPSException {
CMS.debug("SecureChannel.computeAPDU: entering..");
+ if (isSCP02()) {
+ computeAPDU_SCP02(apdu);
+ return;
+
+ }
+
if (apdu == null) {
throw new TPSException("SecureChannel.computeAPDU: bad input apdu!",
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
@@ -236,9 +423,9 @@ public class SecureChannel {
if (secLevel == SecurityLevel.SECURE_MSG_MAC_ENC) {
try {
- // CMS.debug("SecureChannel.computeAPDU: Before encryption data value: " + apdu.getData().toHexString());
- apdu.secureMessage(encSessionKey);
- // CMS.debug("SecureChannel.computeAPDU: After encryption data value: " + apdu.getData().toHexString());
+ CMS.debug("SecureChannel.computeAPDU: Before encryption data value: " + apdu.getData().toHexString());
+ apdu.secureMessage(encSessionKey, (byte) 1);
+ CMS.debug("SecureChannel.computeAPDU: After encryption data value: " + apdu.getData().toHexString());
} catch (EBaseException e) {
throw new TPSException("SecureChannel.computeAPDU: Can't encrypt outgoing data! " + e);
}
@@ -247,6 +434,79 @@ public class SecureChannel {
}
}
+ private void computeAPDU_SCP02(APDU apdu) throws TPSException {
+ CMS.debug("SecureChannel.computeAPDU_SCP02: entering..");
+
+ if (apdu == null) {
+ throw new TPSException("SecureChannel.computeAPDU_SCP02: bad input apdu!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ computeAPDUMacSCP02(apdu);
+
+ if (secLevelGP211 == ExternalAuthenticateAPDUGP211.SecurityLevel.CDEC_CMAC) {
+ try {
+ 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());
+ } catch (EBaseException e) {
+ throw new TPSException("SecureChannel.computeAPDU_SCP02: Can't encrypt outgoing data! " + e);
+ }
+
+ CMS.debug("SecureChannel.computeAPDU_SCP02: Successfully encrypted apdu data.");
+ }
+
+ }
+
+ private void computeAPDUMacSCP02(APDU apdu) throws TPSException {
+
+ TPSBuffer newMac = null;
+ TPSBuffer data = null;
+ TPSBuffer singleDes = null;
+
+ if (apdu == null) {
+ throw new TPSException("SecureChannel.computeAPDUMacSCP02: bad input apdu!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ data = apdu.getDataToMAC();
+
+ CMS.debug("SecureChannel.computeAPDUMacSCP02: data To MAC: " + data.toHexString() + " incoming icv: "
+ + icv.toHexString());
+
+ try {
+
+ if (apdu.getType() != APDU.Type.APDU_EXTERNAL_AUTHENTICATE
+ && (secLevelGP211 == ExternalAuthenticateAPDUGP211.SecurityLevel.CMAC || secLevelGP211 == ExternalAuthenticateAPDUGP211.SecurityLevel.CDEC_CMAC)) {
+ CMS.debug("SecureChannel.computeAPDUMacSCP02: data To MAC, calcuating single des encyption before mac.");
+
+ singleDes = Util.computeEncEcbDes(cmacSessionKey, icv);
+ CMS.debug("SecureChannel.computeAPDUMacSCP02: data To MAC, calcuating single des encyption before mac. result: "
+ + singleDes.toHexString());
+
+ newMac = Util.computeMACdes3des(cmacSessionKey, data, singleDes);
+ } else {
+ CMS.debug("SecureChannel.computeAPDUMacSCP02: No ecnrypton of ICV.");
+ newMac = Util.computeMACdes3des(cmacSessionKey, data, icv);
+
+ }
+
+ } catch (EBaseException e) {
+ CMS.debug("SecureChannel.computeAPDUMacSCP02: Can't compute mac. " + e);
+ throw new TPSException("SecureChannel.compuatAPDUMacSCP02: Can't compute mac.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("SecureChannel.computeAPDUMacSCP02: computed MAC: " + newMac.toHexString());
+
+ apdu.setMAC(newMac);
+
+ icv.set(newMac);
+
+ }
+
// This method computes MAC only.
private void computeAPDUMac(APDU apdu) throws TPSException {
TPSBuffer newMac = null;
@@ -282,25 +542,47 @@ public class SecureChannel {
throw new TPSException("SecureChannel.deleteFileX: no input aid!");
}
- DeleteFileAPDU deleteFile = new DeleteFileAPDU(aid);
+ if (isGP211()) {
+
+ CMS.debug("SecureChannel.deleteFileX: attempting gp211...");
+ DeleteFileGP211APDU deleteFile = new DeleteFileGP211APDU(aid);
+
+ computeAPDU(deleteFile);
+
+ processor.handleAPDURequest(deleteFile);
+ } else {
+
+ CMS.debug("SecureChannel.deleteFileX: attempting gp201...");
+ DeleteFileAPDU deleteFile = new DeleteFileAPDU(aid);
+
+ computeAPDU(deleteFile);
- computeAPDU(deleteFile);
+ processor.handleAPDURequest(deleteFile);
- processor.handleAPDURequest(deleteFile);
+ }
}
// Begin process of loading applet onto token.
public void installLoad(TPSBuffer packageAID, TPSBuffer sdAID, int fileLength) throws TPSException, IOException {
- CMS.debug("SecureChannel.installLoad: entering ...");
+ CMS.debug("SecureChannel.installLoad: entering ... packageAID: " + packageAID.toHexString() + " sdAID: "
+ + sdAID.toHexString());
if (packageAID == null || sdAID == null || fileLength <= 0) {
throw new TPSException("SecureChannel.insallLoad bad input parameters!",
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
- InstallLoadAPDU install = new InstallLoadAPDU(packageAID, sdAID, fileLength);
+ TPSBuffer emptySDAID = new TPSBuffer();
+
+ if (isGP211()) {
+ TPSBuffer cardMgrGP211AIDBuff = new TPSBuffer(TPSEngine.CFG_DEF_CARDMGR_211_INSTANCE_AID);
+ installLoadGP211(packageAID, cardMgrGP211AIDBuff, fileLength);
+ return;
+ }
+
+ InstallLoadAPDU install = new InstallLoadAPDU(packageAID, emptySDAID, fileLength);
CMS.debug("SecureChannel.installLoad: Pre computed apdu: " + install.getEncoding().toHexString());
@@ -315,11 +597,34 @@ public class SecureChannel {
}
+ public void installLoadGP211(TPSBuffer packageAID, TPSBuffer sdAID, int fileLength) throws TPSException,
+ IOException {
+
+ CMS.debug("SecureChannel.installLoadGP211: entering ...");
+
+ if (packageAID == null || sdAID == null || fileLength <= 0) {
+ throw new TPSException("SecureChannel.insallLoadGP211 bad input parameters!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ InstallLoadGP211APDU install = new InstallLoadGP211APDU(packageAID, sdAID,
+ fileLength);
+
+ computeAPDU(install);
+
+ APDUResponse response = processor.handleAPDURequest(install);
+
+ if (!response.checkResult()) {
+ throw new TPSException("SecureChannel.installLoadGP211. Failed to perform installLoadGP211 operation.",
+ TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
+ }
+ }
+
//Actually load applet file onto the token.
public void loadFile(TPSBuffer programFile, int blockSize, int startProgress, int endProgress) throws TPSException,
IOException {
- CMS.debug("SecureChannel.loadFile entering...");
+ CMS.debug("SecureChannel.loadFile entering... blockSize: " + blockSize);
if (programFile == null || blockSize <= 0) {
throw new TPSException("ScureChannel.loadFile. Bad input data.", TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
@@ -407,11 +712,25 @@ public class SecureChannel {
TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
}
- LoadFileAPDU loadFile = new LoadFileAPDU(refControl, (byte) count, piece);
+ CMS.debug("SecureChannel.loadFileSegment: count: " + count + " piece: " + piece.toHexString());
+
+ APDUResponse response = null;
+
+ if (isGP211()) {
+ LoadFileAPDUGP211 loadFile = new LoadFileAPDUGP211(refControl, (byte) count, piece);
- computeAPDU(loadFile);
+ computeAPDU(loadFile);
- APDUResponse response = processor.handleAPDURequest(loadFile);
+ response = processor.handleAPDURequest(loadFile);
+ } else {
+ CMS.debug("SecureChannel.loadFileSegment: gp211.");
+ LoadFileAPDU loadFile = new LoadFileAPDU(refControl, (byte) count, piece);
+
+ computeAPDU(loadFile);
+
+ response = processor.handleAPDURequest(loadFile);
+
+ }
if (!response.checkResult()) {
throw new TPSException(
@@ -437,12 +756,25 @@ public class SecureChannel {
}
- InstallAppletAPDU install = new InstallAppletAPDU(netkeyPAIDBuff, netkeyAIDBuff, appPrivileges,
- channelInstanceSize, channelAppletMemSize);
+ APDUResponse response = null;
- computeAPDU(install);
+ if (isGP211()) {
+ InstallAppletAPDUGP211 install = new InstallAppletAPDUGP211(netkeyPAIDBuff, netkeyAIDBuff, appPrivileges,
+ channelInstanceSize, channelAppletMemSize);
- APDUResponse response = processor.handleAPDURequest(install);
+ computeAPDU(install);
+
+ response = processor.handleAPDURequest(install);
+ } else {
+
+ InstallAppletAPDU install = new InstallAppletAPDU(netkeyPAIDBuff, netkeyAIDBuff, appPrivileges,
+ channelInstanceSize, channelAppletMemSize);
+
+ computeAPDU(install);
+
+ response = processor.handleAPDURequest(install);
+
+ }
if (!response.checkResult()) {
throw new TPSException("SecureChannel.installApplett. Failed installApplet operation.",
@@ -972,7 +1304,8 @@ public class SecureChannel {
public void putKeys(byte curVersion, byte curIndex, TPSBuffer keySetData) throws TPSException, IOException {
- CMS.debug("SecureChannel.putKeys: entering..");
+ CMS.debug("SecureChannel.putKeys: entering.. curVersion: " + curVersion + " curIndex: " + curIndex
+ + " keySetData: " + keySetData);
if (keySetData == null) {
throw new TPSException("SecureChannel.putKeys: Invalid input data!", TPSStatus.STATUS_ERROR_KEY_CHANGE_OVER);
@@ -980,14 +1313,27 @@ public class SecureChannel {
byte keyVersion = curVersion;
- if (curVersion == 0xff) {
- keyVersion = 0x0;
+ if (curVersion == (byte) 0xff) {
+ CMS.debug("Setting keyVersion to 1");
+ keyVersion = 0x1;
}
- PutKeyAPDU putKey = new PutKeyAPDU(keyVersion, (byte) (0x80 | curIndex), keySetData);
+ CMS.debug("keyVersion now set to: " + keyVersion);
+
+ PutKeyAPDU putKey = new PutKeyAPDU(keyVersion, (byte) 0x81, keySetData);
+ if (isSCP02()) {
+ TPSBuffer trailer = new TPSBuffer(1);
+ putKey.setTrailer(trailer);
+
+ }
computeAPDU(putKey);
+ int kill = 0;
+ if (kill == 1) {
+ throw new TPSException("putKeys end of progress.");
+ }
+
APDUResponse response = processor.handleAPDURequest(putKey);
if (!response.checkResult()) {
@@ -1017,11 +1363,12 @@ public class SecureChannel {
CMS.debug("SecureChannel.importKeyEnc entering...");
- if(data == null) {
- throw new TPSException("SecureChannel.importKeyEnc: Invalid input data!",TPSStatus.STATUS_ERROR_MAC_CERT_PDU);
+ if (data == null) {
+ throw new TPSException("SecureChannel.importKeyEnc: Invalid input data!",
+ TPSStatus.STATUS_ERROR_MAC_CERT_PDU);
}
- ImportKeyEncAPDU importKeyEnc = new ImportKeyEncAPDU((byte)pe1,(byte) pe2, data);
+ ImportKeyEncAPDU importKeyEnc = new ImportKeyEncAPDU((byte) pe1, (byte) pe2, data);
computeAPDU(importKeyEnc);
@@ -1042,4 +1389,119 @@ public class SecureChannel {
this.kekDesKey = kekDesKey;
}
+ public TPSBuffer getSequenceCounter() {
+ return sequenceCounter;
+ }
+
+ public PlatformAndSecChannelProtoInfo getChannelPlatformAndProtocolInfo() {
+ return platProtInfo;
+ }
+
+ protected TPSBuffer computeCardCryptogramSCP02(PK11SymKey encSessionKey)
+ throws TPSException {
+
+ if (encSessionKey == null) {
+ throw new TPSException("TPSProcessor.computeCardCryptogramSCP02: invalide input data",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ TPSBuffer data = new TPSBuffer(hostChallenge);
+ data.add(sequenceCounter);
+ data.add(cardChallenge);
+
+ if (data.size() != 16) {
+ throw new TPSException("calculateCardCryptogramSCP02: card cyrptogram source data incorrect size.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ TPSBuffer cardCryptogram = null;
+ try {
+ cardCryptogram = Util.computeMAC(encSessionKey, data, icv);
+ } catch (EBaseException e) {
+ throw new TPSException("calculateCardCryptogramSCP02: card cyrptogram: Error calculating the MAC value",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSProcessor.calculateCardCrytogramSCP02: returning calculated card cryptogram; "
+ + cardCryptogram.toHexString());
+
+ return cardCryptogram;
+
+ }
+
+ protected TPSBuffer computeHostCryptogramSCP02(PK11SymKey encSessionKey)
+ throws TPSException {
+
+ if (encSessionKey == null) {
+ throw new TPSException("TPSProcessor.computeHostCryptogramSCP02: invalide input data",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ TPSBuffer hostCryptogramSCP02 = null;
+
+ TPSBuffer data = new TPSBuffer(sequenceCounter);
+ data.add(cardChallenge);
+ data.add(hostChallenge);
+
+ if (data.size() != 16) {
+ throw new TPSException("calculateHostCryptogramSCP02: host cyrptogram source data incorrect size.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ try {
+ hostCryptogramSCP02 = Util.computeMAC(encSessionKey, data, icv);
+ } catch (EBaseException e) {
+ throw new TPSException("calculateHostCryptogramSCP02: host cyrptogram: Error calculating the MAC value",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSProcessor.calculateHostCrytogramSCP02: returning calculated host cryptogram; "
+ + hostCryptogramSCP02.toHexString());
+
+ return hostCryptogramSCP02;
+
+ }
+
+ public boolean isSCP02() {
+ if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isGP211() {
+
+ if (platProtInfo.isGP211()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public TPSBuffer getDekSessionKeyWrapped() {
+ return dekSessionKeyWrapped;
+ }
+
+ public void setDekSessionKeyWrapped(TPSBuffer dekSessionKeyWrapped) {
+ this.dekSessionKeyWrapped = dekSessionKeyWrapped;
+ }
+
+ public PK11SymKey getDekSessionKey() {
+ return dekSessionKey;
+ }
+
+ public void setDekSessionKey(PK11SymKey dekSessionKey) {
+ this.dekSessionKey = dekSessionKey;
+ }
+
+ public PK11SymKey getRmacSessionKey() {
+ return rmacSessionKey;
+ }
+
+ public void setRmacSessionKey(PK11SymKey rmacSessionKey) {
+ this.rmacSessionKey = rmacSessionKey;
+ }
+
}
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 3c371a45e..c6537e4c2 100644
--- a/base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java
+++ b/base/tps/src/org/dogtagpki/server/tps/cms/TKSRemoteRequestHandler.java
@@ -22,6 +22,7 @@ import java.util.Hashtable;
import org.dogtagpki.server.connector.IRemoteRequest;
import org.dogtagpki.server.tps.TPSSubsystem;
+import org.dogtagpki.server.tps.channel.SecureChannel;
import org.dogtagpki.tps.main.TPSBuffer;
import org.dogtagpki.tps.main.Util;
@@ -93,7 +94,7 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
boolean serverKeygen =
conf.getBoolean("op.enroll." +
- tokenType + ".keyGen.encryption.serverKeygen.enable",
+ tokenType + ".keyGen.encryption.serverKeygen.enable",
false);
String keySet =
conf.getString("connector." + connid + "keySet", "defKeySet");
@@ -205,6 +206,143 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
}
/*
+ * computeSessionKey
+ *
+ * Usage Example:
+ * TKSRemoteRequestHandler tksReq = new TKSRemoteRequestHandler("tks1");
+ * TKSComputeSessionKeyResponse responseObj =
+ * tksReq.computeSessionKey(
+ * cuid,
+ * keyInfo,
+ * card_challenge,
+ * card_cryptogram,
+ * host_challenge);
+ * - on success return, one can say
+ * TPSBuffer value = responseObj.getSessionKey();
+ * to get response param value session key
+ *
+ * @param cuid token cuid
+ * @param keyInfo keyInfo
+ * @param card_challenge card challenge
+ * @param card_cryptogram card cryptogram
+ * @param host_challenge host challenge
+ * @return response TKSComputeSessionKeyResponse class object
+ */
+ public TKSComputeSessionKeyResponse computeSessionKeySCP02(
+ TPSBuffer cuid,
+ TPSBuffer keyInfo,
+ TPSBuffer sequenceCounter,
+ TPSBuffer derivationConstant,
+ String tokenType)
+ throws EBaseException {
+
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): begins.");
+ if (cuid == null || keyInfo == null ||
+ sequenceCounter == null
+ || derivationConstant == null) {
+ throw new EBaseException("TKSRemoteRequestHandler: computeSessionKeySCP02(): input parameter null.");
+ }
+
+ IConfigStore conf = CMS.getConfigStore();
+
+ boolean serverKeygen =
+ conf.getBoolean("op.enroll." +
+ tokenType + ".keyGen.encryption.serverKeygen.enable",
+ false);
+ String keySet =
+ conf.getString("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_CUID + "=" + Util.specialURLEncode(cuid) +
+ "&" + IRemoteRequest.TOKEN_KEYINFO + "=" + Util.specialURLEncode(keyInfo) +
+ "&" + IRemoteRequest.TOKEN_KEYSET + "=" + keySet +
+ "&" + IRemoteRequest.CHANNEL_PROTOCOL + "=" + SecureChannel.SECURE_PROTO_02 +
+ "&" + IRemoteRequest.SEQUENCE_COUNTER + "=" + Util.specialURLEncode(sequenceCounter) +
+ "&" + IRemoteRequest.DERIVATION_CONSTANT + "=" + Util.specialURLEncode(derivationConstant);
+
+ 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("TKSRemoteRequestHandler: computeSessionKeySCP02(): status not found.");
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): got content = " + content);
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): got status = " + value);
+ ist = Integer.parseInt(value);
+ }
+ response.put(IRemoteRequest.RESPONSE_STATUS, ist);
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_SessionKey);
+ if (value == null) {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_SessionKey);
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): got IRemoteRequest.TKS_RESPONSE_SessionKey = ");
+ response.put(IRemoteRequest.TKS_RESPONSE_SessionKey, Util.specialDecode(value));
+ }
+
+ value = (String) response.get(IRemoteRequest.TKS_RESPONSE_DRM_Trans_DesKey);
+ if (value == null) {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_DRM_Trans_DesKey);
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): 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_KEK_DesKey);
+ if (value == null) {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_KEK_DesKey);
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): 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("TKSRemoteRequestHandler: computeSessionKeySCP02(): response missing name-value pair for: " +
+ IRemoteRequest.TKS_RESPONSE_KeyCheck);
+
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): got IRemoteRequest.TKS_RESPONSE_KeyCheck = ");
+ response.put(IRemoteRequest.TKS_RESPONSE_KeyCheck, Util.specialDecode(value));
+ }
+
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): ends.");
+
+ return new TKSComputeSessionKeyResponse(response);
+
+ } else {
+ CMS.debug("TKSRemoteRequestHandler: computeSessionKeySCP02(): no response content.");
+ throw new EBaseException("TKSRemoteRequestHandler: computeSessionKeySCP02(): no response content.");
+ }
+ }
+
+ /*
* createKeySetData
*
* Usage Example:
@@ -226,7 +364,7 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
public TKSCreateKeySetDataResponse createKeySetData(
TPSBuffer NewMasterVer,
TPSBuffer version,
- TPSBuffer cuid)
+ TPSBuffer cuid, int protocol, TPSBuffer wrappedDekSessionKey)
throws EBaseException {
CMS.debug("TKSRemoteRequestHandler: createKeySetData(): begins.");
if (cuid == null || NewMasterVer == null || version == null) {
@@ -242,12 +380,21 @@ public class TKSRemoteRequestHandler extends RemoteRequestHandler
HttpConnector conn =
(HttpConnector) subsystem.getConnectionManager().getConnector(connid);
CMS.debug("TKSRemoteRequestHandler: createKeySetData(): sending request to tks.");
+
+ String command = IRemoteRequest.TOKEN_NEW_KEYINFO + "=" + Util.specialURLEncode(NewMasterVer) +
+ "&" + IRemoteRequest.TOKEN_CUID + "=" + Util.specialURLEncode(cuid) +
+ "&" + IRemoteRequest.TOKEN_KEYINFO + "=" + Util.specialURLEncode(version) +
+ "&" + IRemoteRequest.TOKEN_KEYSET + "=" + keySet +
+ "&" + IRemoteRequest.CHANNEL_PROTOCOL + "=" + protocol;
+
+ if(wrappedDekSessionKey != null) { // We have secure channel protocol 02 trying to upgrade the key set.
+ command += "&" + IRemoteRequest.WRAPPED_DEK_SESSION_KEY + "=" + Util.specialURLEncode(wrappedDekSessionKey);
+ }
+
+
HttpResponse resp =
conn.send("createKeySetData",
- IRemoteRequest.TOKEN_NEW_KEYINFO + "=" + Util.specialURLEncode(NewMasterVer) +
- "&" + IRemoteRequest.TOKEN_CUID + "=" + Util.specialURLEncode(cuid) +
- "&" + IRemoteRequest.TOKEN_KEYINFO + "=" + Util.specialURLEncode(version) +
- "&" + IRemoteRequest.TOKEN_KEYSET + "=" + keySet);
+ command);
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 9221d1ba0..e7efcc031 100644
--- a/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java
+++ b/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java
@@ -106,11 +106,13 @@ public class TPSEngine {
public static final String CFG_APPLET_DIRECTORY = "update.applet.directory";
public static final String CFG_APPLET_EXTENSION = "general.applet_ext";
- public static final String CFG_CHANNEL_BLOCK_SIZE = "channel.blockSize";
+ public static final String CFG_CHANNEL_BLOCK_SIZE = "channel.blocksize";
public static final String CFG_CHANNEL_INSTANCE_SIZE = "channel.instanceSize";
public static final String CFG_CHANNEL_DEFKEY_VERSION = "channel.defKeyVersion";
public static final String CFG_CHANNEL_APPLET_MEMORY_SIZE = "channel.appletMemorySize";
public static final String CFG_CHANNEL_DEFKEY_INDEX = "channel.defKeyIndex";
+ public static final String CFG_CHANNEL_DEF_PLATFORM = "channel.defPlatform";
+ public static final String CFG_CHANNEL_DEF_SECURE_PROTO = "channel.defSecureProtocol";
public static final String CFG_ISSUER_INFO_ENABLE = "issuerinfo.enable";
public static final String CFG_ISSUER_INFO_VALUE = "issuerinfo.value";
public static final String CFG_UPDATE_APPLET_ENCRYPTION = "update.applet.encryption";
@@ -119,6 +121,7 @@ public class TPSEngine {
/* default values */
public static final String CFG_DEF_CARDMGR_INSTANCE_AID = "A0000000030000";
+ public static final String CFG_DEF_CARDMGR_211_INSTANCE_AID = "A000000003000000";
public static final String CFG_DEF_NETKEY_INSTANCE_AID = "627601FF000000";
public static final String CFG_DEF_NETKEY_FILE_AID = "627601FF0000";
public static final String CFG_DEF_NETKEY_OLD_INSTANCE_AID = "A00000000101";
@@ -204,6 +207,45 @@ public class TPSEngine {
return rc;
}
+ public TKSComputeSessionKeyResponse computeSessionKeySCP02(
+ TPSBuffer cuid,
+ TPSBuffer keyInfo,
+ TPSBuffer sequenceCounter,
+ TPSBuffer derivationConstant,
+ String connId,
+ String tokenType)
+ throws TPSException {
+
+ if (cuid == null || keyInfo == null || sequenceCounter == null || derivationConstant == null
+ || tokenType == null) {
+ throw new TPSException("TPSEngine.computeSessionKeySCP02: Invalid input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSEngine.computeSessionKeySCP02");
+
+ TKSRemoteRequestHandler tks = null;
+
+ TKSComputeSessionKeyResponse resp = null;
+ try {
+ tks = new TKSRemoteRequestHandler(connId);
+ resp = tks.computeSessionKeySCP02(cuid, keyInfo, sequenceCounter, derivationConstant, tokenType);
+ } catch (EBaseException e) {
+ throw new TPSException("TPSEngine.computeSessionKeySCP02: Error computing session key!" + e,
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ int status = resp.getStatus();
+ if (status != 0) {
+ CMS.debug("TPSEngine.computeSessionKeySCP02: Non zero status result: " + status);
+ throw new TPSException("TPSEngine.computeSessionKeySCP02: invalid returned status: " + status);
+
+ }
+
+ return resp;
+
+ }
+
public TKSComputeSessionKeyResponse computeSessionKey(TPSBuffer cuid,
TPSBuffer keyInfo,
TPSBuffer card_challenge,
@@ -330,7 +372,7 @@ public class TPSEngine {
}
- public TPSBuffer createKeySetData(TPSBuffer newMasterVersion, TPSBuffer oldVersion, TPSBuffer cuid, String connId)
+ public TPSBuffer createKeySetData(TPSBuffer newMasterVersion, TPSBuffer oldVersion, int protocol, TPSBuffer cuid, TPSBuffer wrappedDekSessionKey, String connId)
throws TPSException {
CMS.debug("TPSEngine.createKeySetData. entering...");
@@ -345,7 +387,7 @@ public class TPSEngine {
try {
tks = new TKSRemoteRequestHandler(connId);
- resp = tks.createKeySetData(newMasterVersion, oldVersion, cuid);
+ resp = tks.createKeySetData(newMasterVersion, oldVersion, cuid, protocol,wrappedDekSessionKey);
} catch (EBaseException e) {
throw new TPSException("TPSEngine.createKeySetData, failure to get key set data from TKS",
@@ -541,27 +583,27 @@ public class TPSEngine {
}
- //Check to see if special operations transition is allowed
+ //Check to see if special operations transition is allowed
public boolean isOperationTransitionAllowed(TokenStatus oldState, TokenStatus newState) throws TPSException {
boolean allowed = true;
- if(transitionList == null) {
+ if (transitionList == null) {
IConfigStore configStore = CMS.getConfigStore();
- String transConfig = CFG_OPERATIONS_TRANSITIONS;
+ String transConfig = CFG_OPERATIONS_TRANSITIONS;
CMS.debug("TPSEngine.isOperationTransistionAllowed: getting config: " + transConfig);
try {
- transitionList = configStore.getString(transConfig,null);
+ transitionList = configStore.getString(transConfig, null);
} catch (EBaseException e) {
throw new TPSException(
"TPSProcessor.isOperationTransitionAllowed: Internal error getting config value for operations transition list!",
TPSStatus.STATUS_ERROR_MISCONFIGURATION);
}
- if(transitionList == null) {
+ if (transitionList == null) {
throw new TPSException(
"TPSProcessor.isOperationTransitionAllowed: Can't find non null config value for operations transition list!",
TPSStatus.STATUS_ERROR_MISCONFIGURATION);
@@ -569,21 +611,21 @@ public class TPSEngine {
CMS.debug("TPSEngine.isOperationTransistionAllowed: transitionList is: " + transitionList);
-
}
String transition = oldState.toInt() + ":" + newState.toInt();
CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition);
- if(transitionList.indexOf(transition) == -1) {
+ if (transitionList.indexOf(transition) == -1) {
CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition);
allowed = false;
}
- CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition + " allowed: " + allowed);
+ CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition + " allowed: "
+ + allowed);
- return allowed;
+ return allowed;
}
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 c74fe2cb6..5b8560a1d 100644
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
@@ -301,12 +301,10 @@ public class TPSEnrollProcessor extends TPSProcessor {
CMS.debug("TPSEnrollProcessor.enroll: Finished updating applet if needed.");
//Check and upgrade keys if called for
-
SecureChannel channel = checkAndUpgradeSymKeys();
channel.externalAuthenticate();
//Reset the token's pin, create one if we don't have one already
-
checkAndHandlePinReset(channel);
tokenRecord.setKeyInfo(channel.getKeyInfoData().toHexStringPlain());
String tksConnId = getTKSConnectorID();
@@ -2361,6 +2359,10 @@ public class TPSEnrollProcessor extends TPSProcessor {
TPSBuffer keyCheck = channel.getKeyCheck();
+ if (keyCheck == null) {
+ keyCheck = new TPSBuffer();
+ }
+
CMS.debug("TPSEnrollProcessor.importprivateKeyPKCS8 : keyCheck: " + keyCheck.toHexString());
// String ivParams = ssKeyGenResponse.getIVParam();
@@ -2381,7 +2383,7 @@ public class TPSEnrollProcessor extends TPSProcessor {
CMS.debug("TPSEnrollProcessor.iportPrivateKeyPKC8: null kekWrappedDesKey!");
byte alg = (byte) 0x80;
- if (kekWrappedDesKey == null || kekWrappedDesKey.size() > 0) {
+ if (kekWrappedDesKey != null && kekWrappedDesKey.size() > 0) {
alg = (byte) 0x81;
}
@@ -2392,9 +2394,13 @@ public class TPSEnrollProcessor extends TPSProcessor {
data.add((byte) kekWrappedDesKey.size());
data.add(kekWrappedDesKey);
data.add((byte) keyCheck.size());
- data.add(keyCheck);
+ if (keyCheck.size() > 0) {
+ data.add(keyCheck);
+ }
data.add((byte) ivParamsBuff.size());
data.add(ivParamsBuff);
+ 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 895893924..ee8b7529f 100644
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
@@ -39,6 +39,7 @@ import org.dogtagpki.server.tps.TPSSession;
import org.dogtagpki.server.tps.TPSSubsystem;
import org.dogtagpki.server.tps.authentication.AuthUIParameter;
import org.dogtagpki.server.tps.authentication.TPSAuthenticator;
+import org.dogtagpki.server.tps.channel.PlatformAndSecChannelProtoInfo;
import org.dogtagpki.server.tps.channel.SecureChannel;
import org.dogtagpki.server.tps.cms.CARemoteRequestHandler;
import org.dogtagpki.server.tps.cms.CARevokeCertResponse;
@@ -57,7 +58,6 @@ import org.dogtagpki.server.tps.profile.BaseTokenProfileResolver;
import org.dogtagpki.server.tps.profile.TokenProfileParams;
import org.dogtagpki.tps.apdu.APDU;
import org.dogtagpki.tps.apdu.APDUResponse;
-import org.dogtagpki.tps.apdu.ExternalAuthenticateAPDU.SecurityLevel;
import org.dogtagpki.tps.apdu.GetDataAPDU;
import org.dogtagpki.tps.apdu.GetStatusAPDU;
import org.dogtagpki.tps.apdu.GetVersionAPDU;
@@ -104,7 +104,11 @@ public class TPSProcessor {
public static final int DIVERSIFICATION_DATA_SIZE = 10;
public static final int CARD_CRYPTOGRAM_OFFSET = 20;
public static final int CARD_CRYPTOGRAM_SIZE = 8;
+ public static final int CARD_CHALLENGE_SIZE_GP211_SC02 = 6;
+ 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;
+ public static final int CARD_CHALLENGE_OFFSET_GP211_SC02 = 14;
public static final int CARD_CHALLENGE_SIZE = 8;
protected boolean isExternalReg;
@@ -119,6 +123,7 @@ public class TPSProcessor {
protected String currentTokenOperation;
protected BeginOpMsg beginMsg;
+ private PlatformAndSecChannelProtoInfo platProtInfo;
public TPSProcessor(TPSSession session) {
setSession(session);
@@ -286,7 +291,7 @@ public class TPSProcessor {
}
protected TPSBuffer getCplcData() throws IOException, TPSException {
- CMS.debug("In TPS_Processor.GetData");
+ CMS.debug("In TPS_Processor.");
GetDataAPDU get_data_apdu = new GetDataAPDU();
@@ -304,6 +309,24 @@ public class TPSProcessor {
return respApdu.getData();
}
+ public TPSBuffer getData(byte[] identifier) throws TPSException, IOException {
+ CMS.debug("In TPSProcessor.getData: identifier: " + identifier.toString());
+
+ if (identifier == null || identifier.length != 2) {
+ throw new TPSException("TPSProcessor.getData: Can't get data, invalid input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+ GetDataAPDU get_data_apdu = new GetDataAPDU(identifier);
+
+ APDUResponse respApdu = handleAPDURequest(get_data_apdu);
+
+ if (!respApdu.checkResult()) {
+ throw new TPSException("TPSProcessor.getData: Can't get data!", TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ return respApdu.getData();
+ }
+
protected TPSBuffer getAppletVersion() throws IOException, TPSException {
//We return null if no applet present
// This is not an error, the token can be blank.
@@ -389,6 +412,10 @@ public class TPSProcessor {
CMS.debug("In TPS_Processor.initializeUpdate.");
InitializeUpdateAPDU initUpdate = new InitializeUpdateAPDU(keyVersion, keyIndex, randomData);
+ int done = 0;
+ if (done == 1)
+ throw new TPSException("TPSProcessor.initializeUpdate. debugging exit...");
+
APDUResponse resp = handleAPDURequest(initUpdate);
if (!resp.checkResult()) {
@@ -418,7 +445,7 @@ public class TPSProcessor {
int defKeyVersion = getChannelDefKeyVersion();
int defKeyIndex = getChannelDefKeyIndex();
- channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex, SecurityLevel.SECURE_MSG_MAC_ENC,
+ channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex,
getTKSConnectorID());
channel.externalAuthenticate();
@@ -426,15 +453,20 @@ public class TPSProcessor {
return channel;
}
- protected SecureChannel setupSecureChannel(byte keyVersion, byte keyIndex, SecurityLevel securityLevel,
+ protected SecureChannel setupSecureChannel(byte keyVersion, byte keyIndex,
String connId)
throws IOException, TPSException {
//Assume generating host challenge on TKS, we no longer support not involving the TKS.
+ CMS.debug("TPSProcessor.setupSecureChannel: keyVersion: " + keyVersion + " keyIndex: " + keyIndex
+ );
+
TPSBuffer randomData = computeRandomData(8, connId);
CMS.debug("TPSProcessor.setupSecureChannel: obtained randomData: " + randomData.toHexString());
+ acquireChannelPlatformAndProtocolInfo();
+
TPSBuffer initUpdateResp = initializeUpdate(keyVersion, keyIndex, randomData);
TPSBuffer key_diversification_data = initUpdateResp.substr(0, DIVERSIFICATION_DATA_SIZE);
@@ -446,10 +478,43 @@ public class TPSProcessor {
TokenRecord tokenRecord = getTokenRecord();
tokenRecord.setKeyInfo(key_info_data.toHexStringPlain());
- TPSBuffer card_cryptogram = initUpdateResp.substr(CARD_CRYPTOGRAM_OFFSET, CARD_CRYPTOGRAM_SIZE);
+ 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());
- TPSBuffer card_challenge = initUpdateResp.substr(CARD_CHALLENGE_OFFSET, CARD_CHALLENGE_SIZE);
+ TPSBuffer card_challenge = null;
+
+ if (isGp211scp02) {
+ sequenceCounter = initUpdateResp.substr(SEQUENCE_COUNTER_OFFSET_GP211_SC02, 2);
+
+ {
+ card_challenge = initUpdateResp
+ .substr(CARD_CHALLENGE_OFFSET_GP211_SC02, CARD_CHALLENGE_SIZE_GP211_SC02);
+ card_cryptogram = initUpdateResp.substr(CARD_CRYPTOGRAM_OFFSET, CARD_CRYPTOGRAM_SIZE); //new TPSBuffer(canned_card_challenge);
+
+ CMS.debug("TPSProcessor.setupSecureChannel 02: card cryptogram: " + card_cryptogram.toHexString());
+ CMS.debug("TPSProcessor.setupSecureChannel 02: card challenge: " + card_challenge.toHexString());
+ CMS.debug("TPSProcessor.setupSecureChannel 02: host challenge: " + randomData.toHexString());
+
+ }
+
+ //Set the second byte of the keyInfo data to 0x1, this only gives us the secure protocol version 0x2 here.
+ //This will allow symkey to not get confused with that 0x02.
+ CMS.debug("TPSProcessor.setupSecureChannel 02: key Info , before massage: " + key_info_data.toHexString());
+ key_info_data.setAt(1, (byte) 0x1);
+ CMS.debug("TPSProcessor.setupSecureChannel 02: key Info , after massage: " + key_info_data.toHexString());
+
+ } else {
+ card_challenge = initUpdateResp.substr(CARD_CHALLENGE_OFFSET, CARD_CHALLENGE_SIZE);
+ }
CMS.debug("TPSProcessor.setupSecureChannel: card challenge: " + card_challenge.toHexString());
SecureChannel channel = null;
@@ -457,7 +522,7 @@ public class TPSProcessor {
try {
channel = generateSecureChannel(connId, key_diversification_data, key_info_data, card_challenge,
card_cryptogram,
- randomData);
+ randomData, sequenceCounter);
} catch (EBaseException e) {
throw new TPSException("TPSProcessor.setupSecureChannel: Can't set up secure channel: " + e,
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
@@ -468,27 +533,35 @@ public class TPSProcessor {
}
protected SecureChannel generateSecureChannel(String connId, TPSBuffer keyDiversificationData,
- TPSBuffer keyInfoData, TPSBuffer cardChallenge, TPSBuffer cardCryptogram, TPSBuffer hostChallenge)
- throws EBaseException, TPSException {
+ TPSBuffer keyInfoData, TPSBuffer cardChallenge, TPSBuffer cardCryptogram, TPSBuffer hostChallenge,
+ TPSBuffer sequenceCounter)
+ throws EBaseException, TPSException, IOException {
- CMS.debug("TPSProcessor.generateSecureChannel: entering..");
+ if (connId == null || keyDiversificationData == null || keyInfoData == null || cardChallenge == null
+ || cardCryptogram == null || hostChallenge == null) {
+ throw new TPSException("TPSProcessor.generateSecureChannel: Invalid input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSProcessor.generateSecureChannel: entering.. keyInfoData: " + keyInfoData.toHexString());
+ CMS.debug("TPSProcessor.generateSecureChannel: isSCP02: " + platProtInfo.isSCP02());
TPSEngine engine = getTPSEngine();
SecureChannel channel = null;
TPSBuffer hostCryptogram = null;
+ PK11SymKey sessionKey = null;
+ PK11SymKey encSessionKey = null;
+ TKSComputeSessionKeyResponse resp = null;
+ TKSComputeSessionKeyResponse respEnc02 = null;
+ TKSComputeSessionKeyResponse respDek02 = null;
+ TKSComputeSessionKeyResponse respCMac02 = null;
+ TKSComputeSessionKeyResponse respRMac02 = null;
- TKSComputeSessionKeyResponse resp = engine.computeSessionKey(keyDiversificationData, keyInfoData,
- cardChallenge, hostChallenge, cardCryptogram,
- connId, getSelectedTokenType());
-
- hostCryptogram = resp.getHostCryptogram();
-
- if (hostCryptogram == null) {
- new TPSException("TPSProcessor.generateSecureChannel: No host cryptogram returned from token!",
- TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
-
- }
+ PK11SymKey encSessionKeySCP02 = null;
+ PK11SymKey dekSessionKeySCP02 = null;
+ PK11SymKey cmacSessionKeySCP02 = null;
+ PK11SymKey rmacSessionKeySCP02 = null;
PK11SymKey sharedSecret = null;
@@ -500,59 +573,175 @@ public class TPSProcessor {
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
- PK11SymKey sessionKey = null;
- PK11SymKey encSessionKey = null;
String tokenName = "Internal Key Storage Token";
- try {
- TPSBuffer sessionKeyWrapped = resp.getSessionKey();
- TPSBuffer encSessionKeyWrapped = resp.getEncSessionKey();
+ if (platProtInfo.isGP201() || platProtInfo.isSCP01()) {
+
+ resp = engine.computeSessionKey(keyDiversificationData, keyInfoData,
+ cardChallenge, hostChallenge, cardCryptogram,
+ connId, getSelectedTokenType());
- sessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
- sessionKeyWrapped.toBytesArray());
+ hostCryptogram = resp.getHostCryptogram();
- if (sessionKey == null) {
- CMS.debug("TPSProcessor.generateSecureChannel: Can't extract session key!");
- throw new TPSException("TPSProcessor.generateSecureChannel: Can't extract session key!",
+ if (hostCryptogram == null) {
+ throw new TPSException("TPSProcessor.generateSecureChannel: No host cryptogram returned from token!",
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+
}
- CMS.debug("TPSProcessor.generateSecureChannel: retrieved session key: " + sessionKey);
- encSessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
- encSessionKeyWrapped.toBytesArray());
+ try {
+ TPSBuffer sessionKeyWrapped = resp.getSessionKey();
+ TPSBuffer encSessionKeyWrapped = resp.getEncSessionKey();
+
+ sessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
+ sessionKeyWrapped.toBytesArray());
+
+ if (sessionKey == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't extract session key!");
+ throw new TPSException("TPSProcessor.generateSecureChannel: Can't extract session key!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+ CMS.debug("TPSProcessor.generateSecureChannel: retrieved session key: " + sessionKey);
+
+ encSessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
+ encSessionKeyWrapped.toBytesArray());
- if (encSessionKey == null) {
- CMS.debug("TPSProcessor.generateSecureChannel: Can't extract enc session key!");
- throw new TPSException("TPSProcessor.generateSecureChannel: Can't extract enc session key!",
+ if (encSessionKey == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't extract enc session key!");
+ throw new TPSException("TPSProcessor.generateSecureChannel: Can't extract enc session key!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSProcessor.generateSecureChannel: retrieved enc session key: " + encSessionKey);
+
+ TPSBuffer drmDesKey = null;
+ TPSBuffer kekDesKey = null;
+ TPSBuffer keyCheck = null;
+
+ drmDesKey = resp.getDRM_Trans_DesKey();
+ keyCheck = resp.getKeyCheck();
+ kekDesKey = resp.getKekWrappedDesKey();
+
+ if (checkServerSideKeyGen(connId)) {
+
+ CMS.debug("TPSProcessor.generateSecureChannel: drmDesKey: " + drmDesKey + " kekDesKey : "
+ + kekDesKey
+ + " keyCheck: " + keyCheck);
+ //ToDo handle server side keygen.
+
+ }
+ channel = new SecureChannel(this, sessionKey, encSessionKey, drmDesKey,
+ kekDesKey, keyCheck, keyDiversificationData, cardChallenge,
+ cardCryptogram, hostChallenge, hostCryptogram, keyInfoData, platProtInfo);
+
+ } catch (Exception e) {
+ CMS.debug(e);
+ e.printStackTrace();
+ throw new TPSException("TPSProcessor.generateSecureChannel: Problem extracting session keys! " + e,
TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
- CMS.debug("TPSProcessor.generateSecureChannel: retrieved enc session key: " + encSessionKey);
- } catch (Exception e) {
- CMS.debug(e);
- e.printStackTrace();
- throw new TPSException("TPSProcessor.generateSecureChannel: Problem extracting session keys! " + e,
- TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
- TPSBuffer drmDesKey = null;
- TPSBuffer kekDesKey = null;
- TPSBuffer keyCheck = null;
+ if (platProtInfo.isGP211() && platProtInfo.isSCP02()) {
+ //Generate the 4 keys we need for SCP02, Impl 15
+
+ if (sequenceCounter == null) {
+ throw new TPSException("TPSProcessor.generateSecureChannel: Invalid input data!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSProcessor.generateSecureChannel Trying secure channel protocol 02");
+ respEnc02 = engine.computeSessionKeySCP02(keyDiversificationData, keyInfoData,
+ sequenceCounter, new TPSBuffer(SecureChannel.ENCDerivationConstant),
+ connId, getSelectedTokenType());
+
+ TPSBuffer encSessionKeyWrappedSCP02 = respEnc02.getSessionKey();
+ encSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
+ encSessionKeyWrappedSCP02.toBytesArray());
+
+ if (encSessionKeySCP02 == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't extract the SCP02 enc session key!");
+ throw new TPSException("TPSProcessor.generateSecureChannel: Can't the emc SCP02 session keys!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ respCMac02 = engine.computeSessionKeySCP02(keyDiversificationData, keyInfoData,
+ sequenceCounter, new TPSBuffer(SecureChannel.C_MACDerivationConstant),
+ connId, getSelectedTokenType());
+
+ TPSBuffer cmacSessionKeyWrappedSCP02 = respCMac02.getSessionKey();
+
+ cmacSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
+ cmacSessionKeyWrappedSCP02.toBytesArray());
+
+ if (cmacSessionKeySCP02 == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't extract the SCP02 cmac session key!");
+ throw new TPSException("TPSProcessor.generateSecureChannel: Can't the s,ac SCP02 session keys!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ respRMac02 = engine.computeSessionKeySCP02(keyDiversificationData, keyInfoData,
+ sequenceCounter, new TPSBuffer(SecureChannel.R_MACDerivationConstant),
+ connId, getSelectedTokenType());
+
+ TPSBuffer rmacSessionKeyWrappedSCP02 = respRMac02.getSessionKey();
- drmDesKey = resp.getDRM_Trans_DesKey();
- keyCheck = resp.getKeyCheck();
- kekDesKey = resp.getKekWrappedDesKey();
+ rmacSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
+ rmacSessionKeyWrappedSCP02.toBytesArray());
+
+ if (rmacSessionKeySCP02 == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't extract the SCP02 cmac session key!");
+ throw new TPSException("TPSProcessor.generateSecureChannel: Can't the cmac SCP02 session keys!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
- if (checkServerSideKeyGen(connId)) {
+ respDek02 = engine.computeSessionKeySCP02(keyDiversificationData, keyInfoData,
+ sequenceCounter, new TPSBuffer(SecureChannel.DEKDerivationConstant),
+ connId, getSelectedTokenType());
+
+ CMS.debug("Past engine.computeSessionKeyData: After dek key request.");
+
+ TPSBuffer dekSessionKeyWrappedSCP02 = respDek02.getSessionKey();
+
+ dekSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
+ dekSessionKeyWrappedSCP02.toBytesArray());
+
+ if (dekSessionKeySCP02 == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't extract the SCP02 dek session key!");
+ throw new TPSException("TPSProcessor.generateSecureChannel: Can't the dek SCP02 session keys!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
- CMS.debug("TPSProcessor.generateSecureChannel: drmDesKey: " + drmDesKey + " kekDesKey : " + kekDesKey
- + " keyCheck: " + keyCheck);
- //ToDo handle server side keygen.
+ TPSBuffer drmDesKey = null;
+ TPSBuffer kekDesKey = null;
+ TPSBuffer keyCheck = null;
+ drmDesKey = respDek02.getDRM_Trans_DesKey();
+ kekDesKey = respDek02.getKekWrappedDesKey();
+ keyCheck = respDek02.getKeyCheck();
+
+ if (drmDesKey == null || kekDesKey == null) {
+ CMS.debug("TPSProcessor.generateSecureChannel: Can't get drmDesKey or kekDesKey from TKS when processing the DEK session key!");
+ throw new TPSException(
+ "TPSProcessor.generateSecureChannel: Can't get drmDesKey or kekDesKey from TKS when processing the DEK session key!",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ channel = new SecureChannel(this, encSessionKeySCP02, cmacSessionKeySCP02,
+ rmacSessionKeySCP02, dekSessionKeySCP02, drmDesKey, kekDesKey, keyCheck,
+ keyDiversificationData,
+ keyInfoData, sequenceCounter, hostChallenge, cardChallenge, cardCryptogram, platProtInfo);
+
+ channel.setDekSessionKeyWrapped(dekSessionKeyWrappedSCP02);
+
+ }
+
+ if (channel == null) {
+ throw new TPSException(
+ "TPSProcessor.generateSecureChannel: Can't create Secure Channel, possibly invalid secure channel protocol requested.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
}
- channel = new SecureChannel(this, sessionKey, encSessionKey, drmDesKey,
- kekDesKey, keyCheck, keyDiversificationData, cardChallenge,
- cardCryptogram, hostChallenge, hostCryptogram, keyInfoData);
return channel;
}
@@ -584,18 +773,12 @@ public class TPSProcessor {
}
protected void checkAndUpgradeApplet(AppletInfo appletInfo) throws TPSException, IOException {
- // TODO Auto-generated method stub
CMS.debug("checkAndUpgradeApplet: entering..");
- SecurityLevel securityLevel = SecurityLevel.SECURE_MSG_MAC;
-
- boolean useEncryption = checkUpdateAppletEncryption();
-
String tksConnId = getTKSConnectorID();
- if (useEncryption)
- securityLevel = SecurityLevel.SECURE_MSG_MAC_ENC;
+ int upgraded = 0;
if (checkForAppletUpdateEnabled()) {
String targetAppletVersion = checkForAppletUpgrade("op." + currentTokenOperation);
@@ -608,18 +791,26 @@ public class TPSProcessor {
if (targetAppletVersion.compareTo(currentAppletVersion) != 0) {
+ upgraded = 1;
CMS.debug("TPSProcessor.checkAndUpgradeApplet: Upgrading applet to : " + targetAppletVersion);
- upgradeApplet("op." + currentTokenOperation, targetAppletVersion, securityLevel, getBeginMessage()
+ upgradeApplet("op." + currentTokenOperation, targetAppletVersion, getBeginMessage()
.getExtensions(),
tksConnId, 5, 12);
- } else {
- CMS.debug("TPSProcessor.checkAndUpgradeApplet: applet already at correct version.");
}
}
+ if (upgraded == 0) {
+ CMS.debug("TPSProcessor.checkAndUpgradeApplet: applet already at correct version or upgrade disabled.");
+
+ // We didn't need to upgrade the applet but create new channel for now.
+ selectCardManager();
+ setupSecureChannel();
+
+ }
+
}
- protected void upgradeApplet(String operation, String new_version, SecurityLevel securityLevel,
+ protected void upgradeApplet(String operation, String new_version,
Map<String, String> extensions, String connId, int startProgress, int endProgress) throws IOException,
TPSException {
@@ -659,17 +850,16 @@ public class TPSProcessor {
throw new TPSException("TPSProcessor.upgradeApplet: Can't selelect the card manager!");
}
- SecureChannel channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex, securityLevel, connId);
+ SecureChannel channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex, connId);
channel.externalAuthenticate();
+
channel.deleteFileX(netkeyAIDBuff);
channel.deleteFileX(netkeyPAIDBuff);
// Next step will be to load the applet file to token.
- TPSBuffer empty = new TPSBuffer();
-
- channel.installLoad(netkeyPAIDBuff, empty, appletData.length);
+ channel.installLoad(netkeyPAIDBuff, cardMgrAIDBuff, appletData.length);
TPSBuffer appletDataBuff = new TPSBuffer(appletData);
@@ -691,6 +881,7 @@ public class TPSProcessor {
public void selectCoolKeyApplet() throws TPSException, IOException {
+ CMS.debug("In selectCoolKeyApplet!");
TPSBuffer netkeyAIDBuff = getNetkeyAID();
APDUResponse select = selectApplet((byte) 0x04, (byte) 0x00, netkeyAIDBuff);
@@ -806,7 +997,6 @@ public class TPSProcessor {
return authInst;
}
-
public void processAuthentication(String op, TPSAuthenticator userAuth, String cuid, TokenRecord tokenRecord)
throws EBaseException, TPSException, IOException {
IAuthCredentials userCred;
@@ -1394,13 +1584,13 @@ public class TPSProcessor {
if (vals != null) {
for (String val : vals) {
CMS.debug(method + ": retrieved certsToDelete:" + val);
-
+
// Each cert is represented as
// (serial#, caID, revokeOnDelete)
// e.g.
// (234, ca1, true)
// note: number above is in decimal
-
+
String[] items = val.split(",");
ExternalRegCertToDelete erCert =
new ExternalRegCertToDelete();
@@ -1674,11 +1864,9 @@ public class TPSProcessor {
CMS.debug("TPSProcessor.format: appletVersion found: " + appletVersion + " requiredVersion: "
+ appletRequiredVersion);
- SecurityLevel secLevel = SecurityLevel.SECURE_MSG_MAC_ENC;
-
String tksConnId = getTKSConnectorID();
- upgradeApplet(TPSEngine.OP_FORMAT_PREFIX, appletRequiredVersion, secLevel,
+ upgradeApplet(TPSEngine.OP_FORMAT_PREFIX, appletRequiredVersion,
beginMsg.getExtensions(), tksConnId,
10, 90);
CMS.debug("TPSProcessor.format: Completed applet upgrade.");
@@ -1738,8 +1926,6 @@ public class TPSProcessor {
UnsupportedEncodingException {
if (checkIssuerInfoEnabled()) {
- SecurityLevel secLevel = SecurityLevel.SECURE_MSG_MAC_ENC;
-
String tksConnId = getTKSConnectorID();
int defKeyIndex = getChannelDefKeyIndex();
@@ -1751,7 +1937,7 @@ public class TPSProcessor {
channel = origChannel;
} else {
- channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex, secLevel, tksConnId);
+ channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex, tksConnId);
channel.externalAuthenticate();
}
@@ -1896,6 +2082,8 @@ public class TPSProcessor {
String profileConfig = "config.Profiles." + selectedTokenType + ".state";
String profileState = null;
+ CMS.debug("TPSProcessor.checkProfileStateOK: config value to check: " + profileConfig);
+
try {
profileState = configStore.getString(profileConfig, TPSEngine.CFG_ENABLED);
} catch (EBaseException e) {
@@ -2121,7 +2309,7 @@ public class TPSProcessor {
IConfigStore configStore = CMS.getConfigStore();
try {
- cardMgrAID = configStore.getString(TPSEngine.CFG_DEF_CARDMGR_INSTANCE_AID,
+ cardMgrAID = configStore.getString(TPSEngine.CFG_APPLET_CARDMGR_INSTANCE_AID,
TPSEngine.CFG_DEF_CARDMGR_INSTANCE_AID);
} catch (EBaseException e1) {
@@ -2520,7 +2708,6 @@ public class TPSProcessor {
try {
channel = setupSecureChannel((byte) requiredVersion, (byte) defKeyIndex,
- SecurityLevel.SECURE_MSG_MAC_ENC,
getTKSConnectorID());
} catch (TPSException e) {
@@ -2553,15 +2740,46 @@ public class TPSProcessor {
TPSBuffer curKeyInfo = channel.getKeyInfoData();
TPSEngine engine = getTPSEngine();
- TPSBuffer keySetData = engine.createKeySetData(newVersion, curKeyInfo,
- channel.getKeyDiversificationData(), connId);
+ int protocol = 1;
+ if (channel.isSCP02()) {
+ protocol = 2;
+ }
+
+ TPSBuffer keySetData = engine.createKeySetData(newVersion, curKeyInfo, protocol,
+ channel.getKeyDiversificationData(), channel.getDekSessionKeyWrapped(), connId);
CMS.debug("TPSProcessor.checkAndUpgradeSymKeys: new keySetData from TKS: " + keySetData.toHexString());
byte curVersion = curKeyInfo.at(0);
byte curIndex = curKeyInfo.at(1);
- channel.putKeys(curVersion, curIndex, keySetData);
+ int done = 0;
+ if (done == 1)
+ throw new TPSException("TPSProcessor.checkAndUpgradeSymKeys: end of progress.");
+
+ try {
+ channel.putKeys(curVersion, curIndex, keySetData);
+ } catch (TPSException e) {
+
+ CMS.debug("TPSProcessor.checkAndUpgradeSymKeys: failed to put key, checking to see if this a SCP02 with 0xFF default key set.");
+
+ if (protocol == 2 && curVersion == (byte) 0xff) {
+ CMS.debug("TPSProcessor.checkAndUpgradeSymKeys: failed to put key, but we have SCP02 and the 0xFF dev key, try again.");
+
+ byte[] nv_dev = { (byte) 0x1, (byte) 0x1 };
+ TPSBuffer devKeySetData = engine.createKeySetData(new TPSBuffer(nv_dev), curKeyInfo, protocol,
+ channel.getKeyDiversificationData(), channel.getDekSessionKeyWrapped(), connId);
+
+ CMS.debug("TPSProcessor.checkAndUpgradeSymKeys: about to get rid of keyset 0xFF and replace it with keyset 0x1 with developer key set");
+ channel.putKeys((byte) 0x0, (byte) 0x1, devKeySetData);
+
+ CMS.debug("TPSProcessor.checkAndUpgradeSymKeys: We've only upgraded to the dev key set on key set #01, will have to try again to upgrade to #02");
+
+ } else {
+ throw e;
+ }
+
+ }
String curVersionStr = curKeyInfo.toHexString();
String newVersionStr = newVersion.toHexString();
@@ -2571,11 +2789,9 @@ public class TPSProcessor {
CMS.debug("TPSProcessor.checkAndUpgradeSymKeys: curVersionStr: " + curVersionStr + " newVersionStr: "
+ newVersionStr);
-
selectCoolKeyApplet();
channel = setupSecureChannel((byte) requiredVersion, (byte) defKeyIndex,
- SecurityLevel.SECURE_MSG_MAC_ENC,
getTKSConnectorID());
} else {
@@ -2588,7 +2804,7 @@ public class TPSProcessor {
defKeyVersion = getChannelDefKeyVersion();
- channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex, SecurityLevel.SECURE_MSG_MAC_ENC,
+ channel = setupSecureChannel((byte) defKeyVersion, (byte) defKeyIndex,
getTKSConnectorID());
}
@@ -2878,6 +3094,146 @@ public class TPSProcessor {
}
}
+ public void acquireChannelPlatformAndProtocolInfo() throws TPSException, IOException {
+
+ if (platProtInfo == null) {
+ platProtInfo = new PlatformAndSecChannelProtoInfo();
+ } else { // We don't need this any more
+ return;
+ }
+
+ try {
+ gp211GetSecureChannelProtocolDetails();
+ } catch (TPSException 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()) {
+ // We only support impl 15, the most common, at this point.
+
+ if (platProtInfo.getImplementation() != SecureChannel.GP211_SCP02_IMPL_15) {
+ throw new TPSException(
+ "SecureChannel.acquireChannelPlatformAndProtocolInfo card returning a non supported implementation for SCP02 "
+ + platProtInfo.getImplementation());
+ }
+ }
+
+ }
+
+ public void gp211GetSecureChannelProtocolDetails() throws TPSException, IOException {
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: Query card for secure channel protocol details for gp211.");
+
+ TPSBuffer data = null;
+ TPSBuffer keyData = null;
+
+ selectCardManager();
+ try {
+
+ data = getData(SecureChannel.GP211_GET_DATA_CARD_DATA);
+ keyData = getData(SecureChannel.GP211_GET_DATA_KEY_INFO);
+
+ } catch (TPSException e) {
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: Card can't understand GP211! " + e);
+
+ throw e;
+
+ }
+
+ if (data.size() < 5) {
+ throw new TPSException("TPSProcessor.gp211GetSecureChannelProtocolDetails: invalide return data.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: returned data: " + data.toHexString());
+
+ // Now process the GP211 data returned by the card.
+
+ int offset = 0;
+ int totalLength = 0;
+ int length = 0;
+
+ if (data.at(offset) == (byte) 0x66) {
+ offset++;
+
+ totalLength = data.getIntFrom1Byte(offset++);
+ offset++;
+
+ } else {
+ offset++;
+ totalLength = data.getIntFrom1Byte(offset++);
+
+ }
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: totalLength: " + totalLength);
+
+ if (totalLength == 0 || totalLength >= data.size()) {
+ throw new TPSException("TPSProcessor.gp211GetSecureChannelProtocolDetails: Invalid return data.",
+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
+ }
+
+ offset++;
+
+ length = data.getIntFrom1Byte(offset++);
+
+ TPSBuffer oidCardRecognitionData = data.substr(offset, length);
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: oidCardRecognitionData: "
+ + oidCardRecognitionData.toHexString());
+
+ platProtInfo.setOidCardRecognitionData(oidCardRecognitionData);
+
+ offset += length + 2 + 1;
+
+ length = data.getIntFrom1Byte(offset++);
+
+ TPSBuffer oidCardManagementTypeAndVer = data.substr(offset, length);
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: oidCardManagementTypeAndVer: "
+ + oidCardManagementTypeAndVer.toHexString());
+
+ platProtInfo.setOidCardManagementTypeAndVer(oidCardManagementTypeAndVer);
+
+ offset += length + 2 + 1;
+
+ length = data.getIntFrom1Byte(offset++);
+
+ TPSBuffer oidCardIdentificationScheme = data.substr(offset, length);
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: oidCardIdentificationScheme: "
+ + oidCardIdentificationScheme.toHexString());
+
+ platProtInfo.setOidCardIdentificationScheme(oidCardIdentificationScheme);
+
+ offset += length + 2 + 1;
+
+ length = data.getIntFrom1Byte(offset++);
+
+ TPSBuffer oidSecureChannelProtocol = data.substr(offset, length);
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: oidSecureChannelProtocol: "
+ + oidSecureChannelProtocol.toHexString());
+
+ byte protocol = oidSecureChannelProtocol.at(length - 2);
+ byte implementation = oidSecureChannelProtocol.at(length - 1);
+
+ platProtInfo.setProtocol(protocol);
+ platProtInfo.setImplementation(implementation);
+ platProtInfo.setKeysetInfoData(keyData);
+ platProtInfo.setPlatform(SecureChannel.GP211);
+
+ CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: protocol: " + protocol + " implementation: "
+ + implementation + " keyInfoData: " + keyData.toHexString());
+
+ }
+
+ public PlatformAndSecChannelProtoInfo getChannelPlatformAndProtocolInfo() {
+ return platProtInfo;
+ }
+
public static void main(String[] args) {
}