summaryrefslogtreecommitdiffstats
path: root/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
diff options
context:
space:
mode:
authorJack Magne <jmagne@dhcp-16-206.sjc.redhat.com>2016-06-01 10:23:33 -0700
committerJack Magne <jmagne@dhcp-16-206.sjc.redhat.com>2017-03-14 15:25:34 -0700
commit6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb (patch)
tree666adf630ac8316eb509bd9b32c7a36d12056879 /base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
parent648361bac96996e76339b9390b8a8882dcde8ad7 (diff)
downloadpki-6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb.tar.gz
pki-6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb.tar.xz
pki-6d6b6f954a5bf6730d4b53875c7cc122eb3ab5eb.zip
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.
Diffstat (limited to 'base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java')
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java162
1 files changed, 129 insertions, 33 deletions
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);