summaryrefslogtreecommitdiffstats
path: root/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java
diff options
context:
space:
mode:
Diffstat (limited to 'base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java')
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java234
1 files changed, 219 insertions, 15 deletions
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()) {