diff options
Diffstat (limited to 'id/server/idserverlib/src')
9 files changed, 157 insertions, 38 deletions
| diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java index e54bba10d..c149d1ce1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationSessionStore.java @@ -5,7 +5,6 @@ import java.util.Iterator;  import java.util.Set;  import at.gv.egovernment.moa.id.AuthenticationException; -import at.gv.egovernment.moa.id.MOAIDException;  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;  import at.gv.egovernment.moa.id.util.Random;  import at.gv.egovernment.moa.logging.Logger; 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 5ea596eeb..33c8af197 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 @@ -18,6 +18,9 @@ import org.opensaml.saml2.core.Status;  import org.opensaml.saml2.core.StatusCode;  import org.opensaml.saml2.core.StatusMessage;  import org.opensaml.saml2.core.StatusResponseType; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor;  import at.gv.egovernment.moa.id.MOAIDException;  import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; @@ -35,10 +38,8 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding;  import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;  import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;  import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; -import at.gv.egovernment.moa.id.protocols.pvp2x.validation.ChainSAMLValidator; -import at.gv.egovernment.moa.id.protocols.pvp2x.validation.SAMLSignatureValidator; -import at.gv.egovernment.moa.id.protocols.pvp2x.verification.ChainSAMLVerifier; -import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerifierMOASP; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;  import at.gv.egovernment.moa.id.util.ParamValidatorUtils;  public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants { @@ -57,10 +58,6 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  	private static HashMap<String, IAction> actions = new HashMap<String, IAction>(); -	private ChainSAMLVerifier samlVerifier = new ChainSAMLVerifier(); -	 -	private ChainSAMLValidator samlValidator = new ChainSAMLValidator(); -	  	static {  		servletList.add(new ServletInfo(PVPProcessor.class, REDIRECT,  				ServletType.AUTH)); @@ -98,11 +95,11 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  		return PATH;  	} -	private IDecoder findDecoder(String action) { +	private IDecoder findDecoder(String action, HttpServletRequest req) {  		Iterator<IDecoder> decoderIT = decoder.iterator();  		while (decoderIT.hasNext()) {  			IDecoder decoder = decoderIT.next(); -			if (decoder.handleDecode(action)) { +			if (decoder.handleDecode(action,  req)) {  				return decoder;  			}  		} @@ -112,10 +109,6 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  	public PVP2XProtocol() {  		super(); -		 -		samlVerifier.addVerifier(new SAMLVerifierMOASP()); -		 -		samlValidator.addValidator(new SAMLSignatureValidator());  	}  	public IRequest preProcess(HttpServletRequest request, @@ -125,7 +118,7 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  			return new PVPTargetConfiguration();  		} -		IDecoder decoder = findDecoder(action); +		IDecoder decoder = findDecoder(action, request);  		if (decoder == null) {  			return null;  		} @@ -140,12 +133,12 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  			//Logger.info("SAML : " + xml); -			// TODO: verify samlReq -			//samlValidator.validateRequest(samlReq); -			 -			// TODO: validate samlReq for  -			//samlVerifier.verifyRequest(samlReq); -			 +			if(!moaRequest.isVerified()) { +				// TODO: verify samlReq +				SAMLVerificationEngine engine = new SAMLVerificationEngine(); +				engine.verifyRequest(samlReq, TrustEngineFactory.getSignatureKnownKeysTrustEngine()); +				moaRequest.setVerified(true); +			}  			// TODO: OAURL is AssertionConsumerService URL from entitydescriptor ...  			if(!(samlReq instanceof AuthnRequest)) { @@ -161,9 +154,10 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  				idx = aIdx.intValue();  			} -			String oaURL = moaRequest.getEntityMetadata(). -					getSPSSODescriptor(SAMLConstants.SAML20P_NS). -					getAssertionConsumerServices().get(idx).getLocation(); +			EntityDescriptor metadata = moaRequest.getEntityMetadata();  +			SPSSODescriptor spSSODescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS); +			AssertionConsumerService consumerService  = spSSODescriptor.getAssertionConsumerServices().get(idx); +			String oaURL = consumerService.getLocation();  			String entityID = moaRequest.getEntityMetadata().getEntityID(); @@ -221,9 +215,11 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {  	public IAction canHandleRequest(HttpServletRequest request,  			HttpServletResponse response) { -		if(request.getParameter("SAMLRequest") != null) { +		if(request.getParameter("SAMLRequest") != null && request.getMethod().equals("GET")) {  			return getAction(REDIRECT); -		} +		} else if(request.getParameter("SAMLRequest") != null && request.getMethod().equals("POST")) { +			return getAction(POST); +		}   		if(METADATA.equals(request.getParameter("action"))) {  			return getAction(METADATA); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/ArtifactBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/ArtifactBinding.java index 8f83812a6..a8c3dab48 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/ArtifactBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/ArtifactBinding.java @@ -97,7 +97,7 @@ public class ArtifactBinding implements IDecoder, IEncoder {  		return null;  	} -	public boolean handleDecode(String action) { +	public boolean handleDecode(String action, HttpServletRequest req) {  		// TODO Auto-generated method stub  		return false;  	} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java index 2778016ba..531ec0756 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java @@ -15,5 +15,5 @@ public interface IDecoder {  			HttpServletResponse resp)  					throws MessageDecodingException, SecurityException; -	public boolean handleDecode(String action); +	public boolean handleDecode(String action, HttpServletRequest req);  } 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 c7d779fa2..1b55d4b2e 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 @@ -9,13 +9,19 @@ import org.opensaml.common.SAMLObject;  import org.opensaml.common.binding.BasicSAMLMessageContext;  import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;  import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; +import org.opensaml.saml2.binding.security.SAML2HTTPRedirectDeflateSignatureRule;  import org.opensaml.saml2.core.RequestAbstractType;  import org.opensaml.saml2.core.Response;  import org.opensaml.saml2.core.StatusResponseType; +import org.opensaml.saml2.metadata.SPSSODescriptor;  import org.opensaml.saml2.metadata.SingleSignOnService;  import org.opensaml.saml2.metadata.impl.SingleSignOnServiceBuilder; +import org.opensaml.saml2.metadata.provider.MetadataProviderException;  import org.opensaml.ws.message.decoder.MessageDecodingException;  import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.security.SecurityPolicyResolver; +import org.opensaml.ws.security.provider.BasicSecurityPolicy; +import org.opensaml.ws.security.provider.StaticSecurityPolicyResolver;  import org.opensaml.ws.transport.http.HttpServletRequestAdapter;  import org.opensaml.ws.transport.http.HttpServletResponseAdapter;  import org.opensaml.xml.parse.BasicParserPool; @@ -24,8 +30,10 @@ import org.opensaml.xml.security.credential.Credential;  import org.opensaml.xml.signature.Signature;  import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; +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;  public class PostBinding implements IDecoder, IEncoder { @@ -86,13 +94,36 @@ public class PostBinding implements IDecoder, IEncoder {  		BasicSAMLMessageContext<RequestAbstractType, ?, ?> messageContext = new BasicSAMLMessageContext<RequestAbstractType, SAMLObject, SAMLObject>();  		messageContext  				.setInboundMessageTransport(new HttpServletRequestAdapter(req)); + +		// TODO: used to verify signature! +		SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( +				TrustEngineFactory.getSignatureKnownKeysTrustEngine()); + +		// signatureRule.evaluate(messageContext); +		BasicSecurityPolicy policy = new BasicSecurityPolicy(); +		policy.getPolicyRules().add(signatureRule); +		SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( +				policy); +		messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); +		messageContext.setSecurityPolicyResolver(resolver); +		 +		MOAMetadataProvider provider = null; +		try { +			provider = new MOAMetadataProvider(); +		} catch (MetadataProviderException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} +		messageContext.setMetadataProvider(provider); +		  		decode.decode(messageContext);  		RequestAbstractType inboundMessage = (RequestAbstractType) messageContext  				.getInboundMessage(); - +		  		MOARequest request = new MOARequest(inboundMessage); - +		request.setVerified(false); +		request.setEntityMetadata(messageContext.getPeerEntityMetadata());  		return request;  	} @@ -105,16 +136,31 @@ public class PostBinding implements IDecoder, IEncoder {  		BasicSAMLMessageContext<Response, ?, ?> messageContext = new BasicSAMLMessageContext<Response, SAMLObject, SAMLObject>();  		messageContext  				.setInboundMessageTransport(new HttpServletRequestAdapter(req)); +		 +		// TODO: used to verify signature! +		SAML2HTTPRedirectDeflateSignatureRule signatureRule = new SAML2HTTPRedirectDeflateSignatureRule( +				TrustEngineFactory.getSignatureKnownKeysTrustEngine()); + +		// signatureRule.evaluate(messageContext); +		BasicSecurityPolicy policy = new BasicSecurityPolicy(); +		policy.getPolicyRules().add(signatureRule); +		SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( +				policy); +		messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME); +		messageContext.setSecurityPolicyResolver(resolver); +		  		decode.decode(messageContext);  		Response inboundMessage = (Response) messageContext.getInboundMessage(); - +		  		MOAResponse moaResponse = new MOAResponse(inboundMessage); +		moaResponse.setVerified(false); +		moaResponse.setEntityMetadata(messageContext.getPeerEntityMetadata());  		return moaResponse;  	} -	public boolean handleDecode(String action) { -		return (action.equals(PVP2XProtocol.POST)); +	public boolean handleDecode(String action, HttpServletRequest req) { +		return (req.getMethod().equals("POST"));  	}  } 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 92a6b6002..a4670d3fc 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 @@ -99,6 +99,7 @@ public class RedirectBinding implements IDecoder, IEncoder {  				policy);  		messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);  		messageContext.setSecurityPolicyResolver(resolver); +		  		decode.decode(messageContext);  		signatureRule.evaluate(messageContext); @@ -132,6 +133,14 @@ public class RedirectBinding implements IDecoder, IEncoder {  				policy);  		messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);  		messageContext.setSecurityPolicyResolver(resolver); +		MOAMetadataProvider provider = null; +		try { +			provider = new MOAMetadataProvider(); +		} catch (MetadataProviderException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} +		messageContext.setMetadataProvider(provider);  		decode.decode(messageContext); @@ -143,7 +152,7 @@ public class RedirectBinding implements IDecoder, IEncoder {  		return moaResponse;  	} -	public boolean handleDecode(String action) { -		return (action.equals(PVP2XProtocol.REDIRECT)); +	public boolean handleDecode(String action, HttpServletRequest req) { +		return (action.equals(PVP2XProtocol.REDIRECT) && req.getMethod().equals("GET"));  	}  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java index 027dab15a..558f19b4f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java @@ -56,7 +56,7 @@ public class SoapBinding implements IDecoder, IEncoder {  		return moaResponse;  	} -	public boolean handleDecode(String action) { +	public boolean handleDecode(String action, HttpServletRequest req) {  		return (action.equals(PVP2XProtocol.SOAP));  	} 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 new file mode 100644 index 000000000..8df418f9a --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java @@ -0,0 +1,67 @@ +package at.gv.egovernment.moa.id.protocols.pvp2x.verification; + +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.RequestAbstractType; +import org.opensaml.saml2.core.Response; +import org.opensaml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml2.metadata.SPSSODescriptor; +import org.opensaml.security.MetadataCriteria; +import org.opensaml.security.SAMLSignatureProfileValidator; +import org.opensaml.xml.security.CriteriaSet; +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.signature.SignatureTrustEngine; +import org.opensaml.xml.validation.ValidationException; + +public class SAMLVerificationEngine { + +	public void verifyResponse(Response samlObj, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception { +		SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator(); +		try { +		    profileValidator.validate(samlObj.getSignature()); +		} catch (ValidationException e) { +		    // Indicates signature did not conform to SAML Signature profile +		    e.printStackTrace(); +		} + +		CriteriaSet criteriaSet = new CriteriaSet(); +		criteriaSet.add( new EntityIDCriteria(samlObj.getIssuer().getValue()) ); +		criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); +		criteriaSet.add( new UsageCriteria(UsageType.SIGNING) ); + +		try { +		    if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) { +		        throw new Exception("Signature was either invalid or signing key could not be established as trusted"); +		    } +		} catch (SecurityException e) { +		    // Indicates processing error evaluating the signature +		    e.printStackTrace(); +		} +	} +	 +	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) { +		    // Indicates signature did not conform to SAML Signature profile +		    e.printStackTrace(); +		} + +		CriteriaSet criteriaSet = new CriteriaSet(); +		criteriaSet.add( new EntityIDCriteria(samlObj.getIssuer().getValue()) ); +		criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); +		criteriaSet.add( new UsageCriteria(UsageType.SIGNING) ); + +		try { +		    if (!sigTrustEngine.validate(samlObj.getSignature(), criteriaSet)) { +		        throw new Exception("Signature was either invalid or signing key could not be established as trusted"); +		    } +		} catch (SecurityException e) { +		    // Indicates processing error evaluating the signature +		    e.printStackTrace(); +		} +	} +	 +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerifierMOASP.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerifierMOASP.java index 37289a8e3..6dbaae0a1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerifierMOASP.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerifierMOASP.java @@ -20,6 +20,8 @@ import eu.stork.vidp.messages.util.XMLUtil;  public class SAMLVerifierMOASP implements ISAMLVerifier { +	 +	//TODO: implement via metadata validator ....  	public void verifyRequest(RequestAbstractType request)  			throws MOAIDException {  		// validate Signature @@ -79,7 +81,7 @@ public class SAMLVerifierMOASP implements ISAMLVerifier {  				Logger.debug("Signing certificate of SAML response succesfully verified");  			} else { -				String msg = "SAML Response is not signed."; +				String msg = "SAML Object is not signed.";  				throw new SecurityException(msg);  			} | 
