/*
* Copyright 1999-2010 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/
package org.globus.gsi.proxy;
import org.globus.common.CoGProperties;
import org.globus.gsi.util.CertificateLoadUtil;
import org.globus.gsi.trustmanager.CRLChecker;
import org.globus.gsi.trustmanager.CertificateChecker;
import org.globus.gsi.trustmanager.DateValidityChecker;
import org.globus.gsi.trustmanager.IdentityChecker;
import org.globus.gsi.trustmanager.SigningPolicyChecker;
import org.globus.gsi.trustmanager.UnsupportedCriticalExtensionChecker;
import org.globus.gsi.trustmanager.X509ProxyCertPathValidator;
import org.globus.gsi.X509Credential;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPath;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.security.cert.X509Certificate;
import java.security.cert.X509CRL;
import org.globus.gsi.GSIConstants;
import org.globus.gsi.TrustedCertificates;
import org.globus.gsi.SigningPolicy;
import org.globus.gsi.SigningPolicyParser;
import org.globus.gsi.CertificateRevocationLists;
import org.globus.gsi.proxy.ProxyPolicyHandler;
import org.globus.gsi.proxy.ProxyPathValidator;
import org.globus.gsi.proxy.ProxyPathValidatorException;
import org.globus.gsi.proxy.ext.ProxyCertInfo;
import org.globus.gsi.proxy.ext.ProxyPolicy;
import junit.framework.TestCase;
public class ProxyPathValidatorTest extends TestCase {
private static Log log = LogFactory.getLog(ProxyPathValidatorTest.class);
public static final String BASE = "validatorTest/";
public static String[] crlNames = { "ca2crl.r0", "testca3.r0" };
public static String[][] certs = {
{GSIConstants.CertificateType.CA.name(), "TestCA1.pem"},
{GSIConstants.CertificateType.EEC.name(), "eecFromTestCA1.pem"},
{GSIConstants.CertificateType.GSI_2_PROXY.name(), "gsi2fullproxy.pem"},
{GSIConstants.CertificateType.GSI_2_LIMITED_PROXY.name(), "gsi2limitedproxy.pem"},
// 4, double GSIConstants.CertificateType.GSI_2_LIMITED_PROXY), gsi2limited2xproxy.pem (issued by
// 3)
{GSIConstants.CertificateType.GSI_2_LIMITED_PROXY.name(), "gsi2limited2xproxy.pem"},
// 5, GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY), gsi3impersonationproxy.pem
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3impersonationproxy.pem"},
// 6, GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY), gsi3independentproxy.pem
{GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY.name(), "gsi3independentproxy.pem"},
// 7, GSIConstants.CertificateType.GSI_3_LIMITED_PROXY), gsi3limitedproxy.pem
{GSIConstants.CertificateType.GSI_3_LIMITED_PROXY.name(), "gsi3limitedproxy.pem"},
// 8, GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY), gsi3restrictedproxy.pem
{GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY.name(), "gsi3restrictedproxy.pem"},
// double
// 9, GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY), gsi3impersonation2xproxy.pem
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3impersonation2xproxy.pem"},
// 10, GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY), gsi3independent2xproxy.pem
{GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY.name(), "gsi3independent2xproxy.pem"},
// pathLen = 0
// 11, GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY), gsi3impersonationp0proxy.pem
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3impersonationp0proxy.pem"},
// pathLen = 1
// 12, GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY), gsi2independentp1proxy.pem
{GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY.name(), "gsi3independentp1proxy.pem"},
// pathLen = 2
// 13, GSIConstants.CertificateType.CA),
{GSIConstants.CertificateType.CA.name(), "testca.pem"},
// 14, GSIConstants.CertificateType.EEC)
{GSIConstants.CertificateType.EEC.name(), "testeec1.pem"},
// 15, GSIConstants.CertificateType.EEC)
{GSIConstants.CertificateType.EEC.name(), "testeec2.pem"},
// pathLen = 1
// 16, GSIConstants.CertificateType.CA)
{GSIConstants.CertificateType.CA.name(), "testca2.pem"}, // crl for this, 16
// 17, GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY),
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "testgsi3proxy.pem"},
// for CRL test
// 18, GSIConstants.CertificateType.CA),
{GSIConstants.CertificateType.CA.name(), "testca3.pem"},
// 19, GSIConstants.CertificateType.EEC),
{GSIConstants.CertificateType.EEC.name(), "crl_usercert.pem"},
// 20, GSIConstants.CertificateType.GSI_2_PROXY),
{GSIConstants.CertificateType.GSI_2_PROXY.name(), "crl_proxy.pem"},
// 21 (all good)
// GSIConstants.CertificateType.CA)
{GSIConstants.CertificateType.CA.name(), "ca1cert.pem"},
// 22, GSIConstants.CertificateType.EEC
{GSIConstants.CertificateType.EEC.name(), "user1ca1.pem"},
// 23, GSIConstants.CertificateType.EEC)
{GSIConstants.CertificateType.EEC.name(), "user2ca1.pem"},
// 24, GSIConstants.CertificateType.EEC)
{GSIConstants.CertificateType.EEC.name(), "user3ca1.pem"},
// 25
// GSIConstants.CertificateType.CA)
{GSIConstants.CertificateType.CA.name(), "ca2cert.pem"}, // crl 25
// must be revoked (in ca2crl.r0)
// 26, GSIConstants.CertificateType.EEC)
{GSIConstants.CertificateType.EEC.name(), "user1ca2.pem"},
// must be revoked (in ca2crl.r0)
// 27, GSIConstants.CertificateType.EEC),
{GSIConstants.CertificateType.EEC.name(), "user2ca2.pem"},
// 28, GSIConstants.CertificateType.EEC)
{GSIConstants.CertificateType.EEC.name(), "user3ca2.pem"},
// 29
// gsi3 limited impersonation signs a gsi3 independent
{GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY.name(), "gsi3independentFromLimitedProxy.pem"},
// 30
// gsi3 limited impersonation signs a gsi3 impersonation
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3limitedimpersonation2xproxy.pem"},
// 31
// gsi3 independent signs a gsi3 impersonation
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3impersonationFromIndependentProxy.pem"},
// 32
// gsi3 pathlength 0 impersonatipon proxy signs proxy
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3FromPathZeroProxy.pem"},
// 33
// gsi3 path length 1 independent proxy signs proxy
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3FromPathOneProxy.pem"},
// 34
// gsi3FrompathOneProxy signs proxy
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3FromPathOneIssuedProxy.pem"},
// 35
// gsi2 proxy generated from gsi3impersonationProxy
{GSIConstants.CertificateType.GSI_2_PROXY.name(), "gsi2proxyFromgsi3.pem"},
// 36
// gsi3 proxy generated from gsi2fullproxy
{GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY.name(), "gsi3proxyFromgsi2.pem" }};
public static String[] badCerts = {
"-----BEGIN CERTIFICATE-----\n" + "MIICFTCCAX6gAwIBAgIDClb3MA0GCSqGSIb3DQEBBAUAMGIxCzAJBgNVBAYTAlVT\n"
+ "MQ8wDQYDVQQKEwZHbG9idXMxJDAiBgNVBAoTG0FyZ29ubmUgTmF0aW9uYWwgTGFi\n"
+ "b3JhdG9yeTEMMAoGA1UECxMDTUNTMQ4wDAYDVQQDEwVnYXdvcjAeFw0wMjEyMTgw\n"
+ "NzEzNDhaFw0wMjEyMTgxOTE4NDhaMIGCMQswCQYDVQQGEwJVUzEPMA0GA1UEChMG\n"
+ "R2xvYnVzMSQwIgYDVQQKExtBcmdvbm5lIE5hdGlvbmFsIExhYm9yYXRvcnkxDDAK\n"
+ "BgNVBAsTA01DUzEOMAwGA1UEAxMFZ2F3b3IxDjAMBgNVBAMTBXByb3h5MQ4wDAYD\n"
+ "VQQDEwVwcm94eTBaMA0GCSqGSIb3DQEBAQUAA0kAMEYCQQCplfu3OZH5AfYgoYKi\n"
+ "KFmGZnbj3+ZwJm45B6Ef7qwW7Le7FP4eirljObqijgn8ao0gGqy38LYbaTntToqX\n"
+ "iy5fAgERMA0GCSqGSIb3DQEBBAUAA4GBAKnNy0VPDzzD6++7i9a/yegPX2+OVI6C\n"
+ "7oss1/4sSw2gfn/q8qNiGdt1kr4W3JJACdjgnik8fokNS7pDMdXKi3Wx6E0HhgKz\n"
+ "eRIm5r6Vj7nshVBAv60Xmfju3yaOZsDnj8p0t8Fjc8ekeZowLEdRn7PCEQPylMOp\n" + "2puR03MaPiFj\n"
+ "-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----\n" + "MIICBDCCAW2gAwIBAgIDAx4rMA0GCSqGSIb3DQEBBAUAMGIxCzAJBgNVBAYTAlVT\n"
+ "MQ8wDQYDVQQKEwZHbG9idXMxJDAiBgNVBAoTG0FyZ29ubmUgTmF0aW9uYWwgTGFi\n"
+ "b3JhdG9yeTEMMAoGA1UECxMDTUNTMQ4wDAYDVQQDEwVnYXZvcjAeFw0wMjEyMTgw\n"
+ "NzIxMThaFw0wMjEyMTgxOTI2MThaMHIxCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZH\n"
+ "bG9idXMxJDAiBgNVBAoTG0FyZ29ubmUgTmF0aW9uYWwgTGFib3JhdG9yeTEMMAoG\n"
+ "A1UECxMDTUNTMQ4wDAYDVQQDEwVnYXdvcjEOMAwGA1UEAxMFcHJveHkwWjANBgkq\n"
+ "hkiG9w0BAQEFAANJADBGAkEAx2fp80b+Yo0zCwjYJdIjzn0N3ezzcD2h2bAr/Nop\n"
+ "w/H6JB4heiVGMeydMlSJHyI7J/s5l8k39G/KVrBGT9tRJwIBETANBgkqhkiG9w0B\n"
+ "AQQFAAOBgQCRRvTdW6Ddn1curWm515l/GoAoJ76XBFJWfusIZ9TdwE8hlkRpK9Bd\n"
+ "Rrao4Z2YO+e3UItn45Hs+8gzx+jBB1AduTUor603Z8AXaNbF/c+gz62lBWlcmZ2Y\n"
+ "LzuUWgwZLd9HdA2YBgCcT3B9VFmBxcnPjGOwWT29ZUtyy2GXFtzcDw==\n"
+ "-----END CERTIFICATE-----" };
public static String[] testCerts = {
"-----BEGIN CERTIFICATE-----\n"
+ "MIIB7zCCAVigAwIBAgICAbowDQYJKoZIhvcNAQEEBQAwVzEbMBkGA1UEChMSZG9l\n"
+ "c2NpZW5jZWdyaWQub3JnMQ8wDQYDVQQLEwZQZW9wbGUxJzAlBgNVBAMTHlZpamF5\n"
+ "YSBMYWtzaG1pIE5hdGFyYWphbiAxNzkwODAeFw0wMzAxMTcyMjExMjJaFw0wMzAx\n"
+ "MTgxMDE2MjJaMGcxGzAZBgNVBAoTEmRvZXNjaWVuY2VncmlkLm9yZzEPMA0GA1UE\n"
+ "CxMGUGVvcGxlMScwJQYDVQQDEx5WaWpheWEgTGFrc2htaSBOYXRhcmFqYW4gMTc5\n"
+ "MDgxDjAMBgNVBAMTBXByb3h5MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANGP+xct\n"
+ "lDYMPm11QKnACvqs95fbPRehvUi6/dizZ+VrDOU1OTUoXA0t6HRgtmJ8XthEUKxU\n"
+ "MVsxjXtoZOzfuFECAwEAATANBgkqhkiG9w0BAQQFAAOBgQBqFTcN/qqvTnyI4z26\n"
+ "lv1lMTuRIjL9l6Ug/Kwxuzjpl088INky1myFPjKsWMYzh9nXIQg9gg2dJTno5JHB\n"
+ "++u0Fw2iNrTjswu4hvqYZn+LoSGchH2XyCUssuOWCbW4IkN8/Xzfre2oC2EieECC\n"
+ "w+jjGhcqPrxvkHh8xXYroqA0Sg==\n"
+ "-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----\n"
+ "MIIDLDCCAhSgAwIBAgICAbowDQYJKoZIhvcNAQEFBQAwdTETMBEGCgmSJomT8ixk\n"
+ "ARkWA25ldDESMBAGCgmSJomT8ixkARkWAmVzMSAwHgYDVQQLExdDZXJ0aWZpY2F0\n"
+ "ZSBBdXRob3JpdGllczEZMBcGA1UECxMQRE9FIFNjaWVuY2UgR3JpZDENMAsGA1UE\n"
+ "AxMEcGtpMTAeFw0wMjA5MjMyMzQ2NDRaFw0wMzA5MjMyMzQ2NDRaMFcxGzAZBgNV\n"
+ "BAoTEmRvZXNjaWVuY2VncmlkLm9yZzEPMA0GA1UECxMGUGVvcGxlMScwJQYDVQQD\n"
+ "Ex5WaWpheWEgTGFrc2htaSBOYXRhcmFqYW4gMTc5MDgwgZ8wDQYJKoZIhvcNAQEB\n"
+ "BQADgY0AMIGJAoGBAORYHsPQU3yVlTsC/29CDoEYF82PVlolQk5s+1m6A7m3VvML\n"
+ "TKh4ja6cKtq7C5rBUIWdyklkU3eXSSmiAzjJrVOmfWK3RR465A5tfvJLmXKWaq3U\n"
+ "7SvI6v3vx4Jzy4MJs46TDAr4v9JRJG2yshoxruRy2gDsn4F5NfLLevDNwzSLAgMB\n"
+ "AAGjaDBmMBEGCWCGSAGG+EIBAQQEAwIF4DAOBgNVHQ8BAf8EBAMCBPAwHwYDVR0j\n"
+ "BBgwFoAUVBeIygPBOSa4VabEmfQrAqu+AOkwIAYDVR0RBBkwF4EVdmlqYXlhbG5A\n"
+ "bWF0aC5sYmwuZ292MA0GCSqGSIb3DQEBBQUAA4IBAQC/dxf5ZuSrNrxslHUZfDle\n"
+ "V8SPnX5roBUOuO2EPpEGYHB25Ca+TEi0ra0RSRuZfGmY13/aS6CzjBF+6GED9MLo\n"
+ "6UdP1dg994wpGZ2Mj0dZoGE7we10NrSvFAS3u7uXrTTegeJoDpo1k9YVsOkK9Lu9\n"
+ "Sg+EztnMGa1BANWf779Qws5J9xUR2Nip0tBkV3IRORcBx0CoZzQnDIWyppmnkza2\n"
+ "mhgEv6CXYYB4ucCFst0P2Q3omcWrtHexoueMGOV6PtLFBst5ReOaZWU+q2D30t3b\n"
+ "GFITa0aayXTlb6gWgo3z/O/K5GZS5jF+BA3j1e8IhxqeibT1rVHF4W4ZMjGhBcwa\n"
+ "-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----\n"
+ "MIIEqjCCBBOgAwIBAgIBLzANBgkqhkiG9w0BAQUFADBbMRkwFwYDVQQKExBET0Ug\n"
+ "U2NpZW5jZSBHcmlkMSAwHgYDVQQLExdDZXJ0aWZpY2F0ZSBBdXRob3JpdGllczEc\n"
+ "MBoGA1UEAxMTQ2VydGlmaWNhdGUgTWFuYWdlcjAeFw0wMTEyMjEyMzQ4MzdaFw0w\n"
+ "NDAxMTAyMzQ4MzdaMHUxEzARBgoJkiaJk/IsZAEZFgNuZXQxEjAQBgoJkiaJk/Is\n"
+ "ZAEZFgJlczEgMB4GA1UECxMXQ2VydGlmaWNhdGUgQXV0aG9yaXRpZXMxGTAXBgNV\n"
+ "BAsTEERPRSBTY2llbmNlIEdyaWQxDTALBgNVBAMTBHBraTEwggEiMA0GCSqGSIb3\n"
+ "DQEBAQUAA4IBDwAwggEKAoIBAQDhgzoAt5viFffXWG6P0KSf/dO0mrEbgpuKIHDa\n"
+ "RdHkxJGaoBgRO2D+YV4Wh+JcKlz64v2ScYHCgGbKoaE+cGM/O06xkLCV0pyT4Xvj\n"
+ "6/R80jqwzzRw8aYz9iE/wjljK1ehb+oJ6TJlnotCVBd7TlHODYfXXblt67/Uk1uu\n"
+ "4l17jCdfk4mUn/2Bdeae4EMibj7Vc1dkPkyY47ZADTeFXMNDyp4yGFeIDZQ6h+YH\n"
+ "27+t1/TDuEH1R4PpklRpSbppGprI8hv2P6uEKTySjAEkww9xVzenN6oULeafFJuS\n"
+ "t6Ui6BFxc1OuxMq/s0PDiFh8bPMhzJWBfzaNPHnYrFDWcDwHAgMBAAGjggHeMIIB\n"
+ "2jAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFFQXiMoDwTkmuFWmxJn0KwKrvgDp\n"
+ "MB8GA1UdIwQYMBaAFJvOT/K8vVhwMdXyMg5+nr3iURTnMA8GA1UdEwEB/wQFMAMB\n"
+ "Af8wgY8GA1UdHwSBhzCBhDCBgaAaoBiGFmh0dHA6Ly9lbnZpc2FnZS5lcy5uZXSB\n"
+ "AgDsol+kXTBbMRkwFwYDVQQKExBET0UgU2NpZW5jZSBHcmlkMSAwHgYDVQQLExdD\n"
+ "ZXJ0aWZpY2F0ZSBBdXRob3JpdGllczEcMBoGA1UEAxMTQ2VydGlmaWNhdGUgTWFu\n"
+ "YWdlcjCB5AYDVR0gBIHcMIHZMIHWBgoqhkiG90wDBgQBMIHHMF8GCCsGAQUFBwIC\n"
+ "MFMwJhYfRVNuZXQgKEVuZXJneSBTY2llbmNlcyBOZXR3b3JrKTADAgEBGilFU25l\n"
+ "dC1ET0UgU2NpZW5jZSBHcmlkIENlcnRpZmljYXRlIFBvbGljeTBkBggrBgEFBQcC\n"
+ "ARZYaHR0cDovL2VudmlzYWdlLmVzLm5ldC9FbnZpc2FnZSUyMERvY3MvRE9FU0cl\n"
+ "MjBDQSUyMENlcnRpZmljYXRlJTIwUG9saWN5JTIwYW5kJTIwQ1BTLnBkZjANBgkq\n"
+ "hkiG9w0BAQUFAAOBgQCaAdUregqwmCJG6j/h6uK2bTpcfa/SfpaYwsTy+zlf5r4P\n"
+ "iY/wIRN0ZjJ4RrJQ/WUH16onNwb87JnYe0V4JYhATAOnp/5y9kl+iC4XvHBioVxm\n"
+ "3sEADL40WAVREWBGZnyFqysXAEGfk+Wg7um5FzCwi6380GASKY0VujQG03f6Pg==\n"
+ "-----END CERTIFICATE-----"
};
// Globus CA signing policy. Using globusca.pem and usercert.pem
public static String signingPolicy = "access_id_CA X509 '/C=TestCA1/CN=CA'\npos_rights globus CA:sign\ncond_subjects globus '\"/*\"'";
// Globus CA signing policy that causes usercert.pem to violate
// the policy
public static String signingPolicyViolation = "access_id_CA X509 '/C=TestCA1/CN=CA'\npos_rights globus CA:sign\ncond_subjects globus '\"/12*\"'";
// Globus CA signing policy without relevant signing policy
public static String signingPolicySansPolicy = "# Globus CA rights\naccess_id_CA nonX509 '/C=US/O=Globus/CN=Globus Certification Authority'\npos_rights globus CA:sign\ncond_subjects globus '\"/C=usa/O=Globus/*\" \"/C=USA/O=Globus/*\"'\n# End of ca-signing-policy.conf";
public static X509Certificate[] goodCertsArr;
static {
try {
goodCertsArr = initCerts();
} catch (Exception e) {
throw new RuntimeException("Failed to load certs: " + e.getMessage());
}
}
public ProxyPathValidatorTest(String name) {
super(name);
}
public static X509Certificate[] initCerts() throws Exception {
CoGProperties.getDefault().setProperty(CoGProperties.getDefault().CRL_CACHE_LIFETIME, "1");
X509Certificate[] goodCertsArr = new X509Certificate[certs.length];
ClassLoader loader = ProxyPathValidatorTest.class.getClassLoader();
for (int i = 0; i < certs.length; i++) {
String name = BASE + certs[i][1];
InputStream in = loader.getResourceAsStream(name);
if (in == null) {
throw new Exception("Unable to load: " + name);
}
log.debug("goodCertsArr[" + i + "]" + name);
goodCertsArr[i] = CertificateLoadUtil.loadCertificate(in);
}
return goodCertsArr;
}
public void testValidateGsi2PathGood() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[0] };
// EEC, CA
chain = new X509Certificate[] { goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], false);
// proxy, EEC, CA
chain = new X509Certificate[] { goodCertsArr[2], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], false);
// limited proxy, EEC, CA
chain = new X509Certificate[] { goodCertsArr[3], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], true);
// double limited proxy, limited proxy, EEC, CA
chain = new X509Certificate[] { goodCertsArr[4], goodCertsArr[3], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], true);
}
public void testValidateGsi3PathGood() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[0] };
// GSI 3 PC impersonation, EEC, CA
chain = new X509Certificate[] { goodCertsArr[5], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], false);
// GSI 3 PC independent, EEC, CA
chain = new X509Certificate[] { goodCertsArr[6], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[6], false);
// GSI 3 PC imperson limited, EEC, CA
chain = new X509Certificate[] { goodCertsArr[7], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], true);
// GSI 3 PC impersonation, GSI 3 PC limited impersonation, EEC, CA
chain = new X509Certificate[] { goodCertsArr[30], goodCertsArr[7], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], true);
// GSI 3 PC impersonation, GSI 3 PC impersonation, EEC, CA
chain = new X509Certificate[] { goodCertsArr[9], goodCertsArr[5], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], false);
// GSI 3 PC indepedent, GSI 3 PC independent, EEC, CA
chain = new X509Certificate[] { goodCertsArr[10], goodCertsArr[6], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[10], false);
// GSI 3 PC impersonation, GSI 3 PC independent, EEC, CA
chain = new X509Certificate[] { goodCertsArr[31], goodCertsArr[6], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[6], false);
// GSI 3 PC indepedent, GSI 3 PC limited impersonation, EEC, CA
chain = new X509Certificate[] { goodCertsArr[29], goodCertsArr[7], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[29], false);
}
public void testValidatePathWithRestrictedProxy() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[0] };
// GSI 3 PC restricted, EEC, CA
chain = new X509Certificate[] { goodCertsArr[8], goodCertsArr[1], goodCertsArr[0] };
validateError(chain, trustedCerts, ProxyPathValidatorException.UNKNOWN_POLICY);
// // GSI 3 PC impersonation, GSI 3 PC restricted, EEC, CA
chain = new X509Certificate[] { goodCertsArr[9], goodCertsArr[8], goodCertsArr[1], goodCertsArr[0] };
validateError(chain, trustedCerts, ProxyPathValidatorException.UNKNOWN_POLICY);
TestProxyPathValidator v = new TestProxyPathValidator();
v.setProxyPolicyHandler("1.3.6.1.4.1.3536.1.1.1.8", new ProxyPolicyHandler() {
public void validate(ProxyCertInfo info, CertPath path, int index) throws CertPathValidatorException {
ProxyPolicy policy = info.getProxyPolicy();
String pol = policy.getPolicyAsString();
assertEquals("<AllPermissions...>\r\n".trim(), pol.trim());
// COMMENT fails without trimming
}
});
chain = new X509Certificate[] { goodCertsArr[8], goodCertsArr[1], goodCertsArr[0] };
v.validate(chain, trustedCerts);
}
public void testValidatePathBad() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[0] };
// proxy, CA
chain = new X509Certificate[] { goodCertsArr[5], goodCertsArr[0] };
validateChain(chain, trustedCerts);
// user, proxy, CA
chain = new X509Certificate[] { goodCertsArr[1], goodCertsArr[2], goodCertsArr[0] };
validateChain(chain, trustedCerts);
// user, user, CA
chain = new X509Certificate[] { goodCertsArr[1], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts);
// user, CA, user
chain = new X509Certificate[] { goodCertsArr[1], goodCertsArr[0], goodCertsArr[1] };
validateChain(chain, trustedCerts);
}
public void testValidatePathMixedProxy() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[0] };
// GSI 3 PC, GSI 2 PC, EEC, CA
chain = new X509Certificate[] { goodCertsArr[6], goodCertsArr[2], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts);
// GSI 2 PC, GSI 3 PC, EEC, CA
chain = new X509Certificate[] { goodCertsArr[2], goodCertsArr[6], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts);
}
public void testValidatePathProxyPathConstraint() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[0] };
// GSI 3 PC pathlen=0, GSI 3 PC, EEC, CA
chain = new X509Certificate[] { goodCertsArr[11], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[1], false);
// GSI 3 PC, GSI 3 PC pathlen=0, EEC, CA
chain = new X509Certificate[] { goodCertsArr[32], goodCertsArr[11], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts);
// GSI 3 PC, GSI 3 PC pathlen=1, EEC, CA
chain = new X509Certificate[] { goodCertsArr[33], goodCertsArr[12], goodCertsArr[1], goodCertsArr[0] };
validateChain(chain, trustedCerts, goodCertsArr[12], false);
// GSI 3 PC, GSI 3 PC, GSI 3 PC pathlen=1, EEC, CA
chain = new X509Certificate[] { goodCertsArr[34], goodCertsArr[33], goodCertsArr[12], goodCertsArr[1],
goodCertsArr[0] };
validateError(chain, trustedCerts, ProxyPathValidatorException.PATH_LENGTH_EXCEEDED);
}
public void testValidatePathCAPathConstraint() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[16] };
// should all be OK
// EEC, CA (pathlen=0)
chain = new X509Certificate[] { goodCertsArr[15], goodCertsArr[16] };
validateChain(chain, trustedCerts, goodCertsArr[15], false);
// GSI 2 limited PC, EEC, CA (pathlen=0)
chain = new X509Certificate[] { goodCertsArr[3], goodCertsArr[15], goodCertsArr[16] };
//validateChain(chain, trustedCerts, goodCertsArr[15], true);
validateError(chain, trustedCerts, ProxyPathValidatorException.PATH_LENGTH_EXCEEDED);
// GSI 3 PC, EEC, CA (pathlen=0)
chain = new X509Certificate[] { goodCertsArr[17], goodCertsArr[15], goodCertsArr[16] };
validateChain(chain, trustedCerts, goodCertsArr[15], false);
// GSI 3 PC, EEC, CA (pathlen=0), CA (pathlen=2), CA (pathlen=2)
chain = new X509Certificate[] { goodCertsArr[17], goodCertsArr[15], goodCertsArr[16], goodCertsArr[13],
goodCertsArr[13] };
validateChain(chain, trustedCerts, goodCertsArr[15], false);
// these should fail
// EEC, CA (pathlen=0), CA (pathlen=0)
chain = new X509Certificate[] { goodCertsArr[15], goodCertsArr[16], goodCertsArr[16] };
validateError(chain, trustedCerts, ProxyPathValidatorException.PATH_LENGTH_EXCEEDED);
// GSI 2 limited PC, EEC, CA (pathlen=0), CA (pathlen=2), CA (pathlen=2), CA (pathlen=2)
chain = new X509Certificate[] { goodCertsArr[3], goodCertsArr[15], goodCertsArr[16], goodCertsArr[13],
goodCertsArr[13], goodCertsArr[13] };
validateError(chain, trustedCerts, ProxyPathValidatorException.PATH_LENGTH_EXCEEDED);
// GSI 3 PC, GSI 3 PC pathlen=1, EEC, CA
chain = new X509Certificate[] { goodCertsArr[10/*10*/], goodCertsArr[12], goodCertsArr[1], goodCertsArr[13] };
//validateChain(chain, trustedCerts, goodCertsArr[10/*10*/], false);
validateError(chain, trustedCerts, ProxyPathValidatorException.PATH_LENGTH_EXCEEDED);
// GSI 3 PC, GSI 3 PC, GSI 3 PC pathlen=1, EEC, CA
chain = new X509Certificate[] { goodCertsArr[10], goodCertsArr[10], goodCertsArr[12], goodCertsArr[1],
goodCertsArr[13] };
validateError(chain, trustedCerts, ProxyPathValidatorException.PATH_LENGTH_EXCEEDED);
// GSI 3 PC, GSI 3 PC pathlen=0, EEC, CA
chain = new X509Certificate[] { goodCertsArr[10], goodCertsArr[11], goodCertsArr[1], goodCertsArr[13] };
validateError(chain, trustedCerts, ProxyPathValidatorException.FAILURE);
}
public void testKeyUsage() throws Exception {
X509Certificate[] certsArr = new X509Certificate[testCerts.length];
for (int i = 0; i < certsArr.length; i++) {
certsArr[i] = CertificateLoadUtil.loadCertificate(
new ByteArrayInputStream(testCerts[i].getBytes()));
}
X509Certificate[] trustedCAs = new X509Certificate[]{certsArr[2]};
X509Certificate[] chain = null;
// certArr[1] - has key usage but certSign is off - but it signs proxy
// certArr[2] - has key usage and certSign is on
chain = new X509Certificate[] { certsArr[0], certsArr[1], certsArr[2] };
validateChain(chain, trustedCAs, certsArr[1], false);
TestProxyPathValidator v = new TestProxyPathValidator();
v.validate(chain, new TrustedCertificates(trustedCAs));
assertEquals(false, v.isLimited());
assertEquals(certsArr[1], v.getIdentityCertificate());
}
public void testNoBasicConstraintsExtension() throws Exception {
X509Certificate[] chain = null;
X509Certificate[] trustedCAs = new X509Certificate[] { goodCertsArr[16] };
X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[16] };
// EEC, EEC, CA - that should fail
//chain = new X509Certificate[] { goodCertsArr[1], goodCertsArr[1], goodCertsArr[0] };
chain = new X509Certificate[] { goodCertsArr[15], goodCertsArr[15], goodCertsArr[16] };
//validateChain(chain, trustedCerts, goodCertsArr[15], false);
validateChain(chain, trustedCAs);
TestProxyPathValidator v = new TestProxyPathValidator();
TrustedCertificates trustedCert = new TrustedCertificates(new X509Certificate[] { goodCertsArr[16] },
new SigningPolicy[] { new SigningPolicy(new X500Principal("CN=foo"), new String[] { "CN=foo" }) });
//X509Certificate[] trustedCerts = new X509Certificate[] { goodCertsArr[1] };
chain = new X509Certificate[] { goodCertsArr[16], goodCertsArr[16], goodCertsArr[0] };
// this makes the PathValidator think the chain is:
// CA, CA, CA - which is ok. irrelevant to signing policy.
try {
v.validate(chain, trustedCert);
} catch (ProxyPathValidatorException e) {
e.printStackTrace();
fail("Unexpected exception: " + e.getMessage());
}
}
//JGLOBUS-103
public void testCrlsChecks() throws Exception {
TestProxyPathValidator tvalidator = new TestProxyPathValidator();
// chain of good certs
X509Certificate[] chain = new X509Certificate[]{goodCertsArr[22], goodCertsArr[21]};
X509Certificate[] tCerts = new X509Certificate[]{goodCertsArr[1],
goodCertsArr[16], goodCertsArr[25], goodCertsArr[21]};
ClassLoader loader = ProxyPathValidatorTest.class.getClassLoader();
String location1 = loader.getResource(BASE).getPath();
CertificateRevocationLists certRevLists = CertificateRevocationLists.getCertificateRevocationLists(location1);
assertNotNull(certRevLists);
assertEquals(2,certRevLists.getCrls().length);
TrustedCertificates trustedCerts = new TrustedCertificates(tCerts);
X509CRL[] crls = certRevLists.getCrls();
assertNotNull(crls);
assertEquals(2, crls.length);
try {
tvalidator.validate(chain, trustedCerts.getCertificates(), certRevLists, trustedCerts.getSigningPolicies());
} catch (ProxyPathValidatorException e) {
e.printStackTrace();
fail("Unexpected exception: " + e.getMessage());
}
tvalidator.reset();
// remove signing policy checks and validity checks
// ca1 ca1user1 good chain
chain = new X509Certificate[] { goodCertsArr[22], goodCertsArr[21] };
certRevLists = CertificateRevocationLists.getCertificateRevocationLists(location1);
assertNotNull(certRevLists.getCrls());
assertEquals(2,certRevLists.getCrls().length);
try {
tvalidator.validate(chain, new X509Certificate[] { goodCertsArr[21] }, certRevLists, trustedCerts
.getSigningPolicies());
} catch (ProxyPathValidatorException e) {
e.printStackTrace();
fail("Unexpected exception: " + e.getMessage());
}
tvalidator.reset();
// ca1 ca1user2 good chain
chain = new X509Certificate[] { goodCertsArr[23], goodCertsArr[21] };
try {
tvalidator.validate(chain, new X509Certificate[] { goodCertsArr[21] }, certRevLists, trustedCerts
.getSigningPolicies());
} catch (ProxyPathValidatorException e) {
e.printStackTrace();
fail("Unexpected exception: " + e.getMessage());
}
tvalidator.reset();
// ca2 user1 bad chain
chain = new X509Certificate[] { goodCertsArr[26], goodCertsArr[25] };
try {
tvalidator.validate(chain, new X509Certificate[] { goodCertsArr[25] }, certRevLists, trustedCerts
.getSigningPolicies());
fail("Validation did not throw exception");
} catch (ProxyPathValidatorException crlExp) {
// COMMENT no check on exception error code
//assertEquals(ProxyPathValidatorException.REVOKED, crlExp.getErrorCode());
}
tvalidator.reset();
// ca2 user2 bad chain
chain = new X509Certificate[] { goodCertsArr[27], goodCertsArr[25] };
try {
tvalidator.validate(chain, new X509Certificate[] { goodCertsArr[25] }, certRevLists, trustedCerts
.getSigningPolicies());
fail("Validation did not throw exception");
} catch (ProxyPathValidatorException crlExp) {
// COMMENT no check on exceptino error code
//assertEquals(ProxyPathValidatorException.REVOKED, crlExp.getErrorCode());
}
tvalidator.reset();
// ca2 user3 good chain
chain = new X509Certificate[] { goodCertsArr[28], goodCertsArr[25] };
try {
tvalidator.validate(chain, new X509Certificate[] { goodCertsArr[25] }, certRevLists, trustedCerts.getSigningPolicies());
} catch (ProxyPathValidatorException e) {
e.printStackTrace();
fail("Unexpected exception: " + e.getMessage());
}
}
public void testSigningPolicy() throws Exception {
X509Certificate[] chain = null;
Map<X500Principal, SigningPolicy> map = new SigningPolicyParser().parse(new StringReader(signingPolicy));
SigningPolicy policy = map.values().iterator().next();
assertNotNull(policy);
TestProxyPathValidator tvalidator = new TestProxyPathValidator(true);
chain = new X509Certificate[] { goodCertsArr[1], goodCertsArr[0] };
TrustedCertificates tc = new TrustedCertificates(new X509Certificate[] { goodCertsArr[0] },
new SigningPolicy[] { policy });
tvalidator.validate(chain, tc);
map = new SigningPolicyParser().parse(new StringReader(signingPolicyViolation));
policy = map.values().iterator().next();
assertNotNull(policy);
tc = new TrustedCertificates(new X509Certificate[] { goodCertsArr[0] }, new SigningPolicy[] { policy });
try {
tvalidator.validate(chain, tc);
fail("Exception expected");
} catch (ProxyPathValidatorException exp) {
// COMMENT ignore error code
//assertEquals(ProxyPathValidatorException.SIGNING_POLICY_VIOLATION, exp.getErrorCode());
}
try {
map = new SigningPolicyParser().parse(new StringReader(signingPolicySansPolicy));
fail("Exception expected");
} catch (IllegalArgumentException exp) {
}
}
private void validateChain(X509Certificate[] chain, X509Certificate[] trustedCerts) throws Exception {
validateError(chain, trustedCerts, ProxyPathValidatorException.FAILURE);
}
private void validateChain(X509Certificate[] chain, X509Certificate[] trustedCerts,
X509Certificate expectedIdentity, boolean expectedLimited) throws Exception {
TestProxyPathValidator v = new TestProxyPathValidator();
v.validate(chain, new TrustedCertificates(trustedCerts));
assertEquals(expectedLimited, v.isLimited());
assertEquals(expectedIdentity, v.getIdentityCertificate());
}
private void validateError(X509Certificate[] chain, X509Certificate[] trustedCerts, int expectedErrorCode) throws Exception {
TestProxyPathValidator v = new TestProxyPathValidator();
try {
v.validate(chain);
fail("Did not throw exception as expected");
} catch (ProxyPathValidatorException e) {
// COMMENT ignore error codes, because new code works with strings
//assertEquals(expectedErrorCode, e.getErrorCode());
}
}
// for testing only to disable validity checking
class TestProxyPathValidator extends ProxyPathValidator {
boolean policyChk = false;
MockProxyCertPathValidator validator;
TestProxyPathValidator() {
super();
policyChk = false;
validator = new MockProxyCertPathValidator(false, false, false);
}
TestProxyPathValidator(boolean checkSigningPolicy) {
policyChk = checkSigningPolicy;
validator = new MockProxyCertPathValidator(false, false, true);
}
public void validate(X509Certificate[] certPath) throws ProxyPathValidatorException {
super.setValidator(validator);
super.validate(certPath);
}
public void validate(X509Certificate[] certPath, TrustedCertificates trustedCerts)
throws ProxyPathValidatorException {
super.setValidator(validator);
super.validate(certPath, trustedCerts);
}
public void validate(X509Certificate[] certPath, TrustedCertificates trustedCerts,
CertificateRevocationLists crlsList, Boolean enforceSigningPolicy) throws ProxyPathValidatorException {
super.setValidator(validator);
super.validate(certPath, trustedCerts, crlsList, enforceSigningPolicy);
}
}
// for testing only to disable validity checking
public class MockProxyCertPathValidator extends X509ProxyCertPathValidator {
boolean checkCertificateDateValidity;
boolean checkCRLDateValidity;
boolean checkSigningPolicy;
private CertificateChecker dateChecker = new DateValidityChecker();
public MockProxyCertPathValidator(boolean checkCertificateDateValidity_,
boolean checkCRLDateValidity_,
boolean checkSigningPolicy_) {
this.checkCertificateDateValidity = checkCertificateDateValidity_;
this.checkCRLDateValidity = checkCRLDateValidity_;
this.checkSigningPolicy = checkSigningPolicy_;
}
@Override
protected List<CertificateChecker> getCertificateCheckers() {
List<CertificateChecker> checkers = new ArrayList<CertificateChecker>();
if (checkCertificateDateValidity) {
checkers.add(dateChecker);
}
checkers.add(new UnsupportedCriticalExtensionChecker());
checkers.add(new IdentityChecker(this));
checkers.add(new CRLChecker(this.certStore, this.keyStore, this.checkCertificateDateValidity));
if (this.checkSigningPolicy) {
checkers.add(new SigningPolicyChecker(this.policyStore));
}
return checkers;
}
}
}