public static X509Certificate generateCertificate()

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;
  }