diff options
Diffstat (limited to 'base/tps/src/org/dogtagpki/server/tps')
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) { } |