//: "The contents of this file are subject to the Mozilla Public License //: Version 1.1 (the "License"); you may not use this file except in //: compliance with the License. You may obtain a copy of the License at //: http://www.mozilla.org/MPL/ //: //: Software distributed under the License is distributed on an "AS IS" //: basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the //: License for the specific language governing rights and limitations //: under the License. //: //: The Original Code is Guanxi (http://www.guanxi.uhi.ac.uk). //: //: The Initial Developer of the Original Code is Alistair Young alistair@codebrane.com //: All Rights Reserved. //: package org.guanxi.common.trust.impl; import org.guanxi.common.metadata.Metadata; import org.guanxi.common.GuanxiException; import org.guanxi.common.trust.TrustUtils; import org.guanxi.xal.saml_2_0.metadata.EntityDescriptorType; import org.guanxi.xal.saml_1_0.protocol.ResponseDocument; import org.apache.xml.security.Init; import org.apache.log4j.Logger; import java.security.cert.X509Certificate; /** * TrustEngine implementation that implements the rules of a Shibboleth federation such * as the UK Access Management Federation. * * @author alistair */ public class ShibbolethTrustEngineImpl extends SimpleTrustEngine { /** Our logger */ private static final Logger logger = Logger.getLogger(ShibbolethTrustEngineImpl.class.getName()); public ShibbolethTrustEngineImpl() { super(); // Initialise the Apache security engine Init.init(); } /** @see org.guanxi.common.trust.TrustEngine#trustEntity(org.guanxi.common.metadata.Metadata, Object) * @link http://www.guanxi.uhi.ac.uk/index.php/Metadata_and_trust_in_the_UK_Access_Management_Federation * */ public boolean trustEntity(Metadata entityMetadata, Object entityData) throws GuanxiException { // Handler private data is raw SAML2 metadata EntityDescriptorType saml2Metadata = (EntityDescriptorType)entityMetadata.getPrivateData(); // Message level validation if (entityData instanceof ResponseDocument) { // Entity data is the SAML Response from the IdP ResponseDocument samlResponse = (ResponseDocument)entityData; // First thing is check to see if the signature verifies if (!TrustUtils.verifySignature(samlResponse)) { logger.error("IdP signature failed validation"); return false; } // Validation via embedded certificates X509Certificate x509CertFromSig = TrustUtils.getX509CertFromSignature(samlResponse); if (TrustUtils.validateEmbeddedCert(saml2Metadata, new X509Certificate[] {x509CertFromSig}, TrustUtils.ENTITY_TYPE_SSO)) { return true; } // Validation via PKIX if (TrustUtils.validatePKIX((ResponseDocument)entityData, saml2Metadata, caCerts, entityMetadata.getHostName())) { return true; } } // Back channel connection validation if (entityData instanceof X509Certificate) { // Entity data is the X509 from the connection X509Certificate x509CertFromConnection = (X509Certificate)entityData; /* SAML2 Web Browser SSO metadata may not have an AttributeAuthorityDescriptor. * In this case the cert will be in the IdPSSODescriptor. */ int entityType; if (saml2Metadata.getAuthnAuthorityDescriptorArray().length > 0) { entityType = TrustUtils.ENTITY_TYPE_AA; } else { entityType = TrustUtils.ENTITY_TYPE_SSO; } if (!TrustUtils.validateEmbeddedCert(saml2Metadata, new X509Certificate[] {x509CertFromConnection}, entityType)) { return TrustUtils.validatePKIXBC(x509CertFromConnection, saml2Metadata, caCerts, entityMetadata.getHostName()); } return true; } return false; } }