diff options
Diffstat (limited to 'base/common/src')
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()); |
