diff options
Diffstat (limited to 'id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java')
-rw-r--r-- | id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java new file mode 100644 index 000000000..7dd5c39ab --- /dev/null +++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java @@ -0,0 +1,221 @@ +package at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20; + +import java.security.Key; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.jose4j.jwa.AlgorithmConstraints; +import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; +import org.jose4j.jws.AlgorithmIdentifiers; +import org.jose4j.jws.JsonWebSignature; +import org.jose4j.lang.JoseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.Constants; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.data.VerificationResult; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SL20Exception; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SL20SecurityException; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SLCommandoBuildException; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SLCommandoParserException; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.utils.X509Utils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.FileUtils; +import at.gv.egovernment.moa.util.KeyStoreUtils; + +@Service +public class JsonSecurityUtils implements IJOSETools{ + + @Autowired(required=true) AuthConfiguration authConfig; + private Key signPrivKey = null; + private X509Certificate[] signCertChain = null; + + private Key encPrivKey = null; + private X509Certificate[] encCertChain = null; + + @PostConstruct + protected void initalize() { + Logger.info("Initialize SL2.0 authentication security constrains ... "); + try { + KeyStore keyStore = KeyStoreUtils.loadKeyStore(getKeyStoreFilePath(), + getKeyStorePassword()); + + //load signing key + signPrivKey = keyStore.getKey(getSigningKeyAlias(), getSigningKeyPassword().toCharArray()); + Certificate[] certChainSigning = keyStore.getCertificateChain(getSigningKeyAlias()); + signCertChain = new X509Certificate[certChainSigning.length]; + for (int i=0; i<certChainSigning.length; i++) { + if (certChainSigning[i] instanceof X509Certificate) { + signCertChain[i] = (X509Certificate)certChainSigning[i]; + } else + Logger.warn("NO X509 certificate for signing: " + certChainSigning[i].getType()); + + } + + //load encryption key + try { + encPrivKey = keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray()); + if (encPrivKey != null) { + Certificate[] certChainEncryption = keyStore.getCertificateChain(getSigningKeyAlias()); + encCertChain = new X509Certificate[certChainEncryption.length]; + for (int i=0; i<certChainEncryption.length; i++) { + if (certChainEncryption[i] instanceof X509Certificate) { + encCertChain[i] = (X509Certificate)certChainEncryption[i]; + } else + Logger.warn("NO X509 certificate for encryption: " + certChainEncryption[i].getType()); + } + } else + Logger.info("No encryption key for SL2.0 found. End-to-End encryption is not used."); + + } catch (Exception e) { + Logger.warn("No encryption key for SL2.0 found. End-to-End encryption is not used. Reason: " + e.getMessage(), e); + + } + + //some short validation + if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) { + Logger.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); + throw new SL20Exception("sl20.03", new Object[]{"Can NOT open private key for signing"}); + + } + + if (signCertChain == null || signCertChain.length == 0) { + Logger.info("NO certificate for SL2.0 signing. KeyStore=" + getKeyStoreFilePath()); + throw new SL20Exception("sl20.03", new Object[]{"NO certificate for SL2.0 signing"}); + + } + + Logger.info("SL2.0 authentication security constrains initialized."); + + } catch ( Exception e) { + Logger.error("SL2.0 security constrains initialization FAILED.", e); + + } + + } + + + @Override + public String createSignature(String payLoad) throws SLCommandoBuildException { + try { + JsonWebSignature jws = new JsonWebSignature(); + + //set payload + jws.setPayload(payLoad); + + //set basic header + jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND); + + //set signing information + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); + jws.setKey(signPrivKey); + jws.setCertificateChainHeaderValue(signCertChain); + + return jws.getCompactSerialization(); + + } catch (JoseException e) { + Logger.warn("Can NOT sign SL2.0 command.", e); + throw new SLCommandoBuildException("Can NOT sign SL2.0 command.", e); + + } + + } + + @Override + public VerificationResult validateSignature(String serializedContent) throws SL20Exception { + try { + JsonWebSignature jws = new JsonWebSignature(); + //set payload + jws.setCompactSerialization(serializedContent); + + //set security constrains + jws.setAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()]))); + + //load signinc certs + List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue(); + List<X509Certificate> sortedX5cCerts = null; + if (x5cCerts == null || x5cCerts.size() < 1) { + Logger.info("Signed SL2.0 response contains NO signature certificate"); + throw new SLCommandoParserException("Signed SL2.0 response contains NO signature certificate"); + + } + Logger.trace("Sorting received X509 certificates ... "); + sortedX5cCerts = X509Utils.sortCertificates(x5cCerts); + + //set verification key + jws.setKey(sortedX5cCerts.get(0).getPublicKey()); + + //validate signature + boolean valid = jws.verifySignature(); + if (!valid) { + Logger.info("JWS signature invalide. Stopping authentication process ..."); + Logger.debug("Received JWS msg: " + serializedContent); + throw new SL20SecurityException("JWS signature invalide."); + + } + + //load payLoad + JsonElement sl20Req = new JsonParser().parse(jws.getPayload()); + + return new VerificationResult(sl20Req.getAsJsonObject(), sortedX5cCerts, valid) ; + + } catch (JoseException e) { + Logger.warn("SL2.0 commando signature validation FAILED", e); + throw new SL20SecurityException(new Object[]{e.getMessage()}, e); + + } + + } + + + @Override + public X509Certificate getEncryptionCertificate() { + //TODO: maybe update after SL2.0 update on encryption certificate parts + if (encCertChain !=null && encCertChain.length > 0) + return encCertChain[0]; + else + return null; + } + + private String getKeyStoreFilePath() { + return FileUtils.makeAbsoluteURL( + authConfig.getBasicMOAIDConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PATH), + authConfig.getRootConfigFileDir()); + } + + private String getKeyStorePassword() { + return authConfig.getBasicMOAIDConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD).trim(); + + } + + private String getSigningKeyAlias() { + return authConfig.getBasicMOAIDConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS).trim(); + } + + private String getSigningKeyPassword() { + return authConfig.getBasicMOAIDConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD).trim(); + } + + private String getEncryptionKeyAlias() { + return authConfig.getBasicMOAIDConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS).trim(); + } + + private String getEncryptionKeyPassword() { + return authConfig.getBasicMOAIDConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD).trim(); + } + +} |