aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/moa-id-module-ssoTransfer/src/main/java/at')
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java3
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java130
-rw-r--r--id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java10
3 files changed, 98 insertions, 45 deletions
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java
index cc60bbd20..ce3a7856b 100644
--- a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/SSOTransferConstants.java
@@ -43,6 +43,7 @@ public class SSOTransferConstants {
public static final String SSOCONTAINER_KEY_TYPE = "type";
public static final String SSOCONTAINER_VALUE_TYPE_TRANSER = "TRANSFER";
public static final String SSOCONTAINER_VALUE_TYPE_PERSIST = "PERSIST";
+ public static final String SSOCONTAINER_VALUE_TYPE_SSO = "SSO";
public static final String SSOCONTAINER_KEY_URL = "url";
@@ -50,7 +51,7 @@ public class SSOTransferConstants {
public static final String SSOCONTAINER_KEY_DH_PRIME = "prime";
public static final String SSOCONTAINER_KEY_DH_GENERATOR = "generator";
- public static final String SSOCONTAINER_KEY_CSR = "csr";
+ public static final String SSOCONTAINER_KEY_CSR = "certificate";
public static final String SSOCONTAINER_KEY_VALIDTO = "validTo";
public static final String SSOCONTAINER_KEY_ENTITYID = "entityID";
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java
index 80c2663fb..48ef5b526 100644
--- a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/servlet/SSOTransferServlet.java
@@ -33,6 +33,7 @@ import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -42,9 +43,14 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.util.Date;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyAgreement;
+import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPublicKeySpec;
+import javax.crypto.spec.SecretKeySpec;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
import javax.servlet.http.HttpServletRequest;
@@ -182,7 +188,8 @@ public class SSOTransferServlet{
Object tokenObj = req.getParameter(SSOTransferConstants.REQ_PARAM_TOKEN);
if (tokenObj != null && tokenObj instanceof String) {
String token = (String)tokenObj;
- try {
+ try {
+ Logger.debug("Load token:" + token + " from storage.");
SSOTransferContainer container = transactionStorage.get(token, SSOTransferContainer.class, transmisionTimeOut * 1000);
if (container != null) {
AuthenticationSession moaSession = new AuthenticationSession("123456", new Date());
@@ -213,51 +220,55 @@ public class SSOTransferServlet{
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Single Sign-On session transfer token is not valid any more.");
} catch (OperatorCreationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (CredentialsNotAvailableException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (PKCSException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (CertificateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (InvalidKeyException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (NoSuchAlgorithmException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (InvalidKeySpecException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (SessionDataStorageException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
} catch (ParseException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (IllegalBlockSizeException e) {
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (BadPaddingException e) {
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
+ } catch (NoSuchPaddingException e) {
+ Logger.warn("Device inpersonisation FAILED: " + e.getMessage(), e);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+
}
-
-
-
+
} else {
Logger.info("Servlet " + getClass().getName() + " receive a NOT valid request.");
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Request not valid.");
@@ -345,8 +356,17 @@ public class SSOTransferServlet{
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
} catch (SessionDataStorageException e) {
- // TODO Auto-generated catch block
e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+ } catch (BadPaddingException e) {
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+ } catch (NoSuchPaddingException e) {
+ e.printStackTrace();
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
}
@@ -416,7 +436,8 @@ public class SSOTransferServlet{
}
private void internalTransferPersonalInformation(HttpServletRequest req, HttpServletResponse resp,
- SSOTransferContainer container, AuthenticationSession moaSession, boolean developmentMode) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, OperatorCreationException, CredentialsNotAvailableException, PKCSException, CertificateException, SessionDataStorageException {
+ SSOTransferContainer container, AuthenticationSession moaSession, boolean developmentMode) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, OperatorCreationException, CredentialsNotAvailableException, PKCSException, CertificateException, SessionDataStorageException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException {
+ Logger.debug("");
JsonObject receivedData = getJSONObjectFromPostMessage(req, developmentMode);
if (receivedData == null) {
@@ -424,33 +445,40 @@ public class SSOTransferServlet{
throw new IOException("No data received");
}
-
- //TODO: check if needed
- //JsonObject reveivedSession = receivedData.get("session").getAsJsonObject();
-
+
String mobilePubKeyBase64 = receivedData.get(
SSOTransferConstants.SSOCONTAINER_KEY_DH_PUBKEY).getAsString();
String mobileCSRBase64 = receivedData.get(
SSOTransferConstants.SSOCONTAINER_KEY_CSR).getAsString();
- Logger.trace("Receive PubKey:" +mobilePubKeyBase64 +
- " | CSR:" + mobileCSRBase64);
+ Logger.debug("Receive PubKey:" +mobilePubKeyBase64 + " | CSR:" + mobileCSRBase64);
//finish DH key agreement
- BigInteger mobilePubKey = new BigInteger(Base64Utils.decode(mobilePubKeyBase64, false));
+ BigInteger mobilePubKey = new BigInteger(Base64Utils.decode(mobilePubKeyBase64, true));
DHPublicKeySpec mobilePubKeySpec = new DHPublicKeySpec(mobilePubKey,
container.getDhParams().getF().getP(),
container.getDhParams().getF().getG());
byte[] sharedSecret = getSecret(mobilePubKeySpec, container.getDhParams().getS());
- Logger.debug("Finished Diffie-Hellman key exchange. --> Starting CSR decryption ...");
- //TODO decrypt CSR
- byte[] decryptedCSR = Base64Utils.decode(mobileCSRBase64, true);
-
+ //build ASE256 key
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ digest.reset();
+ byte[] hashedSecret = digest.digest(sharedSecret);
+
+ //decrypt CSR
+ Logger.debug("Finished Diffie-Hellman key exchange. --> Starting CSR decryption ...");
+ byte[] encryptedCSR = Base64Utils.decode(mobileCSRBase64, true);
+ Logger.debug("EncCSR:" + Base64Utils.encode(encryptedCSR) + " | Key:" + Base64Utils.encode(hashedSecret));
+ byte[] decryptedCSR = enOrDeCryptCSR(encryptedCSR, hashedSecret, Cipher.DECRYPT_MODE);
+ Logger.debug("DecCSR:" + Base64Utils.encode(decryptedCSR));
+ Logger.debug("CSR decryption finished. --> Starting CSR validation and signing ...");
+
//generate certificate from CSR
X509Certificate mobileCert = signCSRWithMOAKey(decryptedCSR);
+ Logger.debug("CSR validation finished. --> Starting personData generation ... ");
+
moaSession.setGenericDataToSession(
SSOTransferConstants.MOASESSION_DATA_HOLDEROFKEY_CERTIFICATE,
mobileCert.getEncoded());
@@ -460,10 +488,17 @@ public class SSOTransferServlet{
String personInformationToTransfer =
ssoTransferUtils.generateSignedAndEncryptedSSOContainer(
container.getAuthURL(), moaSession, now);
-
+ Logger.debug("PersonData:" + personInformationToTransfer);
+
+ //encrypt personal information
+ Logger.debug("PersonData generation finished. --> Starting personData encryption ... ");
+ byte[] encPersonData = enOrDeCryptCSR(personInformationToTransfer.getBytes(), hashedSecret, Cipher.ENCRYPT_MODE);
+ String encAndEncodedPersonalData = Base64Utils.encode(encPersonData);
+
+ Logger.debug("Encrypt personData finished. --> Send token to device.");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = new PrintWriter(resp.getOutputStream());
- out.print(personInformationToTransfer);
+ out.print(encAndEncodedPersonalData);
out.flush();
return;
@@ -532,9 +567,19 @@ public class SSOTransferServlet{
}
- private X509Certificate signCSRWithMOAKey(byte[] inputCSR) throws IOException, OperatorCreationException, PKCSException, CredentialsNotAvailableException, CertificateException {
+ public byte[] enOrDeCryptCSR(byte[] binBlob, byte[] binSecret, int mode) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
+ byte[] decrypted = null;
+ SecretKeySpec skeySpec = new SecretKeySpec(binSecret, "AES");
+ Cipher cipher = Cipher.getInstance("AES");
+ cipher.init(mode, skeySpec);
+ decrypted = cipher.doFinal(binBlob);
+
+ return decrypted;
+ }
+
+ private X509Certificate signCSRWithMOAKey(byte[] inputCSR) throws IOException, OperatorCreationException, PKCSException, CredentialsNotAvailableException, CertificateException {
PKCS10CertificationRequest csr = new PKCS10CertificationRequest(inputCSR);
-
+
//validate CSR request
ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(
new BouncyCastleProvider()).build(csr.getSubjectPublicKeyInfo());
@@ -594,11 +639,12 @@ public class SSOTransferServlet{
}
JsonParser parser = new JsonParser();
- JsonObject receivedData = null;
- if (MiscUtil.isNotEmpty(receivedPostMessage))
+ JsonObject receivedData = null;
+ Logger.debug("JSON POST msg: " + sb.toString());
+ if (MiscUtil.isNotEmpty(receivedPostMessage)) {
receivedData = (JsonObject) parser.parse(sb.toString());
- else if (developmentMode && MiscUtil.isNotEmpty(req.getParameter("blob"))) {
+ } else if (developmentMode && MiscUtil.isNotEmpty(req.getParameter("blob"))) {
receivedData = (JsonObject) parser.parse(req.getParameter("blob"));
}
diff --git a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java
index dea538f75..ddfd0958f 100644
--- a/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java
+++ b/id/server/modules/moa-id-module-ssoTransfer/src/main/java/at/gv/egovernment/moa/id/auth/modules/ssotransfer/utils/SSOContainerUtils.java
@@ -118,6 +118,10 @@ import iaik.x509.X509Certificate;
*/
@Service("SSOContainerUtils")
public class SSOContainerUtils {
+
+ private static final String PVP_HOLDEROFKEY_NAME = PVPConstants.URN_OID_PREFIX +
+ "1.2.40.0.10.2.1.1.261.xx.xx";
+
public static final List<String> REQUIRED_ATTRIBUTES;
static {
List<String> tmp = new ArrayList<String>();
@@ -133,7 +137,9 @@ public class SSOContainerUtils {
tmp.add(PVPConstants.MANDATE_PROF_REP_OID_NAME);
tmp.add(PVPConstants.MANDATE_PROF_REP_DESC_NAME);
tmp.add(PVPConstants.EID_CITIZEN_QAA_LEVEL_NAME);
- tmp.add(PVPConstants.PVP_HOLDEROFKEY_NAME);
+
+ //TODO: change to final definition
+ tmp.add(PVP_HOLDEROFKEY_NAME);
REQUIRED_ATTRIBUTES = Collections.unmodifiableList(tmp);
}
@@ -354,7 +360,7 @@ public class SSOContainerUtils {
String ssoDataBlob = buildSSOContainerObject(authURL, assertion, new DateTime(date.getTime()));
JsonObject container = new JsonObject();
- container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_TYPE, "SSO");
+ container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_TYPE, SSOTransferConstants.SSOCONTAINER_VALUE_TYPE_SSO);
container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_VALIDTO, subjectConfirmationData.getNotOnOrAfter().toString());
container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_ENTITYID, entityID);
container.addProperty(SSOTransferConstants.SSOCONTAINER_KEY_USERID, authData.getGivenName() + " " + authData.getFamilyName());