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