Issue #1553 - Guard against X509.isCertSign AIOOBE

This commit is contained in:
Joakim Erdfelt 2017-05-15 10:23:22 -07:00
parent da5a783e86
commit ca4e72ca5d
3 changed files with 324 additions and 2 deletions

View File

@ -52,8 +52,12 @@ public class X509
public static boolean isCertSign(X509Certificate x509)
{
boolean[] key_usage=x509.getKeyUsage();
return key_usage!=null && key_usage[KEY_USAGE__KEY_CERT_SIGN];
boolean[] key_usage = x509.getKeyUsage();
if ((key_usage == null) || (key_usage.length <= KEY_USAGE__KEY_CERT_SIGN))
{
return false;
}
return key_usage[KEY_USAGE__KEY_CERT_SIGN];
}
private final X509Certificate _x509;

View File

@ -0,0 +1,192 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util.ssl;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Set;
/**
* Bogus X509Certificate to aide in testing
*/
public class X509CertificateAdapter extends X509Certificate
{
@Override
public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException
{
}
@Override
public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException
{
}
@Override
public byte[] getEncoded() throws CertificateEncodingException
{
return new byte[0];
}
@Override
public boolean hasUnsupportedCriticalExtension()
{
return false;
}
@Override
public Set<String> getCriticalExtensionOIDs()
{
return null;
}
@Override
public Set<String> getNonCriticalExtensionOIDs()
{
return null;
}
@Override
public byte[] getExtensionValue(String oid)
{
return new byte[0];
}
@Override
public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException
{
}
@Override
public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException
{
}
@Override
public String toString()
{
return null;
}
@Override
public PublicKey getPublicKey()
{
return null;
}
@Override
public int getVersion()
{
return 0;
}
@Override
public BigInteger getSerialNumber()
{
return null;
}
@Override
public Principal getIssuerDN()
{
return null;
}
@Override
public Principal getSubjectDN()
{
return null;
}
@Override
public Date getNotBefore()
{
return null;
}
@Override
public Date getNotAfter()
{
return null;
}
@Override
public byte[] getTBSCertificate() throws CertificateEncodingException
{
return new byte[0];
}
@Override
public byte[] getSignature()
{
return new byte[0];
}
@Override
public String getSigAlgName()
{
return null;
}
@Override
public String getSigAlgOID()
{
return null;
}
@Override
public byte[] getSigAlgParams()
{
return new byte[0];
}
@Override
public boolean[] getIssuerUniqueID()
{
return new boolean[0];
}
@Override
public boolean[] getSubjectUniqueID()
{
return new boolean[0];
}
@Override
public boolean[] getKeyUsage()
{
return new boolean[0];
}
@Override
public int getBasicConstraints()
{
return 0;
}
}

View File

@ -0,0 +1,126 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util.ssl;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.security.cert.X509Certificate;
import org.junit.Test;
public class X509Test
{
@Test
public void testIsCertSign_Normal()
{
X509Certificate bogusX509 = new X509CertificateAdapter()
{
@Override
public boolean[] getKeyUsage()
{
boolean[] keyUsage = new boolean[8];
keyUsage[5] = true;
return keyUsage;
}
};
assertThat("Normal X509", X509.isCertSign(bogusX509), is(true));
}
@Test
public void testIsCertSign_Normal_NoSupported()
{
X509Certificate bogusX509 = new X509CertificateAdapter()
{
@Override
public boolean[] getKeyUsage()
{
boolean[] keyUsage = new boolean[8];
keyUsage[5] = false;
return keyUsage;
}
};
assertThat("Normal X509", X509.isCertSign(bogusX509), is(false));
}
@Test
public void testIsCertSign_NonStandard_Short()
{
X509Certificate bogusX509 = new X509CertificateAdapter()
{
@Override
public boolean[] getKeyUsage()
{
boolean[] keyUsage = new boolean[6]; // at threshold
keyUsage[5] = true;
return keyUsage;
}
};
assertThat("NonStandard X509", X509.isCertSign(bogusX509), is(true));
}
@Test
public void testIsCertSign_NonStandard_Shorter()
{
X509Certificate bogusX509 = new X509CertificateAdapter()
{
@Override
public boolean[] getKeyUsage()
{
boolean[] keyUsage = new boolean[5]; // just below threshold
return keyUsage;
}
};
assertThat("NonStandard X509", X509.isCertSign(bogusX509), is(false));
}
@Test
public void testIsCertSign_Normal_Null()
{
X509Certificate bogusX509 = new X509CertificateAdapter()
{
@Override
public boolean[] getKeyUsage()
{
return null;
}
};
assertThat("Normal X509", X509.isCertSign(bogusX509), is(false));
}
@Test
public void testIsCertSign_Normal_Empty()
{
X509Certificate bogusX509 = new X509CertificateAdapter()
{
@Override
public boolean[] getKeyUsage()
{
return new boolean[0];
}
};
assertThat("Normal X509", X509.isCertSign(bogusX509), is(false));
}
}