HBASE-12006 [JDK 8] KeyStoreTestUtil#generateCertificate fails due to "subject class type invalid"

This is a port of the fix from HADOOP-10847
This commit is contained in:
Andrew Purtell 2015-04-15 09:47:34 -07:00
parent fe8658ce35
commit c2eeddfb27
3 changed files with 34 additions and 45 deletions

View File

@ -506,6 +506,11 @@
<artifactId>hadoop-minikdc</artifactId> <artifactId>hadoop-minikdc</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<profiles> <profiles>
<!-- Skip the tests in this module --> <!-- Skip the tests in this module -->

View File

@ -26,38 +26,32 @@ import java.io.Writer;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URL; import java.net.URL;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.NoSuchProviderException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory; import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory;
import org.apache.hadoop.security.ssl.SSLFactory; import org.apache.hadoop.security.ssl.SSLFactory;
import org.bouncycastle.x509.X509V1CertificateGenerator;
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateSubjectName;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
public class KeyStoreTestUtil { public class KeyStoreTestUtil {
public static String getClasspathDir(Class klass) throws Exception { public static String getClasspathDir(Class<?> klass) throws Exception {
String file = klass.getName(); String file = klass.getName();
file = file.replace('.', '/') + ".class"; file = file.replace('.', '/') + ".class";
URL url = Thread.currentThread().getContextClassLoader().getResource(file); URL url = Thread.currentThread().getContextClassLoader().getResource(file);
@ -68,48 +62,31 @@ public class KeyStoreTestUtil {
/** /**
* Create a self-signed X.509 Certificate. * Create a self-signed X.509 Certificate.
* From http://bfo.com/blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html.
* *
* @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB" * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
* @param pair the KeyPair * @param pair the KeyPair
* @param days how many days from now the Certificate is valid for * @param days how many days from now the Certificate is valid for
* @param algorithm the signing algorithm, eg "SHA1withRSA" * @param algorithm the signing algorithm, eg "SHA1withRSA"
* @return the self-signed certificate * @return the self-signed certificate
* @throws IOException thrown if an IO error ocurred.
* @throws GeneralSecurityException thrown if an Security error ocurred.
*/ */
public static X509Certificate generateCertificate(String dn, KeyPair pair, public static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
int days, String algorithm) throws CertificateEncodingException, InvalidKeyException, IllegalStateException,
throws GeneralSecurityException, IOException { NoSuchProviderException, NoSuchAlgorithmException, SignatureException {
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date(); Date from = new Date();
Date to = new Date(from.getTime() + days * 86400000l); Date to = new Date(from.getTime() + days * 86400000l);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom()); BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn); KeyPair keyPair = pair;
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
X500Principal dnName = new X500Principal(dn);
info.set(X509CertInfo.VALIDITY, interval); certGen.setSerialNumber(sn);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); certGen.setIssuerDN(dnName);
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); certGen.setNotBefore(from);
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); certGen.setNotAfter(to);
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); certGen.setSubjectDN(dnName);
info certGen.setPublicKey(keyPair.getPublic());
.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); certGen.setSignatureAlgorithm(algorithm);
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); X509Certificate cert = certGen.generate(pair.getPrivate());
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
// Sign the cert to identify the algorithm that's used.
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
// Update the algorith, and resign.
algo = (AlgorithmId) cert.get(X509CertImpl.SIG_ALG);
info
.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM,
algo);
cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
return cert; return cert;
} }

View File

@ -1104,6 +1104,7 @@
<joni.version>2.1.2</joni.version> <joni.version>2.1.2</joni.version>
<jcodings.version>1.0.8</jcodings.version> <jcodings.version>1.0.8</jcodings.version>
<spy.version>2.11.6</spy.version> <spy.version>2.11.6</spy.version>
<bouncycastle.version>1.46</bouncycastle.version>
<!-- Plugin Dependencies --> <!-- Plugin Dependencies -->
<maven.assembly.version>2.4</maven.assembly.version> <maven.assembly.version>2.4</maven.assembly.version>
<maven.antrun.version>1.6</maven.antrun.version> <maven.antrun.version>1.6</maven.antrun.version>
@ -1637,6 +1638,12 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>${bouncycastle.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<!-- Dependencies needed by subprojects --> <!-- Dependencies needed by subprojects -->