static void certReq()

in modules/jretools/src/main/java/org/apache/harmony/jretools/keytool/CSRGenerator.java [69:185]


    static void certReq(KeytoolParameters param) throws KeyStoreException,
            NoSuchAlgorithmException, UnrecoverableKeyException, IOException,
            InvalidKeyException, SignatureException, NoSuchProviderException,
            KeytoolException, CertificateException {

        KeyStore keyStore = param.getKeyStore();
        String alias = param.getAlias();

        if (!keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
            throw new KeytoolException(
                    "Failed to generate a certificate request. \n" + "Entry <"
                            + alias + "> is not a private key entry. ");
        }

        // get the existing certificate and keys associated with the alias
        X509Certificate cert = (X509Certificate) keyStore.getCertificate(param
                .getAlias());
        PrivateKey privateKey;
        try {
            privateKey = (PrivateKey) keyStore.getKey(param.getAlias(), param
                    .getKeyPass());
        } catch (NoSuchAlgorithmException e) {
            throw new NoSuchAlgorithmException(
                    "Cannot find the algorithm to recover the key. ", e);
        }
        PublicKey publicKey = cert.getPublicKey();

        Name distinguishedName;
        try {
            distinguishedName = new Name(cert.getSubjectDN().getName());
        } catch (IOException e) {
            throw (IOException) new IOException(
                    "Failed to generate a distinguished name. ").initCause(e);
        }

        SubjectPublicKeyInfo subjectPublicKeyInfo = null;
        try {
            subjectPublicKeyInfo = (SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1
                    .decode(publicKey.getEncoded());
        } catch (IOException e) {
            throw (IOException) new IOException(
                    "Failed to decode SubjectPublicKeyInfo. ").initCause(e);
        }

        // generate CertificationRequestInfo based on data taken from
        // the existing certificate.
        CertificationRequestInfo certReqInfo = new CertificationRequestInfo(
                cert.getVersion(), distinguishedName, subjectPublicKeyInfo,
                // attributes
                new Vector());
        byte[] infoEncoding = certReqInfo.getEncoded();

        // generate the signature
        String sigAlgName = (param.getSigAlg() != null) ? param.getSigAlg()
                : cert.getSigAlgName();

        Signature sig;
        String sigProvider = (param.getSigProvider() != null) ? param
                .getSigProvider() : param.getProvider();
        try {
            sig = (sigProvider != null) ? Signature.getInstance(sigAlgName,
                    sigProvider) : Signature.getInstance(sigAlgName);
        } catch (NoSuchAlgorithmException e) {
            throw new NoSuchAlgorithmException("The algorithm " + sigAlgName
                    + " is not found in the environment.", e);
        } catch (NoSuchProviderException e) {
            throw (NoSuchProviderException) new NoSuchProviderException(
                    "The provider " + sigProvider
                            + " is not found in the environment.").initCause(e);
        }

        try {
            sig.initSign(privateKey);
        } catch (InvalidKeyException e) {
            throw new InvalidKeyException(
                    "The private key used to generate the signature is invalid.",
                    e);
        }

        byte[] signatureValue;
        try {
            sig.update(infoEncoding, 0, infoEncoding.length);
            signatureValue = sig.sign();
        } catch (SignatureException e) {
            throw new SignatureException("Failed to sign the certificate. ", e);
        }

        // generating the request
        CertificationRequest certReq = new CertificationRequest(certReqInfo,
                new AlgorithmIdentifier(cert.getSigAlgOID()), signatureValue);
        byte[] certReqEncoding = certReq.getEncoded();

        OutputStream output;
        // if no file name is given, output to System.out
        String fileName = param.getFileName();
        if (fileName == null) {
            output = System.out;
        } else { // output to a file if the name is supplied
            File file = new File(fileName);
            // the file will be created if it doesn't already exist.
            // If it already exists and is not a file, then an IOException will
            // be thrown.
            file.createNewFile();

            output = new BufferedOutputStream(new FileOutputStream(file));
        }

        output.write("-----BEGIN NEW CERTIFICATE REQUEST-----\n".getBytes());
        output.write(Base64.encode(certReqEncoding, "ISO-8859-1").getBytes());
        output.write("\n-----END NEW CERTIFICATE REQUEST-----\n".getBytes());
        output.flush();

        if (param.isVerbose() && fileName != null) {
            System.out.println("The certificate request is stored in file <"
                    + fileName + ">.");
        }
    }