Inline CRLs in the metadata are now honored during pkix validation. Junit tests...
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Fri, 8 Apr 2005 04:29:49 +0000 (04:29 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Fri, 8 Apr 2005 04:29:49 +0000 (04:29 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@1389 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

data/metadata7.xml [new file with mode: 0644]
data/metadata8.xml [new file with mode: 0644]
data/trusttest.jks
src/edu/internet2/middleware/shibboleth/common/provider/ShibbolethTrust.java
tests/edu/internet2/middleware/shibboleth/common/TrustTests.java

diff --git a/data/metadata7.xml b/data/metadata7.xml
new file mode 100644 (file)
index 0000000..df5f4ed
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata ../schemas/sstc-saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 ../schemas/shibboleth-metadata-1.0.xsd" 
+       Name="urn-x:testFed1" validUntil="3010-01-01T00:00:00Z">
+       <EntityDescriptor entityID="urn-x:testSP1">
+                <Extensions>
+                       <KeyAuthority xmlns="urn:mace:shibboleth:metadata:1.0">
+                               <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+           <ds:X509Data>
+                <ds:X509Certificate>MIIC4zCCAkygAwIBAgIBADANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJVUzEL
+MAkGA1UECBMCVE4xEDAOBgNVBAcTB01lbXBoaXMxEjAQBgNVBAoTCVdhc3NhLk9y
+RzEZMBcGA1UEAxMQV2FsdGVyJ3MgVGVzdCBDQTAeFw0wNTA0MDgwMzU1MzdaFw0w
+NjA0MDgwMzU1MzdaMFsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQMA4GA1UE
+BxMHTWVtcGhpczESMBAGA1UEChMJV2Fzc2EuT3JHMRkwFwYDVQQDExBXYWx0ZXIn
+cyBUZXN0IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi0Lwb7bURmrS1
+cpMuBAfYhAqd5jbnIOzJ9U8TfM0e6eTnPZMrWw3fhtbTu//RY2yMwGi4bEJqtkWo
+IsOPK3Zu8iawHXdmJx6jYigWOHljQKQDDo2YQGwHiEmsfyeZLLcDLmb9mAZV1MEP
+Qo+gv13T3DPJI/lt2xNhbUulHr+XGwIDAQABo4G2MIGzMB0GA1UdDgQWBBRwbYDU
+/IGFzPTOpQlqjhTQHPnQITCBgwYDVR0jBHwweoAUcG2A1PyBhcz0zqUJao4U0Bz5
+0CGhX6RdMFsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQMA4GA1UEBxMHTWVt
+cGhpczESMBAGA1UEChMJV2Fzc2EuT3JHMRkwFwYDVQQDExBXYWx0ZXIncyBUZXN0
+IENBggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAG3yK1mpA8gq+
+RTSBS7HfW7Y7x7D0kSbQHBW6WXXrSEcTJ3lbph3MjMjJZw0+p4xiIG/k4ErAKjIY
+6w4NWRNEFsSdoxnBhest6RZFEA+VN9/YafqucvG0DAnOD6yGFbXOcMPG3LYK+vOe
+HOaSn5DIb/jt04vkJnXrZ6GrHiMGxxM=
+</ds:X509Certificate>
+                       <ds:X509CRL>MIIBNjCBoDANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
+VE4xEDAOBgNVBAcTB01lbXBoaXMxEjAQBgNVBAoTCVdhc3NhLk9yRzEZMBcGA1UE
+AxMQV2FsdGVyJ3MgVGVzdCBDQRcNMDUwNDA4MDQwMTU2WhcNMDUwNTA4MDQwMTU2
+WjAUMBICAQEXDTA1MDQwODA0MDA1MVowDQYJKoZIhvcNAQEEBQADgYEAETadhKU8
+nrxii0wwkbdfBZ5lmlBu0z9wqobPCH/oSlkMZ9FlE/LmADEclR2hqOgczMRz/BwL
+kghUXSJe4yuXl2gvGrTd/Mn36HQ/rvr6dbgLzpuNWHRAW99o4Wpf5o+Hi9iEyF2J
+/50cy2EUSe6YtzA8pGXzSP67YC/3U0D8U4A=
+</ds:X509CRL>
+            </ds:X509Data>
+                               </ds:KeyInfo>
+                       </KeyAuthority>
+               </Extensions>
+               <SPSSODescriptor 
+                       protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+                       <KeyDescriptor>
+                               <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+                                       <ds:KeyName>foo.wassa.org</ds:KeyName>
+                               </ds:KeyInfo>
+                       </KeyDescriptor>
+                       <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+                       <AssertionConsumerService index="1" 
+                               Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" 
+                               Location="https://www.example.org/Shibboleth.shire"/>
+               </SPSSODescriptor>
+               
+       </EntityDescriptor>
+</EntitiesDescriptor>
\ No newline at end of file
diff --git a/data/metadata8.xml b/data/metadata8.xml
new file mode 100644 (file)
index 0000000..2a7d5f2
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" 
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata ../schemas/sstc-saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 ../schemas/shibboleth-metadata-1.0.xsd" 
+       Name="urn-x:testFed1" validUntil="3010-01-01T00:00:00Z">
+       <EntityDescriptor entityID="urn-x:testSP1">
+                <Extensions>
+                       <KeyAuthority xmlns="urn:mace:shibboleth:metadata:1.0">
+                               <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+           <ds:X509Data>
+                <ds:X509Certificate>MIIC4zCCAkygAwIBAgIBADANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJVUzEL
+MAkGA1UECBMCVE4xEDAOBgNVBAcTB01lbXBoaXMxEjAQBgNVBAoTCVdhc3NhLk9y
+RzEZMBcGA1UEAxMQV2FsdGVyJ3MgVGVzdCBDQTAeFw0wNTA0MDgwMzU1MzdaFw0w
+NjA0MDgwMzU1MzdaMFsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQMA4GA1UE
+BxMHTWVtcGhpczESMBAGA1UEChMJV2Fzc2EuT3JHMRkwFwYDVQQDExBXYWx0ZXIn
+cyBUZXN0IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi0Lwb7bURmrS1
+cpMuBAfYhAqd5jbnIOzJ9U8TfM0e6eTnPZMrWw3fhtbTu//RY2yMwGi4bEJqtkWo
+IsOPK3Zu8iawHXdmJx6jYigWOHljQKQDDo2YQGwHiEmsfyeZLLcDLmb9mAZV1MEP
+Qo+gv13T3DPJI/lt2xNhbUulHr+XGwIDAQABo4G2MIGzMB0GA1UdDgQWBBRwbYDU
+/IGFzPTOpQlqjhTQHPnQITCBgwYDVR0jBHwweoAUcG2A1PyBhcz0zqUJao4U0Bz5
+0CGhX6RdMFsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQMA4GA1UEBxMHTWVt
+cGhpczESMBAGA1UEChMJV2Fzc2EuT3JHMRkwFwYDVQQDExBXYWx0ZXIncyBUZXN0
+IENBggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAG3yK1mpA8gq+
+RTSBS7HfW7Y7x7D0kSbQHBW6WXXrSEcTJ3lbph3MjMjJZw0+p4xiIG/k4ErAKjIY
+6w4NWRNEFsSdoxnBhest6RZFEA+VN9/YafqucvG0DAnOD6yGFbXOcMPG3LYK+vOe
+HOaSn5DIb/jt04vkJnXrZ6GrHiMGxxM=
+</ds:X509Certificate>
+                       <ds:X509CRL>MIIBIDCBijANBgkqhkiG9w0BAQQFADBbMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
+VE4xEDAOBgNVBAcTB01lbXBoaXMxEjAQBgNVBAoTCVdhc3NhLk9yRzEZMBcGA1UE
+AxMQV2FsdGVyJ3MgVGVzdCBDQRcNMDUwNDA4MDM1OTQyWhcNMDUwNTA4MDM1OTQy
+WjANBgkqhkiG9w0BAQQFAAOBgQA3L1aOQcPxgio9N7IUdPTu3jyAOV0HfMfWiifc
+3lF/WVq4n655AV61Av5NE41LiSdDqET9wnovmP8Pdbd2DnqvH0wOr3/faALrkZb9
+dE8xlTPidelZLTyhBXauu3ufTgxRYG2rPQ7wkkpos+g8qk9eL9FTfw7amLc5j0mO
+OVVK8w==
+</ds:X509CRL>
+            </ds:X509Data>
+                               </ds:KeyInfo>
+                       </KeyAuthority>
+               </Extensions>
+               <SPSSODescriptor 
+                       protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+                       <KeyDescriptor>
+                               <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+                                       <ds:KeyName>foo.wassa.org</ds:KeyName>
+                               </ds:KeyInfo>
+                       </KeyDescriptor>
+                       <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+                       <AssertionConsumerService index="1" 
+                               Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" 
+                               Location="https://www.example.org/Shibboleth.shire"/>
+               </SPSSODescriptor>
+               
+       </EntityDescriptor>
+</EntitiesDescriptor>
\ No newline at end of file
index ec06b00..b141e92 100644 (file)
Binary files a/data/trusttest.jks and b/data/trusttest.jks differ
index 433b1b8..67d3216 100644 (file)
 
 package edu.internet2.middleware.shibboleth.common.provider;
 
+import java.io.ByteArrayInputStream;
 import java.security.GeneralSecurityException;
 import java.security.cert.CertPathBuilder;
 import java.security.cert.CertPathValidator;
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertStore;
+import java.security.cert.CertificateFactory;
 import java.security.cert.CertificateParsingException;
 import java.security.cert.CollectionCertStoreParameters;
 import java.security.cert.PKIXBuilderParameters;
@@ -55,6 +57,7 @@ import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.keys.KeyInfo;
 import org.apache.xml.security.keys.content.KeyName;
 import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.x509.XMLX509CRL;
 import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
 
 import edu.internet2.middleware.shibboleth.common.Trust;
@@ -171,11 +174,13 @@ public class ShibbolethTrust extends BasicTrust implements Trust {
        private boolean pkixValidate(X509Certificate[] certChain, KeyAuthority authority) {
 
                Set anchors = new HashSet();
+               Set crls = new HashSet();
                Iterator keyInfos = authority.getKeyInfos();
                while (keyInfos.hasNext()) {
                        KeyInfo keyInfo = (KeyInfo) keyInfos.next();
                        if (keyInfo.containsX509Data()) {
                                try {
+                                       //Add all certificates in the authority as trust anchors
                                        for (int i = 0; i < keyInfo.lengthX509Data(); i++) {
                                                X509Data data = keyInfo.itemX509Data(i);
                                                if (data.containsCertificate()) {
@@ -184,7 +189,20 @@ public class ShibbolethTrust extends BasicTrust implements Trust {
                                                                anchors.add(new TrustAnchor(xmlCert.getX509Certificate(), null));
                                                        }
                                                }
+                                               // Compile all CRLs in the authority
+                                               if (data.containsCRL()) {
+                                                       for (int j = 0; j < data.lengthCRL(); j++) {
+                                                               XMLX509CRL xmlCrl = data.itemCRL(j);
+                                                               try {
+                                                                       crls.add(CertificateFactory.getInstance("X.509").generateCRL(
+                                                                                       new ByteArrayInputStream(xmlCrl.getCRLBytes())));
+                                                               } catch (GeneralSecurityException e) {
+                                                                       log.error("Encountered an error parsing CRL from shibboleth metadata: " + e);
+                                                               }
+                                                       }
+                                               }
                                        }
+
                                } catch (XMLSecurityException e) {
                                        log.error("Encountered an error constructing trust list from shibboleth metadata: " + e);
                                }
@@ -201,13 +219,17 @@ public class ShibbolethTrust extends BasicTrust implements Trust {
                                selector.setCertificate(certChain[0]);
                                PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, selector);
                                params.setMaxPathLength(authority.getVerifyDepth());
-                               CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Arrays
-                                               .asList(certChain)));
+                               List storeMaterial = new ArrayList(crls);
+                               storeMaterial.addAll(Arrays.asList(certChain));
+                               CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(storeMaterial));
                                List stores = new ArrayList();
                                stores.add(store);
                                params.setCertStores(stores);
-                               //TODO hmm... what about revocation
-                               params.setRevocationEnabled(false);
+                               if (crls.size() > 0) {
+                                       params.setRevocationEnabled(true);
+                               } else {
+                                       params.setRevocationEnabled(false);
+                               }
 
                                CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
                                PKIXCertPathBuilderResult buildResult = (PKIXCertPathBuilderResult) builder.build(params);
index 6c50a40..786b930 100644 (file)
@@ -341,4 +341,78 @@ public class TrustTests extends TestCase {
                        fail("Error in test specification: " + e);
                }
        }
+
+       public void testCRL() {
+
+               try {
+                       // Pull the role descriptor from example metadata
+                       Metadata metadata = new XMLMetadata(new File("data/metadata7.xml").toURL().toString());
+                       EntityDescriptor entity = metadata.lookup("urn-x:testSP1");
+                       SPSSODescriptor role = (SPSSODescriptor) entity.getRoleByType(SPSSODescriptor.class,
+                                       "urn:oasis:names:tc:SAML:1.1:protocol");
+
+                       // Use a pre-defined cert
+                       KeyStore keyStore = KeyStore.getInstance("JKS");
+                       keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
+                                       new char[]{'t', 'e', 's', 't', '1', '2', '3'});
+                       X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline4");
+
+                       // Try to validate against the metadata
+                       Trust validator = new ShibbolethTrust();
+                       boolean successful = validator.validate(role, new X509Certificate[]{cert}, KeyDescriptor.ENCRYPTION);
+                       if (successful) {
+                               fail("Validation should not have succeeded.");
+                       }
+
+               } catch (MetadataException e) {
+                       fail("Error in test specification: " + e);
+               } catch (ResourceNotAvailableException e) {
+                       fail("Error in test specification: " + e);
+               } catch (IOException e) {
+                       fail("Error in test specification: " + e);
+               } catch (NoSuchAlgorithmException e) {
+                       fail("Error in test specification: " + e);
+               } catch (CertificateException e) {
+                       fail("Error in test specification: " + e);
+               } catch (KeyStoreException e) {
+                       fail("Error in test specification: " + e);
+               }
+       }
+
+       public void testCRLDoesntBreakValid() {
+
+               try {
+                       // Pull the role descriptor from example metadata
+                       Metadata metadata = new XMLMetadata(new File("data/metadata8.xml").toURL().toString());
+                       EntityDescriptor entity = metadata.lookup("urn-x:testSP1");
+                       SPSSODescriptor role = (SPSSODescriptor) entity.getRoleByType(SPSSODescriptor.class,
+                                       "urn:oasis:names:tc:SAML:1.1:protocol");
+
+                       // Use a pre-defined cert
+                       KeyStore keyStore = KeyStore.getInstance("JKS");
+                       keyStore.load(new ShibResource(new File("data/trusttest.jks").toURL().toString()).getInputStream(),
+                                       new char[]{'t', 'e', 's', 't', '1', '2', '3'});
+                       X509Certificate cert = (X509Certificate) keyStore.getCertificate("inline4");
+
+                       // Try to validate against the metadata
+                       Trust validator = new ShibbolethTrust();
+                       boolean successful = validator.validate(role, new X509Certificate[]{cert}, KeyDescriptor.ENCRYPTION);
+                       if (!successful) {
+                               fail("Validation should have succeeded.");
+                       }
+
+               } catch (MetadataException e) {
+                       fail("Error in test specification: " + e);
+               } catch (ResourceNotAvailableException e) {
+                       fail("Error in test specification: " + e);
+               } catch (IOException e) {
+                       fail("Error in test specification: " + e);
+               } catch (NoSuchAlgorithmException e) {
+                       fail("Error in test specification: " + e);
+               } catch (CertificateException e) {
+                       fail("Error in test specification: " + e);
+               } catch (KeyStoreException e) {
+                       fail("Error in test specification: " + e);
+               }
+       }
 }
\ No newline at end of file