aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/Authenticate.java5
-rw-r--r--id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/BuildMetadata.java30
-rw-r--r--id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java8
-rw-r--r--id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/struts/action/IndexAction.java53
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java2
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java10
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java124
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionEncryptionException.java14
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java120
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java16
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java1
-rw-r--r--id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties3
13 files changed, 325 insertions, 86 deletions
diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/Authenticate.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/Authenticate.java
index 8684b8cc1..e298bcdb3 100644
--- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/Authenticate.java
+++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/Authenticate.java
@@ -146,11 +146,12 @@ public class Authenticate extends HttpServlet {
for (SingleSignOnService sss :
idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) {
- if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) { //Get the service address for the binding you wish to use
+ //Get the service address for the binding you wish to use
+ if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
redirectEndpoint = sss;
}
}
-
+
authReq.setDestination(redirectEndpoint.getLocation());
RequestedAuthnContext reqAuthContext =
diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/BuildMetadata.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/BuildMetadata.java
index fa02443dc..9c6f39b30 100644
--- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/BuildMetadata.java
+++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/auth/pvp2/BuildMetadata.java
@@ -142,21 +142,38 @@ public class BuildMetadata extends HttpServlet {
entitiesSignKeyDescriptor.setUse(UsageType.SIGNING);
entitiesSignKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(signingcredential));
Signature entitiesSignature = getSignature(signingcredential);
-
+ spEntitiesDescriptor.setSignature(entitiesSignature);
+
+ //Set AuthRequest Signing certificate
X509Credential authcredential = new KeyStoreX509CredentialAdapter(
keyStore,
config.getPVP2KeystoreAuthRequestKeyAlias(),
- config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray());
-
-
- //Set AuthRequest Signing certificate
+ config.getPVP2KeystoreAuthRequestKeyPassword().toCharArray());
KeyDescriptor signKeyDescriptor = SAML2Utils
.createSAMLObject(KeyDescriptor.class);
signKeyDescriptor.setUse(UsageType.SIGNING);
signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authcredential));
- spEntitiesDescriptor.setSignature(entitiesSignature);
spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor);
+
+ //set AuthRequest encryption certificate
+ if (MiscUtil.isNotEmpty(config.getPVP2KeystoreAuthRequestEncryptionKeyAlias())) {
+ X509Credential authEncCredential = new KeyStoreX509CredentialAdapter(
+ keyStore,
+ config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(),
+ config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray());
+ KeyDescriptor encryKeyDescriptor = SAML2Utils
+ .createSAMLObject(KeyDescriptor.class);
+ encryKeyDescriptor.setUse(UsageType.ENCRYPTION);
+ encryKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(authEncCredential));
+ spSSODescriptor.getKeyDescriptors().add(encryKeyDescriptor);
+
+ } else {
+ log.warn("No Assertion Encryption-Key defined. This setting is not recommended!");
+
+ }
+
+
NameIDFormat persistentnameIDFormat = SAML2Utils.createSAMLObject(NameIDFormat.class);
persistentnameIDFormat.setFormat(NameIDType.PERSISTENT);
@@ -187,6 +204,7 @@ public class BuildMetadata extends HttpServlet {
spSSODescriptor.setWantAssertionsSigned(true);
spSSODescriptor.setAuthnRequestsSigned(true);
+
AttributeConsumingService attributeService =
SAML2Utils.createSAMLObject(AttributeConsumingService.class);
diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java
index fb468967c..6b30c0cfa 100644
--- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java
+++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/config/ConfigurationProvider.java
@@ -258,6 +258,14 @@ public class ConfigurationProvider {
return props.getProperty("general.login.pvp2.keystore.authrequest.key.password");
}
+ public String getPVP2KeystoreAuthRequestEncryptionKeyAlias() {
+ return props.getProperty("general.login.pvp2.keystore.authrequest.encryption.key.alias");
+ }
+
+ public String getPVP2KeystoreAuthRequestEncryptionKeyPassword() {
+ return props.getProperty("general.login.pvp2.keystore.authrequest.encryption.key.password");
+ }
+
public String getPVP2IDPMetadataURL() {
return props.getProperty("general.login.pvp2.idp.metadata.url");
}
diff --git a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/struts/action/IndexAction.java b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/struts/action/IndexAction.java
index c82746dbc..b5896aecf 100644
--- a/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/struts/action/IndexAction.java
+++ b/id/ConfigWebTool/src/main/java/at/gv/egovernment/moa/id/configuration/struts/action/IndexAction.java
@@ -1,5 +1,6 @@
package at.gv.egovernment.moa.id.configuration.struts.action;
+import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
@@ -23,18 +24,24 @@ import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Conditions;
+import org.opensaml.saml2.core.EncryptedAssertion;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.core.SubjectConfirmation;
import org.opensaml.saml2.core.SubjectConfirmationData;
+import org.opensaml.saml2.encryption.Decrypter;
+import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
import org.opensaml.saml2.metadata.IDPSSODescriptor;
import org.opensaml.security.MetadataCredentialResolver;
import org.opensaml.security.MetadataCredentialResolverFactory;
import org.opensaml.security.MetadataCriteria;
import org.opensaml.security.SAMLSignatureProfileValidator;
import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
+import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver;
+import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
+import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.CriteriaSet;
import org.opensaml.xml.security.credential.UsageType;
@@ -43,9 +50,12 @@ import org.opensaml.xml.security.criteria.UsageCriteria;
import org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver;
import org.opensaml.xml.security.keyinfo.KeyInfoCredentialResolver;
import org.opensaml.xml.security.keyinfo.KeyInfoProvider;
+import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
import org.opensaml.xml.security.keyinfo.provider.DSAKeyValueProvider;
import org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider;
import org.opensaml.xml.security.keyinfo.provider.RSAKeyValueProvider;
+import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter;
+import org.opensaml.xml.security.x509.X509Credential;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine;
@@ -261,8 +271,47 @@ public class IndexAction extends ActionSupport implements ServletRequestAware,
if (samlResponse.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
- List<org.opensaml.saml2.core.Assertion> saml2assertions = samlResponse.getAssertions();
-
+ List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>();
+
+ //check encrypted Assertion
+ List<EncryptedAssertion> encryAssertionList = samlResponse.getEncryptedAssertions();
+ if (encryAssertionList != null && encryAssertionList.size() > 0) {
+ //decrypt assertions
+
+ log.debug("Found encryped assertion. Start decryption ...");
+
+ KeyStore keyStore = config.getPVP2KeyStore();
+
+ X509Credential authDecCredential = new KeyStoreX509CredentialAdapter(
+ keyStore,
+ config.getPVP2KeystoreAuthRequestEncryptionKeyAlias(),
+ config.getPVP2KeystoreAuthRequestEncryptionKeyPassword().toCharArray());
+
+
+ StaticKeyInfoCredentialResolver skicr =
+ new StaticKeyInfoCredentialResolver(authDecCredential);
+
+ ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver();
+ encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() );
+ encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() );
+ encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() );
+
+ Decrypter samlDecrypter =
+ new Decrypter(null, skicr, encryptedKeyResolver);
+
+ for (EncryptedAssertion encAssertion : encryAssertionList) {
+ saml2assertions.add(samlDecrypter.decrypt(encAssertion));
+
+ }
+
+ log.debug("Assertion decryption finished. ");
+
+ } else {
+ saml2assertions = samlResponse.getAssertions();
+
+ }
+
+
if (MiscUtil.isEmpty(authID)) {
log.info("NO AuthRequestID");
return Constants.STRUTS_ERROR;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java
index bef58ab59..dc2330f40 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java
@@ -124,7 +124,6 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
RequestAbstractType samlReq = moaRequest.getSamlRequest();
//String xml = PrettyPrinter.prettyPrint(SAML2Utils.asDOMDocument(samlReq));
-
//Logger.info("SAML : " + xml);
if(!moaRequest.isVerified()) {
@@ -137,6 +136,12 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
throw new MOAIDException("Unsupported request", new Object[] {});
}
+ EntityDescriptor metadata = moaRequest.getEntityMetadata();
+ if(metadata == null) {
+ throw new NoMetadataInformationException();
+ }
+ SPSSODescriptor spSSODescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+
AuthnRequest authnRequest = (AuthnRequest)samlReq;
Integer aIdx = authnRequest.getAssertionConsumerServiceIndex();
@@ -144,6 +149,9 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
if(aIdx != null) {
assertionidx = aIdx.intValue();
+
+ } else {
+ assertionidx = SAML2Utils.getDefaultAssertionConsumerServiceIndex(spSSODescriptor);
}
aIdx = authnRequest.getAttributeConsumingServiceIndex();
@@ -153,13 +161,14 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
attributeIdx = aIdx.intValue();
}
- EntityDescriptor metadata = moaRequest.getEntityMetadata();
- if(metadata == null) {
- throw new NoMetadataInformationException();
- }
- SPSSODescriptor spSSODescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
AssertionConsumerService consumerService = spSSODescriptor.getAssertionConsumerServices().get(assertionidx);
- AttributeConsumingService attributeConsumer = spSSODescriptor.getAttributeConsumingServices().get(attributeIdx);
+
+ AttributeConsumingService attributeConsumer = null;
+
+ if (spSSODescriptor.getAttributeConsumingServices() != null &&
+ spSSODescriptor.getAttributeConsumingServices().size() > 0) {
+ attributeConsumer = spSSODescriptor.getAttributeConsumingServices().get(attributeIdx);
+ }
String oaURL = moaRequest.getEntityMetadata().getEntityID();
String binding = consumerService.getBinding();
@@ -176,7 +185,7 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
String useMandate = request.getParameter(PARAM_USEMANDATE);
if(useMandate != null) {
- if(useMandate.equals("true")) {
+ if(useMandate.equals("true") && attributeConsumer != null) {
if(!CheckMandateAttributes.canHandleMandate(attributeConsumer)) {
throw new MandateAttributesNotHandleAbleException();
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java
index 232ad315f..2fe52d032 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java
@@ -67,7 +67,7 @@ public class PostBinding implements IDecoder, IEncoder {
.buildObject();
service.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
service.setLocation(targetLocation);
- context.setOutboundSAMLMessageSigningCredential(credentials);
+ context.setOutboundSAMLMessageSigningCredential(credentials);
context.setPeerEntityEndpoint(service);
// context.setOutboundMessage(authReq);
context.setOutboundSAMLMessage(response);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java
index 418c4a60c..9b43fb999 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java
@@ -3,11 +3,13 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.binding;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.jcp.xml.dsig.internal.dom.DOMURIDereferencer;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.binding.BasicSAMLMessageContext;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder;
import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder;
+import org.opensaml.saml2.binding.security.SAML2AuthnRequestsSignedRule;
import org.opensaml.saml2.binding.security.SAML2HTTPRedirectDeflateSignatureRule;
import org.opensaml.saml2.core.RequestAbstractType;
import org.opensaml.saml2.core.Response;
@@ -31,6 +33,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;
+import at.gv.egovernment.moa.util.DOMUtils;
public class RedirectBinding implements IDecoder, IEncoder {
@@ -84,13 +87,18 @@ public class RedirectBinding implements IDecoder, IEncoder {
SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule(
TrustEngineFactory.getSignatureKnownKeysTrustEngine());
+ SAML2AuthnRequestsSignedRule signedRole = new SAML2AuthnRequestsSignedRule();
+
+
BasicSecurityPolicy policy = new BasicSecurityPolicy();
policy.getPolicyRules().add(signatureRule);
+ policy.getPolicyRules().add(signedRole);
+
SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver(
policy);
messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
messageContext.setSecurityPolicyResolver(resolver);
-
+
decode.decode(messageContext);
signatureRule.evaluate(messageContext);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java
index f21567245..d1d79373c 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java
@@ -64,46 +64,48 @@ public class PVP2AssertionBuilder implements PVPConstants {
RequestedAuthnContext reqAuthnContext = authnRequest
.getRequestedAuthnContext();
- if (reqAuthnContext == null) {
- throw new NoAuthContextException();
- }
-
- boolean stork_qaa_1_4_found = false;
-
AuthnContextClassRef authnContextClassRef = SAML2Utils
.createSAMLObject(AuthnContextClassRef.class);
-
- List<AuthnContextClassRef> reqAuthnContextClassRefIt = reqAuthnContext
- .getAuthnContextClassRefs();
- if (reqAuthnContextClassRefIt.size() == 0) {
- stork_qaa_1_4_found = true;
+ if (reqAuthnContext == null) {
authnContextClassRef.setAuthnContextClassRef(STORK_QAA_1_4);
-
- } else {
- for (AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) {
- String qaa_uri = authnClassRef.getAuthnContextClassRef();
- if (qaa_uri.trim().equals(STORK_QAA_1_4)
- || qaa_uri.trim().equals(STORK_QAA_1_3)
- || qaa_uri.trim().equals(STORK_QAA_1_2)
- || qaa_uri.trim().equals(STORK_QAA_1_1)) {
-
- if (authSession.isForeigner()) {
- //TODO: insert QAA check
-
- stork_qaa_1_4_found = false;
-
- } else {
- stork_qaa_1_4_found = true;
- authnContextClassRef.setAuthnContextClassRef(STORK_QAA_1_4);
+
+ } else {
+
+ boolean stork_qaa_1_4_found = false;
+
+ List<AuthnContextClassRef> reqAuthnContextClassRefIt = reqAuthnContext
+ .getAuthnContextClassRefs();
+
+ if (reqAuthnContextClassRefIt.size() == 0) {
+ stork_qaa_1_4_found = true;
+ authnContextClassRef.setAuthnContextClassRef(STORK_QAA_1_4);
+
+ } else {
+ for (AuthnContextClassRef authnClassRef : reqAuthnContextClassRefIt) {
+ String qaa_uri = authnClassRef.getAuthnContextClassRef();
+ if (qaa_uri.trim().equals(STORK_QAA_1_4)
+ || qaa_uri.trim().equals(STORK_QAA_1_3)
+ || qaa_uri.trim().equals(STORK_QAA_1_2)
+ || qaa_uri.trim().equals(STORK_QAA_1_1)) {
+
+ if (authSession.isForeigner()) {
+ //TODO: insert QAA check
+
+ stork_qaa_1_4_found = false;
+
+ } else {
+ stork_qaa_1_4_found = true;
+ authnContextClassRef.setAuthnContextClassRef(STORK_QAA_1_4);
+ }
+ break;
}
- break;
}
}
- }
-
- if (!stork_qaa_1_4_found) {
- throw new QAANotSupportedException(STORK_QAA_1_4);
+
+ if (!stork_qaa_1_4_found) {
+ throw new QAANotSupportedException(STORK_QAA_1_4);
+ }
}
// reqAuthnContextClassRefIt = reqAuthnContext.getAuthnContextClassRefs()
@@ -144,16 +146,14 @@ public class PVP2AssertionBuilder implements PVPConstants {
SPSSODescriptor spSSODescriptor = peerEntity
.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
-
+
Integer aIdx = authnRequest.getAttributeConsumingServiceIndex();
int idx = 0;
if (aIdx != null) {
idx = aIdx.intValue();
- }
-
- AttributeConsumingService attributeConsumingService = spSSODescriptor
- .getAttributeConsumingServices().get(idx);
+
+ }
AttributeStatement attributeStatement = SAML2Utils
.createSAMLObject(AttributeStatement.class);
@@ -197,32 +197,38 @@ public class PVP2AssertionBuilder implements PVPConstants {
.buildAuthenticationData(authSession, oaParam,
oaParam.getTarget());
- Iterator<RequestedAttribute> it = attributeConsumingService
- .getRequestAttributes().iterator();
- while (it.hasNext()) {
- RequestedAttribute reqAttribut = it.next();
- try {
- Attribute attr = PVPAttributeBuilder.buildAttribute(
- reqAttribut.getName(), authSession, oaParam, authData);
- if (attr == null) {
+ if (spSSODescriptor.getAttributeConsumingServices() != null &&
+ spSSODescriptor.getAttributeConsumingServices().size() > 0) {
+
+ AttributeConsumingService attributeConsumingService = spSSODescriptor
+ .getAttributeConsumingServices().get(idx);
+
+ Iterator<RequestedAttribute> it = attributeConsumingService
+ .getRequestAttributes().iterator();
+ while (it.hasNext()) {
+ RequestedAttribute reqAttribut = it.next();
+ try {
+ Attribute attr = PVPAttributeBuilder.buildAttribute(
+ reqAttribut.getName(), authSession, oaParam, authData);
+ if (attr == null) {
+ if (reqAttribut.isRequired()) {
+ throw new UnprovideableAttributeException(
+ reqAttribut.getName());
+ }
+ } else {
+ attributeStatement.getAttributes().add(attr);
+ }
+ } catch (PVP2Exception e) {
+ Logger.error(
+ "Attribute generation failed! for "
+ + reqAttribut.getFriendlyName(), e);
if (reqAttribut.isRequired()) {
throw new UnprovideableAttributeException(
reqAttribut.getName());
}
- } else {
- attributeStatement.getAttributes().add(attr);
- }
- } catch (PVP2Exception e) {
- Logger.error(
- "Attribute generation failed! for "
- + reqAttribut.getFriendlyName(), e);
- if (reqAttribut.isRequired()) {
- throw new UnprovideableAttributeException(
- reqAttribut.getName());
}
}
}
-
if (attributeStatement.getAttributes().size() > 0) {
assertion.getAttributeStatements().add(attributeStatement);
}
@@ -294,7 +300,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
SubjectConfirmationData subjectConfirmationData = SAML2Utils
.createSAMLObject(SubjectConfirmationData.class);
subjectConfirmationData.setInResponseTo(authnRequest.getID());
- subjectConfirmationData.setNotOnOrAfter(new DateTime().plusMinutes(20));
+ subjectConfirmationData.setNotOnOrAfter(new DateTime().plusMinutes(5));
//TL: change from entityID to destination URL
AssertionConsumerService consumerService = spSSODescriptor
@@ -319,7 +325,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
audienceRestriction.getAudiences().add(audience);
conditions.setNotBefore(new DateTime());
- conditions.setNotOnOrAfter(new DateTime().plusMinutes(20));
+ conditions.setNotOnOrAfter(new DateTime().plusMinutes(5));
// conditions.setNotOnOrAfter(new DateTime());
conditions.getAudienceRestrictions().add(audienceRestriction);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionEncryptionException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionEncryptionException.java
new file mode 100644
index 000000000..142227a59
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/InvalidAssertionEncryptionException.java
@@ -0,0 +1,14 @@
+package at.gv.egovernment.moa.id.protocols.pvp2x.exceptions;
+
+import org.opensaml.saml2.core.StatusCode;
+
+public class InvalidAssertionEncryptionException extends PVP2Exception {
+
+ private static final long serialVersionUID = 6513388841485355549L;
+
+ public InvalidAssertionEncryptionException() {
+ super("pvp2.16", new Object[]{});
+ this.statusCodeValue = StatusCode.REQUESTER_URI;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java
index fec21df9e..4128a406b 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java
@@ -1,22 +1,48 @@
package at.gv.egovernment.moa.id.protocols.pvp2x.requestHandler;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.TransformerException;
import org.joda.time.DateTime;
+import org.opensaml.Configuration;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.EncryptedAssertion;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.impl.EncryptedAssertionBuilder;
+import org.opensaml.saml2.encryption.Encrypter;
+import org.opensaml.saml2.encryption.Encrypter.KeyPlacement;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.KeyDescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.security.MetadataCredentialResolver;
+import org.opensaml.security.MetadataCriteria;
import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.xml.encryption.EncryptionConstants;
+import org.opensaml.xml.encryption.EncryptionException;
+import org.opensaml.xml.encryption.EncryptionParameters;
+import org.opensaml.xml.encryption.KeyEncryptionParameters;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.security.CriteriaSet;
import org.opensaml.xml.security.SecurityException;
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.credential.UsageType;
+import org.opensaml.xml.security.criteria.EntityIDCriteria;
+import org.opensaml.xml.security.criteria.UsageCriteria;
+import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.signature.KeyInfo;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
@@ -30,6 +56,9 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionB
import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionConsumerServiceException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionEncryptionException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.PrettyPrinter;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.logging.Logger;
@@ -49,10 +78,9 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
EntityDescriptor peerEntity = obj.getEntityMetadata();
Assertion assertion = PVP2AssertionBuilder.buildAssertion(authnRequest, authSession, peerEntity);
-
+
Response authResponse = SAML2Utils.createSAMLObject(Response.class);
-
Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
//TODO: check!
@@ -67,27 +95,94 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
//SAML2 response required IssueInstant
authResponse.setIssueInstant(new DateTime());
- authResponse.getAssertions().add(assertion);
authResponse.setStatus(SAML2Utils.getSuccessStatus());
+ SPSSODescriptor spSSODescriptor = peerEntity
+ .getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+
Integer aIdx = authnRequest.getAssertionConsumerServiceIndex();
int idx = 0;
if (aIdx != null) {
idx = aIdx.intValue();
+
+ } else {
+ idx = SAML2Utils.getDefaultAssertionConsumerServiceIndex(spSSODescriptor);
}
-
- SPSSODescriptor spSSODescriptor = peerEntity
- .getSPSSODescriptor(SAMLConstants.SAML20P_NS);
AssertionConsumerService consumerService = spSSODescriptor
.getAssertionConsumerServices().get(idx);
if (consumerService == null) {
+ //TODO: maybe use default ConsumerService
+
throw new InvalidAssertionConsumerServiceException(idx);
+
}
String oaURL = consumerService.getLocation();
+ //check, if metadata includes an encryption key
+ MetadataCredentialResolver mdCredResolver =
+ new MetadataCredentialResolver(MOAMetadataProvider.getInstance());
+
+ CriteriaSet criteriaSet = new CriteriaSet();
+ criteriaSet.add( new EntityIDCriteria(obj.getSamlRequest().getIssuer().getValue()) );
+ criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) );
+ criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) );
+
+ X509Credential encryptionCredentials = null;
+ try {
+ encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet);
+
+ } catch (SecurityException e2) {
+ Logger.warn("Can not extract the Assertion Encryption-Key from metadata", e2);
+ throw new InvalidAssertionEncryptionException();
+
+ }
+
+ if (encryptionCredentials != null) {
+ //encrypt SAML2 assertion
+
+ try {
+
+ EncryptionParameters dataEncParams = new EncryptionParameters();
+ dataEncParams.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128);
+
+ List<KeyEncryptionParameters> keyEncParamList = new ArrayList<KeyEncryptionParameters>();
+ KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
+
+ keyEncParam.setEncryptionCredential(encryptionCredentials);
+ keyEncParam.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
+ KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration()
+ .getKeyInfoGeneratorManager().getDefaultManager()
+ .getFactory(encryptionCredentials);
+ keyEncParam.setKeyInfoGenerator(kigf.newInstance());
+ keyEncParamList.add(keyEncParam);
+
+ Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
+ //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE);
+ samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
+
+ EncryptedAssertion encryptAssertion = null;
+
+ encryptAssertion = samlEncrypter.encrypt(assertion);
+
+ authResponse.getEncryptedAssertions().add(encryptAssertion);
+
+ } catch (EncryptionException e1) {
+ Logger.warn("Can not encrypt the PVP2 assertion", e1);
+ throw new InvalidAssertionEncryptionException();
+
+ }
+
+ } else {
+ authResponse.getAssertions().add(assertion);
+
+ }
+
+
+
+
IEncoder binding = null;
if (consumerService.getBinding().equals(
@@ -113,6 +208,10 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
binding.encodeRespone(req, resp, authResponse, oaURL);
// TODO add remoteSessionID to AuthSession ExternalPVPSessionStore
+// Logger logger = new Logger();
+// logger.debug("Redirect Binding Request = " + PrettyPrinter.prettyPrint(SAML2Utils.asDOMDocument(authResponse)));
+
+
return assertion.getID();
} catch (MessageEncodingException e) {
@@ -121,6 +220,15 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
} catch (SecurityException e) {
Logger.error("Security exception", e);
throw new MOAIDException("pvp2.01", null, e);
+// } catch (TransformerException e) {
+// Logger.error("Security exception", e);
+// throw new MOAIDException("pvp2.01", null, e);
+// } catch (IOException e) {
+// Logger.error("Security exception", e);
+// throw new MOAIDException("pvp2.01", null, e);
+// } catch (MarshallingException e) {
+// Logger.error("Security exception", e);
+// throw new MOAIDException("pvp2.01", null, e);
}
}
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
index 7bb5b052f..373bca902 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
@@ -2,6 +2,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.utils;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
+import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
@@ -13,6 +14,8 @@ import org.opensaml.Configuration;
import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.Marshaller;
@@ -77,4 +80,17 @@ public class SAML2Utils {
status.setStatusCode(statusCode);
return status;
}
+
+ public static int getDefaultAssertionConsumerServiceIndex(SPSSODescriptor spSSODescriptor) {
+
+ List<AssertionConsumerService> assertionConsumerList = spSSODescriptor.getAssertionConsumerServices();
+
+ for (AssertionConsumerService el : assertionConsumerList) {
+ if (el.isDefault())
+ return el.getIndex();
+
+ }
+
+ return 0;
+ }
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java
index 628da6773..4823d7629 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java
@@ -41,6 +41,7 @@ public class SAMLVerificationEngine {
public void verifyRequest(RequestAbstractType samlObj, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception {
SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
+
try {
profileValidator.validate(samlObj.getSignature());
} catch (ValidationException e) {
diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
index afe14daee..7e8f679b4 100644
--- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
+++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties
@@ -218,4 +218,5 @@ pvp2.11=Binding {0} wird nicht unterstuetzt
pvp2.12=NameID Format {0} wird nicht unterstuetzt
pvp2.13=Interner Server Fehler
pvp2.14=SAML Anfrage verweigert
-pvp2.15=Keine Metadateninformation gefunden
+pvp2.15=Keine Metadateninformation gefunden
+pvp2.16=Fehler beim verschl\u00FCsseln der PVP2 Assertion