in gateway-util-common/src/main/java/org/apache/knox/gateway/util/X509CertificateUtil.java [70:279]
public static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm) {
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(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(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(BigInteger.class);
Object certificateSerialNumberObject = certificateSerialNumberConstr.newInstance(sn);
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "SERIAL_NUMBER"),
certificateSerialNumberObject);
// info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
try {
Class<?> certificateSubjectNameClass = Class.forName(getCertificateSubjectNameModuleName());
Constructor<?> certificateSubjectNameConstr = certificateSubjectNameClass
.getConstructor(x500NameClass);
Object certificateSubjectNameObject = certificateSubjectNameConstr
.newInstance(x500NameObject);
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "SUBJECT"),
certificateSubjectNameObject);
}
catch (InvocationTargetException ite) {
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "SUBJECT"),
x500NameObject);
}
// info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
try {
Class<?> certificateIssuerNameClass = Class.forName(getCertificateIssuerNameModuleName());
Constructor<?> certificateIssuerNameConstr = certificateIssuerNameClass
.getConstructor(x500NameClass);
Object certificateIssuerNameObject = certificateIssuerNameConstr.newInstance(x500NameObject);
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "ISSUER"),
certificateIssuerNameObject);
}
catch (InvocationTargetException ite) {
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "ISSUER"),
x500NameObject);
}
// info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
Class<?> certificateX509KeyClass = Class.forName(getCertificateX509KeyModuleName());
Constructor<?> certificateX509KeyConstr = certificateX509KeyClass
.getConstructor(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(int.class);
Constructor<?> certificateVersionConstr0 = certificateVersionClass.getConstructor();
Object certInfoObject0 = certificateVersionConstr0.newInstance();
Field v3IntField = certInfoObject0.getClass().getDeclaredField("V3");
v3IntField.setAccessible(true);
int fValue = 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("RSAEncryption_oid");
md5WithRSAField.setAccessible(true);
Class<?> objectIdentifierClass = Class.forName(getObjectIdentifierModuleName());
Object md5WithRSAValue = md5WithRSAField.get(algorithmIdClass);
Constructor<?> algorithmIdConstr = algorithmIdClass.getConstructor(objectIdentifierClass);
Object algorithmIdObject = algorithmIdConstr.newInstance(md5WithRSAValue);
// info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
Class<?> certificateAlgorithmIdClass = Class.forName(getCertificateAlgorithmIdModuleName());
Constructor<?> certificateAlgorithmIdConstr = certificateAlgorithmIdClass
.getConstructor(algorithmIdClass);
Object certificateAlgorithmIdObject = certificateAlgorithmIdConstr
.newInstance(algorithmIdObject);
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "ALGORITHM_ID"),
certificateAlgorithmIdObject);
// Set the SAN extension
Class<?> generalNameInterfaceClass = Class.forName(getGeneralNameInterfaceModuleName());
Class<?> generalNameClass = Class.forName(getGeneralNameModuleName());
Constructor<?> generalNameConstr = generalNameClass.getConstructor(generalNameInterfaceClass);
// GeneralNames generalNames = new GeneralNames();
Class<?> generalNamesClass = Class.forName(getGeneralNamesModuleName());
Constructor<?> generalNamesConstr = generalNamesClass.getConstructor();
Object generalNamesObject = generalNamesConstr.newInstance();
Method generalNamesAdd = generalNamesObject.getClass().getMethod("add", generalNameClass);
Class<?> dnsNameClass = Class.forName(getDNSNameModuleName());
Constructor<?> dnsNameConstr = dnsNameClass.getConstructor(String.class);
boolean generalNameAdded = false;
// Pull the hostname out of the DN
String hostname = dn.split(",", 2)[0].split("=", 2)[1];
if("localhost".equals(hostname)) {
// Add short hostname
String detectedHostname = InetAddress.getLocalHost().getHostName();
if (Character.isAlphabetic(detectedHostname.charAt(0))) {
// DNSName dnsName = new DNSName(detectedHostname);
Object dnsNameObject = dnsNameConstr.newInstance(detectedHostname);
// GeneralName generalName = new GeneralName(dnsName);
Object generalNameObject = generalNameConstr.newInstance(dnsNameObject);
// generalNames.add(generalName);
generalNamesAdd.invoke(generalNamesObject, generalNameObject);
generalNameAdded = true;
}
// Add fully qualified hostname
String detectedFullyQualifiedHostname = InetAddress.getLocalHost().getCanonicalHostName();
if (Character.isAlphabetic(detectedFullyQualifiedHostname.charAt(0))) {
// DNSName dnsName = new DNSName(detectedFullyQualifiedHostname);
Object fullyQualifiedDnsNameObject = dnsNameConstr.newInstance(detectedFullyQualifiedHostname);
// GeneralName generalName = new GeneralName(fullyQualifiedDnsNameObject);
Object fullyQualifiedGeneralNameObject = generalNameConstr.newInstance(fullyQualifiedDnsNameObject);
// generalNames.add(fullyQualifiedGeneralNameObject);
generalNamesAdd.invoke(generalNamesObject, fullyQualifiedGeneralNameObject);
generalNameAdded = true;
}
}
if (Character.isAlphabetic(hostname.charAt(0))) {
// DNSName dnsName = new DNSName(hostname);
Object dnsNameObject = dnsNameConstr.newInstance(hostname);
// GeneralName generalName = new GeneralName(dnsName);
Object generalNameObject = generalNameConstr.newInstance(dnsNameObject);
// generalNames.add(generalName);
generalNamesAdd.invoke(generalNamesObject, generalNameObject);
generalNameAdded = true;
}
if (generalNameAdded) {
// SubjectAlternativeNameExtension san = new SubjectAlternativeNameExtension(generalNames);
Class<?> subjectAlternativeNameExtensionClass = Class.forName(getSubjectAlternativeNameExtensionModuleName());
Constructor<?> subjectAlternativeNameExtensionConstr = subjectAlternativeNameExtensionClass.getConstructor(generalNamesClass);
Object subjectAlternativeNameExtensionObject = subjectAlternativeNameExtensionConstr.newInstance(generalNamesObject);
// CertificateExtensions certificateExtensions = new CertificateExtensions();
Class<?> certificateExtensionsClass = Class.forName(getCertificateExtensionsModuleName());
Constructor<?> certificateExtensionsConstr = certificateExtensionsClass.getConstructor();
Object certificateExtensionsObject = certificateExtensionsConstr.newInstance();
// certificateExtensions.set(san.getExtensionId().toString(), san);
Method getExtensionIdMethod = subjectAlternativeNameExtensionObject.getClass().getMethod("getExtensionId");
String sanExtensionId = getExtensionIdMethod.invoke(subjectAlternativeNameExtensionObject).toString();
Method certificateExtensionsSet = certificateExtensionsObject.getClass().getMethod("set", String.class, Object.class);
certificateExtensionsSet.invoke(certificateExtensionsObject, sanExtensionId, subjectAlternativeNameExtensionObject);
// info.set(X509CertInfo.EXTENSIONS, certificateExtensions);
methodSET.invoke(certInfoObject, getSetField(certInfoObject, "EXTENSIONS"), certificateExtensionsObject);
}
// Sign the cert to identify the algorithm that's used.
// X509CertImpl cert = new X509CertImpl(info);
Class<?> x509CertImplClass = Class.forName(getX509CertImplModuleName());
Constructor<?> x509CertImplConstr = x509CertImplClass.getConstructor(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 (Exception e) {
LOG.failedToGenerateCertificate(e);
}
return (X509Certificate) x509CertImplObject;
}