summaryrefslogtreecommitdiffstats
path: root/base/common/src/org
diff options
context:
space:
mode:
authorJack Magne <jmagne@redhat.com>2014-10-13 13:40:59 -0700
committerJack Magne <jmagne@redhat.com>2015-02-27 18:44:07 -0800
commitf39e3387f8a671ef97a08d1c0c3e4b2b6fd65ad3 (patch)
tree256bd8cca169f87c99c8ef6874b173bed3f1db4e /base/common/src/org
parent7b1d897ba4cf9de1459d2aad37e969ce9a93a05a (diff)
downloadpki-f39e3387f8a671ef97a08d1c0c3e4b2b6fd65ad3.tar.gz
pki-f39e3387f8a671ef97a08d1c0c3e4b2b6fd65ad3.tar.xz
pki-f39e3387f8a671ef97a08d1c0c3e4b2b6fd65ad3.zip
Ticket: TPS Rewrite: Implement Secure Channel Protocol 02 (#883).
First cut of gp211 and scp protocol 02 for tokens. Allow token operations using a GP211 token over secure channel protocol 02. This patch supports the following: 1. Token operations with a GP211 card and SCP02 protocol, implementation 15. 2. Token still supports GP201 cards with SCP01. 3. SCP02 tested with SC650 gp211/scp02 card. Things still to do: 1. Right now the SCP02 support has been tested with the current gp201 applet and enrollment and formatting works just fine. We need to modify and compile the applet against the GP211 spec and retest to see if any further changes are needed. 2. The nistSP800 key derivation stuff is not completed for the SCP02 protocol. Some of the routines are self contained vs similar SCP01 ones. We have another ticket to complete the nistSP800 support from end to end. This work will be done for that ticket. 3. One of the new scp02 deriviation functions can make use of a new NSS derive mechanism. As of now this work is done by simple encryption, this can be done later. 4. The security APDU level of "RMAC" is not supported because the card does not support it. It could have been done to the spec, but it having the card to test is more convenient and there were more crucial issues to this point.
Diffstat (limited to 'base/common/src/org')
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/APDU.java35
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/DeleteFileGP211APDU.java31
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/ExternalAuthenticateAPDUGP211.java125
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/GetDataAPDU.java11
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/InstallAppletAPDUGP211.java101
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/InstallLoadGP211APDU.java51
-rw-r--r--base/common/src/org/dogtagpki/tps/apdu/LoadFileAPDUGP211.java48
-rw-r--r--base/common/src/org/dogtagpki/tps/main/TPSBuffer.java10
-rw-r--r--base/common/src/org/dogtagpki/tps/main/TPSException.java4
-rw-r--r--base/common/src/org/dogtagpki/tps/main/Util.java165
10 files changed, 576 insertions, 5 deletions
diff --git a/base/common/src/org/dogtagpki/tps/apdu/APDU.java b/base/common/src/org/dogtagpki/tps/apdu/APDU.java
index c1aa51716..86f07ee70 100644
--- a/base/common/src/org/dogtagpki/tps/apdu/APDU.java
+++ b/base/common/src/org/dogtagpki/tps/apdu/APDU.java
@@ -67,6 +67,7 @@ public abstract class APDU {
protected TPSBuffer data = null;
protected TPSBuffer plainText = null;
protected TPSBuffer mac = null;
+ protected TPSBuffer trailer = null;
public APDU() {
data = new TPSBuffer();
@@ -101,6 +102,10 @@ public abstract class APDU {
mac = theMac;
}
+ public void setTrailer(TPSBuffer theTrailer) {
+ trailer = theTrailer;
+ }
+
/**
* Retrieves APDU's encoding.
* The encoding of APDU is as follows:
@@ -140,6 +145,10 @@ public abstract class APDU {
encoding.add(mac);
}
+ if (trailer != null) {
+ encoding.add(trailer);
+ }
+
return encoding;
}
@@ -156,7 +165,7 @@ public abstract class APDU {
return mac;
}
- public void secureMessage(PK11SymKey encKey) throws EBaseException {
+ public void secureMessage(PK11SymKey encKey, byte protocol) throws EBaseException {
if (encKey == null) {
throw new EBaseException("APDU.secureData: No input encrytion session key!");
@@ -169,14 +178,24 @@ public abstract class APDU {
TPSBuffer dataEncrypted = null;
dataToEnc = new TPSBuffer();
- dataToEnc.add((byte) data.size());
+
+ if(protocol == (byte) 1) {
+ dataToEnc.add((byte) data.size());
+ }
+
dataToEnc.add(data);
int dataSize = dataToEnc.size();
int rem = dataSize % 8;
if (rem == 0) {
- padNeeded = 0;
+
+ if (protocol == (byte) 1) {
+ padNeeded = 0;
+ }
+ else if (protocol == (byte) 2) {
+ padNeeded = 8;
+ }
} else if (dataSize < 8) {
padNeeded = 8 - dataSize;
} else {
@@ -198,6 +217,16 @@ public abstract class APDU {
data.set(dataEncrypted);
}
+ public void secureMessageSCP02(PK11SymKey encKey) throws EBaseException {
+
+ if (encKey == null) {
+ throw new EBaseException("APDU.secureDataSCP02: Invalid input data!");
+ }
+
+ secureMessage(encKey,(byte) 2);
+
+ }
+
public Type getType() {
return Type.APDU_UNDEFINED;
}
diff --git a/base/common/src/org/dogtagpki/tps/apdu/DeleteFileGP211APDU.java b/base/common/src/org/dogtagpki/tps/apdu/DeleteFileGP211APDU.java
new file mode 100644
index 000000000..ec91f50d6
--- /dev/null
+++ b/base/common/src/org/dogtagpki/tps/apdu/DeleteFileGP211APDU.java
@@ -0,0 +1,31 @@
+package org.dogtagpki.tps.apdu;
+
+import org.dogtagpki.tps.main.TPSBuffer;
+
+public class DeleteFileGP211APDU extends APDU {
+ public DeleteFileGP211APDU(TPSBuffer aid) {
+ trailer = new TPSBuffer();
+ trailer.add((byte) 0x0);
+
+ setCLA((byte) 0x84);
+ setINS((byte) 0xE4);
+ setP1((byte) 0x00);
+ setP2((byte) 0x80);
+
+ TPSBuffer AIDTLV = new TPSBuffer();
+
+ AIDTLV.add((byte) 0x4f);
+ AIDTLV.add((byte) aid.size());
+
+ AIDTLV.add(aid);
+
+ setData(AIDTLV);
+
+ }
+
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/base/common/src/org/dogtagpki/tps/apdu/ExternalAuthenticateAPDUGP211.java b/base/common/src/org/dogtagpki/tps/apdu/ExternalAuthenticateAPDUGP211.java
new file mode 100644
index 000000000..bd687848c
--- /dev/null
+++ b/base/common/src/org/dogtagpki/tps/apdu/ExternalAuthenticateAPDUGP211.java
@@ -0,0 +1,125 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps.apdu;
+
+import org.dogtagpki.tps.main.TPSBuffer;
+
+public class ExternalAuthenticateAPDUGP211 extends APDU {
+
+ public enum SecurityLevel {
+ SECURE_MSG_NONE, //not yet supported
+ CMAC,
+ CDEC_CMAC,
+ RMAC,
+ CMAC_RMAC,
+ CDEC_CMAC_RMAC
+
+ }
+
+ public ExternalAuthenticateAPDUGP211(TPSBuffer theData, SecurityLevel securityLevel) {
+ setCLA((byte) 0x84);
+ setINS((byte) 0x82);
+
+ setP1(securityLevelToByte(securityLevel));
+ setP2((byte) 0x0);
+
+ setData(theData);
+ }
+
+ public TPSBuffer getHostCryptogram()
+ {
+ return getData();
+ }
+
+ @Override
+ public APDU.Type getType()
+ {
+ return APDU.Type.APDU_EXTERNAL_AUTHENTICATE;
+ }
+
+ public static byte securityLevelToByte(SecurityLevel level) {
+ byte result = 0;
+
+ switch (level) {
+ case SECURE_MSG_NONE:
+ result = 0x0;
+ break;
+ case CMAC:
+ result = 0x1;
+ break;
+ case CDEC_CMAC:
+ result = 0x03;
+ break;
+ case RMAC:
+ result = 0x10;
+ break;
+
+ case CMAC_RMAC:
+ result = 0x11;
+ break;
+
+ case CDEC_CMAC_RMAC:
+ result = 0x13;
+ break;
+
+ default:
+ result = 0;
+ break;
+
+ }
+
+ return result;
+ }
+
+ public static SecurityLevel byteToSecurityLevel(byte level) {
+
+ SecurityLevel result = SecurityLevel.SECURE_MSG_NONE;
+
+ switch (level) {
+
+ case 0:
+ result = SecurityLevel.SECURE_MSG_NONE;
+ break;
+ case 1:
+ result = SecurityLevel.CMAC;
+ break;
+ case 0x03:
+ result = SecurityLevel.CDEC_CMAC;
+ break;
+ case 0x10:
+ result = SecurityLevel.RMAC;
+ break;
+
+ case 0x13:
+ result = SecurityLevel.CDEC_CMAC_RMAC;
+ break;
+ default:
+ result = SecurityLevel.SECURE_MSG_NONE;
+ break;
+ }
+
+ return result;
+
+ }
+
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/base/common/src/org/dogtagpki/tps/apdu/GetDataAPDU.java b/base/common/src/org/dogtagpki/tps/apdu/GetDataAPDU.java
index 7cd52fcd1..6a2e8ed13 100644
--- a/base/common/src/org/dogtagpki/tps/apdu/GetDataAPDU.java
+++ b/base/common/src/org/dogtagpki/tps/apdu/GetDataAPDU.java
@@ -32,6 +32,17 @@ public class GetDataAPDU extends APDU {
setP2((byte) 0x7F);
}
+ public GetDataAPDU(byte[] identifier) {
+
+ this();
+
+ if(identifier != null && identifier.length == 2) {
+ setP1(identifier[0]);
+ setP2(identifier[1]);
+ }
+
+ }
+
@Override
public Type getType()
{
diff --git a/base/common/src/org/dogtagpki/tps/apdu/InstallAppletAPDUGP211.java b/base/common/src/org/dogtagpki/tps/apdu/InstallAppletAPDUGP211.java
new file mode 100644
index 000000000..a2bae0e14
--- /dev/null
+++ b/base/common/src/org/dogtagpki/tps/apdu/InstallAppletAPDUGP211.java
@@ -0,0 +1,101 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+package org.dogtagpki.tps.apdu;
+
+import org.dogtagpki.tps.main.TPSBuffer;
+
+public class InstallAppletAPDUGP211 extends APDU {
+
+ public InstallAppletAPDUGP211(TPSBuffer packageAID, TPSBuffer appletAID,
+ byte appPrivileges, int instanceSize, int appletMemorySize)
+ {
+ trailer = new TPSBuffer();
+ trailer.add((byte)0x0);
+ setCLA((byte) 0x84);
+ setINS((byte) 0xE6);
+ setP1((byte) 0x0C);
+ setP2((byte) 0x00);
+
+ data = new TPSBuffer();
+ data.add((byte) packageAID.size());
+ data.add(packageAID);
+ data.add((byte) appletAID.size());
+ data.add(appletAID);
+ data.add((byte) appletAID.size());
+ data.add(appletAID);
+
+ data.add((byte) 0x01); // length of application privileges byte
+ data.add(appPrivileges);
+
+ TPSBuffer installParams = new TPSBuffer();
+ installParams.add((byte) 0xEF);
+ installParams.add((byte) 0x04);
+ installParams.add((byte) 0xC8);
+ installParams.add((byte) 0x02);
+
+ installParams.add((byte) ((instanceSize >> 8) & 0xff));
+ installParams.add((byte) (instanceSize & 0xff));
+ installParams.add((byte) 0xC9);
+
+ //Now add some applet specific init data that the applet supports
+ //Length of applet specific data
+
+ installParams.add((byte) 0x04);
+
+ //Issuer info length.
+ //Leave this to zero since TPS already writes phone home info to card.
+ installParams.add((byte) 0x00);
+
+ //Length of applet memory size
+ installParams.add((byte) 0x02);
+
+ // Applet memory block size
+
+ installParams.add((byte) ((appletMemorySize >> 8) & 0xff));
+ installParams.add((byte) (appletMemorySize & 0xff));
+
+ data.add((byte) installParams.size());
+ data.add(installParams);
+ data.add((byte) 0x00); // size of token return data
+ }
+
+ /**
+ * Constructs Install Applet APDU.
+ */
+ public InstallAppletAPDUGP211(TPSBuffer theData)
+ {
+ trailer = new TPSBuffer();
+ trailer.add((byte)0x0);
+ setCLA((byte) 0x84);
+ setINS((byte) 0xE6);
+ setP1((byte) 0x0C);
+ setP2((byte) 0x00);
+ setData(theData);
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.APDU_INSTALL_APPLET;
+ }
+
+}
diff --git a/base/common/src/org/dogtagpki/tps/apdu/InstallLoadGP211APDU.java b/base/common/src/org/dogtagpki/tps/apdu/InstallLoadGP211APDU.java
new file mode 100644
index 000000000..d277fc6a1
--- /dev/null
+++ b/base/common/src/org/dogtagpki/tps/apdu/InstallLoadGP211APDU.java
@@ -0,0 +1,51 @@
+package org.dogtagpki.tps.apdu;
+
+import org.dogtagpki.tps.main.TPSBuffer;
+
+import com.netscape.certsrv.apps.CMS;
+
+public class InstallLoadGP211APDU extends APDU {
+
+ public InstallLoadGP211APDU(TPSBuffer packageAID, TPSBuffer sdAID,
+ int fileLen) {
+ setCLA((byte) 0x84);
+ setINS((byte) 0xE6);
+ setP1((byte) 0x02);
+ setP2((byte) 0x00);
+
+
+ CMS.debug("InstlalLoadGP211APDU: packageAID " + packageAID.toHexString() + " aid size: " + packageAID.size() + " fileLen: " + fileLen);
+
+ TPSBuffer inputData = new TPSBuffer();
+
+ // inputData.add((byte) 0x0);
+
+ inputData.add((byte) packageAID.size());
+ inputData.add(packageAID);
+ inputData.add((byte) sdAID.size());
+ inputData.add(sdAID);
+
+ //work in file size here
+
+ inputData.add((byte) 0x00);
+ inputData.add((byte) 0x06);
+
+ inputData.add((byte) 0xEF);
+ inputData.add((byte) 0x04);
+ inputData.add((byte) 0xc6);
+
+
+ inputData.add((byte) 0x02);
+ int finalLen = fileLen + 24 + sdAID.size();
+ inputData.addInt2Bytes(finalLen);
+
+ //assume no load file data block hash
+ inputData.add((byte) 0x0);
+
+ setData(inputData);
+
+ trailer = new TPSBuffer();
+ trailer.add((byte)0x0);
+ }
+
+}
diff --git a/base/common/src/org/dogtagpki/tps/apdu/LoadFileAPDUGP211.java b/base/common/src/org/dogtagpki/tps/apdu/LoadFileAPDUGP211.java
new file mode 100644
index 000000000..23e1ed790
--- /dev/null
+++ b/base/common/src/org/dogtagpki/tps/apdu/LoadFileAPDUGP211.java
@@ -0,0 +1,48 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+package org.dogtagpki.tps.apdu;
+
+import org.dogtagpki.tps.main.TPSBuffer;
+
+public class LoadFileAPDUGP211 extends APDU {
+ /**
+ * Constructs Load File APDU.
+ */
+ public LoadFileAPDUGP211(byte refControl, byte blockNum, TPSBuffer theData)
+ {
+ trailer = new TPSBuffer();
+ setCLA((byte) 0x84);
+ setINS((byte) 0xE8);
+ setP1(refControl);
+ setP2(blockNum);
+
+ setData(theData);
+
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.APDU_LOAD_FILE;
+ }
+
+}
+
diff --git a/base/common/src/org/dogtagpki/tps/main/TPSBuffer.java b/base/common/src/org/dogtagpki/tps/main/TPSBuffer.java
index 242f0825e..24c0b490a 100644
--- a/base/common/src/org/dogtagpki/tps/main/TPSBuffer.java
+++ b/base/common/src/org/dogtagpki/tps/main/TPSBuffer.java
@@ -156,6 +156,12 @@ public class TPSBuffer {
buf = newContents.toBytesArray();
}
+ public void set(byte [] newContents) {
+ if (newContents == null)
+ return;
+ buf = newContents;
+ }
+
/**
* Append operators.
*/
@@ -361,6 +367,10 @@ public class TPSBuffer {
return l1 + l2 + l3 + l4;
}
+ public void reset() {
+ buf = new byte[0];
+ }
+
public static void main(String[] args) {
byte[] first = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a };
diff --git a/base/common/src/org/dogtagpki/tps/main/TPSException.java b/base/common/src/org/dogtagpki/tps/main/TPSException.java
index 0d89aae5b..940e89ad1 100644
--- a/base/common/src/org/dogtagpki/tps/main/TPSException.java
+++ b/base/common/src/org/dogtagpki/tps/main/TPSException.java
@@ -26,8 +26,8 @@ public class TPSException extends EBaseException {
private static final long serialVersionUID = -678878301521643436L;
private TPSStatus status;
- public TPSException(String msg) {
- super(msg);
+ public TPSException(String e) {
+ super(e);
status = TPSStatus.STATUS_ERROR_CONTACT_ADMIN;
}
diff --git a/base/common/src/org/dogtagpki/tps/main/Util.java b/base/common/src/org/dogtagpki/tps/main/Util.java
index c10262208..2973bb8ec 100644
--- a/base/common/src/org/dogtagpki/tps/main/Util.java
+++ b/base/common/src/org/dogtagpki/tps/main/Util.java
@@ -43,6 +43,7 @@ import org.mozilla.jss.pkcs11.PK11SymKey;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.cmsutil.util.Utils;
+import com.netscape.symkey.SessionKey;
public class Util {
@@ -171,6 +172,166 @@ public class Util {
return Utils.SpecialEncode(data.toBytesArray());
}
+ public static TPSBuffer computeEncEcbDes(PK11SymKey symKey, TPSBuffer input) throws EBaseException {
+
+ //Asssume 8 bytes message
+ if (symKey == null || input == null || input.size() != 8) {
+ throw new EBaseException("Util.computeEncEcbDes: invalid input data!");
+ }
+
+ CMS.debug("Util.computeEncEcbDes entering... ");
+
+ TPSBuffer result = null;
+ CryptoToken token = null;
+
+ int inputLen = input.size();
+
+ TPSBuffer message = new TPSBuffer(input);
+
+ CMS.debug("Util.computeEncEcbDes: input data. " + message.toHexString() + " input len: " + inputLen);
+
+ try {
+
+ token = CryptoManager.getInstance().getInternalKeyStorageToken();
+
+ PK11SymKey des = SessionKey.DeriveDESKeyFrom3DesKey(token.getName(), symKey, 0x00000121 /*CKM_DES_ECB */);
+
+ if (des == null) {
+ throw new EBaseException("Util.computeEncEcbDes: Can't derive single des key from triple des key!");
+ }
+
+ TPSBuffer desDebug = new TPSBuffer(des.getEncoded());
+
+ CMS.debug("des key debug bytes: " + desDebug.toHexString());
+
+ Cipher cipher = token.getCipherContext(EncryptionAlgorithm.DES_ECB);
+
+ result = new TPSBuffer();
+
+ cipher.initEncrypt(des);
+ byte[] ciphResult = cipher.doFinal(message.toBytesArray());
+
+ if (ciphResult.length != 8) {
+ throw new EBaseException("Invalid cipher in Util.computeEncEcbDes");
+ }
+
+ result.set(ciphResult);
+
+ CMS.debug("Util.computeEncEcbDes: encrypted bloc: " + result.toHexString());
+
+ } catch (Exception e) {
+ throw new EBaseException("Util.computeMACdes3des: Cryptographic problem encountered! " + e.toString());
+ }
+
+ return result;
+ }
+
+ public static TPSBuffer computeMACdes3des(PK11SymKey symKey, TPSBuffer input, TPSBuffer initialIcv)
+ throws EBaseException {
+
+ if (symKey == null || input == null || initialIcv == null || initialIcv.size() != 8) {
+ throw new EBaseException("Util.coputeMACdes3des: invalid input data!");
+ }
+
+ CMS.debug("Util.computeMACdes3des entering... Initial icv: " + initialIcv.toHexString());
+
+ TPSBuffer output = null;
+ TPSBuffer mac = null;
+ CryptoToken token = null;
+
+ int inputLen = input.size();
+
+ TPSBuffer message = new TPSBuffer(input);
+ CMS.debug("Util.computeMACdes3des entering... Input message: " + message.toHexString() + " message.size(): "
+ + message.size());
+
+ //Add the padding, looks like we need this even if the remainder is 0
+ int remainder = inputLen % 8;
+
+ CMS.debug("Util.computeMACdes3des remainder: " + remainder);
+
+ TPSBuffer macPad = new TPSBuffer(8);
+ macPad.setAt(0, (byte) 0x80);
+
+ TPSBuffer padBuff = macPad.substr(0, 8 - remainder);
+
+ message.add(padBuff);
+ inputLen += (8 - remainder);
+
+ CMS.debug("Util.computeMACdes3des: padded input data. " + message.toHexString() + " input len: " + inputLen);
+
+ try {
+
+ token = CryptoManager.getInstance().getInternalKeyStorageToken();
+
+ PK11SymKey des = SessionKey.DeriveDESKeyFrom3DesKey(token.getName(), symKey, 0x00000122 /* CKM_DES_CBC */);
+
+ if (des == null) {
+ throw new EBaseException("Util.computeMACdes3des: Can't derive single des key from tripe des key!");
+ }
+
+ TPSBuffer desDebug = new TPSBuffer(des.getEncoded());
+
+ CMS.debug("des key debug bytes: " + desDebug.toHexString());
+
+ Cipher cipher = token.getCipherContext(EncryptionAlgorithm.DES_CBC);
+ Cipher cipher3des = token.getCipherContext(EncryptionAlgorithm.DES3_CBC);
+ mac = new TPSBuffer(initialIcv);
+
+ AlgorithmParameterSpec algSpec = new IVParameterSpec(initialIcv.toBytesArray());
+
+ int inputOffset = 0;
+
+ while (inputLen > 8)
+ {
+
+ mac.set(message.substr(inputOffset, 8));
+
+ // CMS.debug("About to encrypt1des: " + mac.toHexString());
+ cipher.initEncrypt(des, algSpec);
+ byte[] ciphResult = cipher.doFinal(mac.toBytesArray());
+
+ if (ciphResult.length != mac.size()) {
+ throw new EBaseException("Invalid cipher in Util.computeMAC");
+ }
+
+ mac.set(ciphResult);
+ algSpec = new IVParameterSpec(ciphResult);
+
+ // CMS.debug("Util.computeMACdes3des: des encrypted bloc: " + mac.toHexString());
+
+ inputLen -= 8;
+ inputOffset += 8;
+ }
+
+ // Now do the 3DES portion of the operation
+
+ TPSBuffer newICV = new TPSBuffer(mac);
+
+ CMS.debug("Util.computeMACdes3des: inputOffset: " + inputOffset);
+
+ mac.set(message.substr(inputOffset, 8));
+
+ CMS.debug("About to encrypt 3des: " + mac.toHexString() + " icv: " + newICV.toHexString());
+
+ cipher3des.initEncrypt(symKey, new IVParameterSpec(newICV.toBytesArray()));
+ byte[] ciphResultFinal = cipher3des.doFinal(mac.toBytesArray());
+
+ if (ciphResultFinal.length != mac.size()) {
+ throw new EBaseException("Invalid cipher in Util.computeMAC");
+ }
+
+ output = new TPSBuffer(ciphResultFinal);
+
+ CMS.debug("Util.computeMACdes3des: final mac results: " + output.toHexString());
+
+ } catch (Exception e) {
+ throw new EBaseException("Util.computeMACdes3des: Cryptographic problem encountered! " + e.toString());
+ }
+
+ return output;
+ }
+
public static TPSBuffer computeMAC(PK11SymKey symKey, TPSBuffer input, TPSBuffer icv) throws EBaseException {
TPSBuffer output = null;
TPSBuffer result = null;
@@ -271,6 +432,8 @@ public class Util {
throw new EBaseException("Util.encryptData: called with no sym key or no data!");
}
+ CMS.debug("Util.encryptData: dataToEnc: " + dataToEnc.toHexString());
+
CryptoToken token = null;
try {
@@ -280,9 +443,11 @@ public class Util {
AlgorithmParameterSpec algSpec = null;
int len = EncryptionAlgorithm.DES3_CBC.getIVLength();
+
byte[] iv = new byte[len]; // Assume iv set to 0's as in current TPS
algSpec = new IVParameterSpec(iv);
+
cipher.initEncrypt(encKey, algSpec);
byte[] encryptedBytes = cipher.doFinal(dataToEnc.toBytesArray());