From b40bfa06fb709386d21553a73700134cf013301d Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 1 Mar 2016 15:14:50 +0100 Subject: some more SSO transfer module updates --- .../modules/ssotransfer/SSOTransferConstants.java | 3 +- .../ssotransfer/servlet/SSOTransferServlet.java | 129 ++++++++++++++------- .../ssotransfer/utils/SSOContainerUtils.java | 2 +- 3 files changed, 90 insertions(+), 44 deletions(-) (limited to 'id/server/modules/moa-id-module-ssoTransfer/src/main/java/at') 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 56bbeed5c..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,34 +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()); + //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); - - //TODO decrypt CSR - byte[] decryptedCSR = encryptedCSR; + 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()); @@ -461,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; @@ -533,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()); @@ -595,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 cc6b34cf5..0d96afc6a 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 @@ -360,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()); -- cgit v1.2.3