diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java hbase-server/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java index 248b820..8fa0aa8 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java @@ -18,6 +18,9 @@ package org.apache.hadoop.hbase.http.ssl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; @@ -43,20 +46,16 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory; import org.apache.hadoop.security.ssl.SSLFactory; -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; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.security.PublicKey; public class KeyStoreTestUtil { + public static final Log LOG = + LogFactory.getLog(KeyStoreTestUtil.class); + public static String getClasspathDir(Class klass) throws Exception { String file = klass.getName(); file = file.replace('.', '/') + ".class"; @@ -80,39 +79,122 @@ public class KeyStoreTestUtil { */ public static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm) - throws GeneralSecurityException, IOException { - PrivateKey privkey = pair.getPrivate(); - X509CertInfo info = new X509CertInfo(); - Date from = new Date(); - Date to = new Date(from.getTime() + days * 86400000l); - CertificateValidity interval = new CertificateValidity(from, to); - BigInteger sn = new BigInteger(64, new SecureRandom()); - X500Name owner = new X500Name(dn); - - info.set(X509CertInfo.VALIDITY, interval); - info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); - info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); - info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); - info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); - info - .set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); - AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); - 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; + throws GeneralSecurityException, IOException { + PrivateKey privkey = pair.getPrivate(); + Object x509CertImplObject = null ; + try{ + Date from = new Date(); + Date to = new Date(from.getTime() + days * 86400000l); + + Class certInfoClass = Class.forName(getX509CertInfoModuleName()); + Constructor certInfoConstr = certInfoClass.getConstructor(); + Object certInfoObject = certInfoConstr.newInstance(); + + //CertificateValidity interval = new CertificateValidity(from, to); + Class certValidityClass = Class.forName(getX509CertifValidityModuleName()); + Constructor certValidityConstr = certValidityClass.getConstructor(new Class[] {Date.class, Date.class}); + Object certValidityObject = certValidityConstr.newInstance(from, to); + + BigInteger sn = new BigInteger(64, new SecureRandom()); + + //X500Name owner = new X500Name(dn); + Class x500NameClass = Class.forName(getX509X500NameModuleName()); + Constructor x500NameConstr = x500NameClass.getConstructor(new Class[] {String.class}); + Object x500NameObject = x500NameConstr.newInstance(dn); + + Method methodSET = certInfoObject.getClass().getMethod("set", String.class, Object.class); + + //info.set(X509CertInfo.VALIDITY, interval); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"VALIDITY"), certValidityObject); + + //info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); + Class certificateSerialNumberClass = Class.forName(getCertificateSerialNumberModuleName()); + Constructor certificateSerialNumberConstr = certificateSerialNumberClass.getConstructor(new Class[] {BigInteger.class}); + Object certificateSerialNumberObject = certificateSerialNumberConstr.newInstance(sn); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"SERIAL_NUMBER"), certificateSerialNumberObject); + + //info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); + Class certificateSubjectNameClass = Class.forName(getCertificateSubjectNameModuleName()); + Constructor certificateSubjectNameConstr = certificateSubjectNameClass.getConstructor(new Class[] {x500NameClass}); + Object certificateSubjectNameObject = certificateSubjectNameConstr.newInstance(x500NameObject); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"SUBJECT"), certificateSubjectNameObject); + + //info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); + Class certificateIssuerNameClass = Class.forName(getCertificateIssuerNameModuleName()); + Constructor certificateIssuerNameConstr = certificateIssuerNameClass.getConstructor(new Class[] {x500NameClass}); + Object certificateIssuerNameObject = certificateIssuerNameConstr.newInstance(x500NameObject); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"ISSUER"), certificateIssuerNameObject); + + //info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); getCertificateX509KeyModuleName + Class certificateX509KeyClass = Class.forName(getCertificateX509KeyModuleName()); + Constructor certificateX509KeyConstr = certificateX509KeyClass.getConstructor(new Class[] {PublicKey.class}); + Object certificateX509KeyObject = certificateX509KeyConstr.newInstance(pair.getPublic()); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"KEY"), certificateX509KeyObject); + //info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); + Class certificateVersionClass = Class.forName(getCertificateVersionModuleName()); + Constructor certificateVersionConstr = certificateVersionClass.getConstructor(new Class[] {int.class}); + Constructor certificateVersionConstr0 = certificateVersionClass.getConstructor(); + Object certInfoObject0 = certificateVersionConstr0.newInstance(); + Field v3IntField = certInfoObject0.getClass().getDeclaredField("V3"); + v3IntField.setAccessible(true); + int fValue = (int) v3IntField.getInt(certInfoObject0); + Object certificateVersionObject = certificateVersionConstr.newInstance(fValue); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"VERSION"), certificateVersionObject); + + + //AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); + Class algorithmIdClass = Class.forName(getAlgorithmIdModuleName()); + Field md5WithRSAField = algorithmIdClass.getDeclaredField("md5WithRSAEncryption_oid"); + md5WithRSAField.setAccessible(true); + Class objectIdentifierClass = Class.forName(getObjectIdentifierModuleName()); + + Object md5WithRSAValue = md5WithRSAField.get(algorithmIdClass); + + Constructor algorithmIdConstr = algorithmIdClass.getConstructor(new Class[] {objectIdentifierClass}); + Object algorithmIdObject = algorithmIdConstr.newInstance(md5WithRSAValue); + + //info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo)); + Class certificateAlgorithmIdClass = Class.forName(getCertificateAlgorithmIdModuleName()); + Constructor certificateAlgorithmIdConstr = certificateAlgorithmIdClass.getConstructor(new Class[] {algorithmIdClass}); + Object certificateAlgorithmIdObject = certificateAlgorithmIdConstr.newInstance(algorithmIdObject); + methodSET.invoke(certInfoObject, getSetField(certInfoObject,"ALGORITHM_ID"), certificateAlgorithmIdObject); + + // Sign the cert to identify the algorithm that's used. + //X509CertImpl cert = new X509CertImpl(info); + Class x509CertImplClass = Class.forName(getX509CertImplModuleName()); + Constructor x509CertImplConstr = x509CertImplClass.getConstructor(new Class[] {certInfoClass}); + x509CertImplObject = x509CertImplConstr.newInstance(certInfoObject); + + //cert.sign(privkey, algorithm); + Method methoSIGN = x509CertImplObject.getClass().getMethod("sign", PrivateKey.class, String.class); + methoSIGN.invoke(x509CertImplObject, privkey,algorithm ); + + // Update the algorith, and resign. + //algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG); + Method methoGET = x509CertImplObject.getClass().getMethod("get", String.class); + String sig_alg = getSetField(x509CertImplObject,"SIG_ALG"); + + String certAlgoIdNameValue = getSetField(certificateAlgorithmIdObject,"NAME"); + String certAlgoIdAlgoValue = getSetField(certificateAlgorithmIdObject,"ALGORITHM"); + //info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo); + methodSET.invoke(certInfoObject, certAlgoIdNameValue +"."+ certAlgoIdAlgoValue, methoGET.invoke(x509CertImplObject, sig_alg)); + + //cert = new X509CertImpl(info); + x509CertImplObject = x509CertImplConstr.newInstance(certInfoObject); + //cert.sign(privkey, algorithm); + methoSIGN.invoke(x509CertImplObject, privkey,algorithm ); + } catch (SecurityException e) { + LOG.error("Could not generate X509 Certificate", e); + } catch (RuntimeException e){ + LOG.error("Could not generate X509 Certificate", e); + } catch (ReflectiveOperationException e) { + LOG.error("Could not generate X509 Certificate", e); + } + //return cert; + return (X509Certificate)x509CertImplObject; } + public static KeyPair generateKeyPair(String algorithm) throws NoSuchAlgorithmException { KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm); @@ -362,4 +444,76 @@ public class KeyStoreTestUtil { writer.close(); } } + + + private static String getX509CertInfoModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.X509CertInfo" + : "sun.security.x509.X509CertInfo"; + } + + private static String getX509CertifValidityModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateValidity" + : "sun.security.x509.CertificateValidity"; + } + + + private static String getX509X500NameModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.X500Name" + : "sun.security.x509.X500Name"; + } + + private static String getCertificateSerialNumberModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateSerialNumber" + : "sun.security.x509.CertificateSerialNumber"; + } + + private static String getCertificateSubjectNameModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateSubjectName" + : "sun.security.x509.CertificateSubjectName"; + } + + private static String getCertificateIssuerNameModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateIssuerName" + : "sun.security.x509.CertificateIssuerName"; + } + + private static String getCertificateX509KeyModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateX509Key" + : "sun.security.x509.CertificateX509Key"; + } + + private static String getCertificateVersionModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateVersion" + : "sun.security.x509.CertificateVersion"; + } + + + private static String getAlgorithmIdModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.AlgorithmId" + : "sun.security.x509.AlgorithmId"; + } + + private static String getObjectIdentifierModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.util.ObjectIdentifier" + : "sun.security.util.ObjectIdentifier"; + } + + private static String getCertificateAlgorithmIdModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.CertificateAlgorithmId" + : "sun.security.x509.CertificateAlgorithmId"; + } + + private static String getX509CertImplModuleName() { + return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.X509CertImpl" + : "sun.security.x509.X509CertImpl"; + } + + + private static String getSetField(Object obj, String setString ) throws ReflectiveOperationException, SecurityException{ + Field privateStringField = obj.getClass().getDeclaredField(setString); + privateStringField.setAccessible(true); + String fieldValue = (String) privateStringField.get(obj); + return fieldValue; + } + }