You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/08/07 08:51:06 UTC

svn commit: r429254 - /incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/

Author: mloenko
Date: Sun Aug  6 23:51:05 2006
New Revision: 429254

URL: http://svn.apache.org/viewvc?rev=429254&view=rev
Log:
applied patch for HARMONY-1067
[tools] Keytool - added certificate signing request (CSR) generation, topic help, usage of specific providers for various purposes

Added:
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CSRGenerator.java
Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/ArgumentsParser.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CRLManager.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertChainVerifier.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertImporter.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/EntryManager.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/HelpPrinter.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreCertPrinter.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreLoaderSaver.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeytoolParameters.java
    incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/Main.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/ArgumentsParser.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/ArgumentsParser.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/ArgumentsParser.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/ArgumentsParser.java Sun Aug  6 23:51:05 2006
@@ -91,6 +91,18 @@
 
     final static String sProvider = "-provider";
 
+    final static String sCertProvider = "-certprovider";
+    
+    final static String sKeyProvider = "-keyprovider";
+    
+    final static String sMdProvider = "-mdprovider";
+    
+    final static String sSigProvider = "-sigprovider";
+    
+    final static String sKsProvider = "-ksprovider";
+    
+    final static String sConvKsProvider = "-convprovider";
+    
     final static String sStorepass = "-storepass";
 
     final static String sAlias = "-alias";
@@ -232,6 +244,9 @@
                 }
                 if (args[i].compareToIgnoreCase(sHelp) == 0) {
                     param.setCommand(Command.HELP);
+                    if (args.length == i + 2){
+                        param.setHelpTopic(args[++i]);
+                    }
                     continue;
                 }
 
@@ -246,6 +261,30 @@
                 }
                 if (args[i].compareToIgnoreCase(sProvider) == 0) {
                     param.setProvider(args[++i]);
+                    continue;
+                }
+                if (args[i].compareToIgnoreCase(sCertProvider) == 0) {
+                    param.setCertProvider(args[++i]);
+                    continue;
+                }
+                if (args[i].compareToIgnoreCase(sKeyProvider) == 0) {
+                    param.setKeyProvider(args[++i]);
+                    continue;
+                }
+                if (args[i].compareToIgnoreCase(sMdProvider) == 0) {
+                    param.setMdProvider(args[++i]);
+                    continue;
+                }
+                if (args[i].compareToIgnoreCase(sSigProvider) == 0) {
+                    param.setSigProvider(args[++i]);
+                    continue;
+                }
+                if (args[i].compareToIgnoreCase(sKsProvider) == 0) {
+                    param.setKsProvider(args[++i]);
+                    continue;
+                }
+                if (args[i].compareToIgnoreCase(sConvKsProvider) == 0) {
+                    param.setConvKsProvider(args[++i]);
                     continue;
                 }
                 if (args[i].compareToIgnoreCase(sAlias) == 0) {

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CRLManager.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CRLManager.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CRLManager.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CRLManager.java Sun Aug  6 23:51:05 2006
@@ -34,9 +34,10 @@
 public class CRLManager {
     /**
      * Checks if the certificate given in the file is contained in the CRL which
-     * is stored in the certstore. If the file name is not given, stdin is used.
+     * is stored in the file. If the file name is not given, stdin is used.
      * File with CRL and the checked certificate file are specified in param.
      * 
+     * @return true if found at least one revoked certifiacte
      * @param param
      * @throws KeytoolException
      * @throws IOException
@@ -46,13 +47,18 @@
      * @throws FileNotFoundException
      * @throws NoSuchAlgorithmException 
      */
-    static void checkRevoked(KeytoolParameters param) throws FileNotFoundException,
-            CertificateException, NoSuchProviderException, CRLException,
-            IOException, KeytoolException, NoSuchAlgorithmException {
+    static boolean checkRevoked(KeytoolParameters param)
+            throws FileNotFoundException, CertificateException,
+            NoSuchProviderException, CRLException, IOException,
+            KeytoolException, NoSuchAlgorithmException {
 
-        String providerName = param.getProvider();
+        String provider = param.getProvider();
+        String certProvider = (param.getCertProvider() != null) ? param
+                .getCertProvider() : provider;
+        String mdProvider = (param.getMdProvider() != null) ? param
+                .getMdProvider() : provider;
         // firstly, get CRLs from the file 
-        Collection crls = CertReader.readCRLs(param.getCrlFile(), providerName);
+        Collection crls = CertReader.readCRLs(param.getCrlFile(), certProvider);
         // quit, if couldn't read anything
         if (crls.isEmpty()) {
             throw new CRLException("Failed to generate a CRL from the input. ");
@@ -67,33 +73,34 @@
         }
 
         boolean foundRevoked = false;
-        
+
         // search in the CRLs for revocations of the certificates
         Iterator crlIter = crls.iterator();
         while (crlIter.hasNext()) {
             X509CRL crl = (X509CRL) crlIter.next();
             Iterator certIter = certs.iterator();
-            while (certIter.hasNext()){
-                X509Certificate cert = (X509Certificate)certIter.next();
-                X509CRLEntry entry = crl.getRevokedCertificate(cert); 
+            while (certIter.hasNext()) {
+                X509Certificate cert = (X509Certificate) certIter.next();
+                X509CRLEntry entry = crl.getRevokedCertificate(cert);
                 if (entry != null) {
                     System.out.println("The certificate ...");
-                    KeyStoreCertPrinter.printX509CertDetailed(cert, providerName);
+                    KeyStoreCertPrinter.printX509CertDetailed(cert, mdProvider);
                     System.out.println("... is revoked on "
                             + entry.getRevocationDate() + "\n");
                     foundRevoked = true;
                     continue;
-                } 
+                }
             }
         }
-        
-        if (certs.size() == 1 && !foundRevoked){
+
+        if (certs.size() == 1 && !foundRevoked) {
             System.out.println("The certificate ...");
             KeyStoreCertPrinter.printX509CertDetailed((X509Certificate) certs
-                    .iterator().next(), providerName);
+                    .iterator().next(), mdProvider);
             System.out.println("... is not found in CRLs given");
-        } else if (!foundRevoked){
+        } else if (!foundRevoked) {
             System.out.println("The certificates are not found in CRLs given");
         }
+        return foundRevoked;
     }
 }

Added: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CSRGenerator.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CSRGenerator.java?rev=429254&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CSRGenerator.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CSRGenerator.java Sun Aug  6 23:51:05 2006
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tools.keytool;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Vector;
+
+import org.apache.harmony.luni.util.Base64;
+import org.apache.harmony.security.pkcs10.CertificationRequest;
+import org.apache.harmony.security.pkcs10.CertificationRequestInfo;
+import org.apache.harmony.security.x501.Name;
+import org.apache.harmony.security.x509.AlgorithmIdentifier;
+import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
+
+/**
+ * Class for generating X.509 Certificate Signing Requests (CSRs). The generated
+ * certificate request is printed to a file, if its name is supplied in param,
+ * or otherwise printed to stdout.
+ */
+public class CSRGenerator {
+    /**
+     * Generates a Certificate Signing Request (CSR). The request is generated
+     * based on data taken from keystore entry associated with alias given in
+     * parameter param. The certificate request is printed to a file, if its
+     * name is supplied in param, or otherwise printed to stdout.
+     * 
+     * @param param
+     * @throws KeyStoreException
+     * @throws UnrecoverableKeyException
+     * @throws NoSuchAlgorithmException
+     * @throws IOException
+     * @throws InvalidKeyException
+     * @throws SignatureException
+     * @throws NoSuchProviderException
+     * @throws KeytoolException 
+     * @throws CertificateException 
+     */
+    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 + ">.");
+        }
+    }
+}
+

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertChainVerifier.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertChainVerifier.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertChainVerifier.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertChainVerifier.java Sun Aug  6 23:51:05 2006
@@ -24,11 +24,13 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.PublicKey;
+import java.security.SignatureException;
 import java.security.cert.CertPathBuilder;
 import java.security.cert.CertPathBuilderException;
 import java.security.cert.CertPathBuilderResult;
 import java.security.cert.CertStore;
 import java.security.cert.CertStoreException;
+import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CollectionCertStoreParameters;
 import java.security.cert.PKIXBuilderParameters;
@@ -38,6 +40,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -51,7 +54,8 @@
  * certificate chains.
  */
 public class CertChainVerifier {
-    private final static String strFailed = "Failed to build a certificate chain from reply.\n";
+    private final static String strFailed =
+        "Failed to build a certificate chain from reply.\n";
 
     /**
      * A cerificate chain is built by looking up the certificate of the issuer
@@ -61,12 +65,147 @@
      * certificate path is built in the same way as in import operation. If an
      * error occurs the flow is not stopped but an attempt to continue is made.
      * The results of the verification are printed to stdout.
+     * 
+     * @param param
+     * @throws NoSuchAlgorithmException
+     * @throws NoSuchProviderException
+     * @throws FileNotFoundException
+     * @throws CertificateException
+     * @throws IOException
+     * @throws KeytoolException
+     * @throws KeyStoreException 
      */
-    static void verifyChain(KeytoolParameters param){
-        // TODO
-        throw new RuntimeException("Method is not implemented yet.");
+    static void verifyChain(KeytoolParameters param)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            FileNotFoundException, CertificateException, IOException,
+            KeytoolException, KeyStoreException {
+
+        try {
+            if (param.getCrlFile() != null) {
+                CRLManager.checkRevoked(param);
+            } else {
+                System.out
+                        .println("Certificates revocation status is not checked, "
+                                + "CRL file name is not supplied.");
+            }
+        } catch (Exception e) {
+            System.out.println(e);
+            System.out.println("Failed to check revocation status.");
+        }
+
+        String provider = param.getProvider();
+        String certProvider = (param.getCertProvider() != null) ? param
+                .getCertProvider() : provider;
+        String sigProvider = (param.getSigProvider() != null) ? param
+                .getSigProvider() : provider;
+        String mdProvider = (param.getMdProvider() != null) ? param
+                .getMdProvider() : provider;
+
+        // Don't catch exceptions here, because if exception is
+        // thrown here, there is no need to proceed.
+        Collection<X509Certificate> certs = CertReader.readCerts(param
+                .getFileName(), false, certProvider);
+        X509Certificate[] ordered = orderChain(certs);
+
+        try {
+            for (int i = 0; i < ordered.length - 1; i++) {
+                checkSignature(ordered[i], ordered[i + 1].getPublicKey(),
+                        sigProvider, mdProvider);
+            }
+            // check the signature of the last element of the ordered chain
+            boolean lastSignChecked = findIssuerAndCheckSignature(param
+                    .getKeyStore(), ordered[ordered.length - 1], sigProvider,
+                    mdProvider);
+            // if haven't found issuer's certificate in main keystore
+            if (!lastSignChecked) {
+                if (param.isTrustCACerts()) {
+                    // make the search and check again
+                    lastSignChecked = findIssuerAndCheckSignature(param
+                            .getCacerts(), ordered[ordered.length - 1],
+                            sigProvider, mdProvider);
+                }
+
+                if (!lastSignChecked) {
+                    System.out
+                            .println("Failed to find the issuer's certificate.");
+                    System.out
+                            .println("Failed to check the signature of certificate:");
+                    KeyStoreCertPrinter.printX509CertDetailed(
+                            ordered[ordered.length - 1], mdProvider);
+                }
+            }
+        } catch (Exception e) {
+            System.out.println(e);
+            System.out.println("Signature check failed.");
+        }
+
+        try {
+            buildCertPath(param, ordered[0]);
+
+            // won't come here if exception is thrown
+            System.out.println("Certificate path is built successfully.");
+        } catch (Exception e) {
+            // Exception's own message contains strFailed string,
+            // but its cause can be more informative here.
+            System.out.println(e.getCause());
+            System.out.println("Failed to build a certificate path.");
+        }
+        System.out.println("Verification complete.");
+    }
+
+    // Checks the signature, prints the result. Returns true if
+    // signature verification process succeeds (no exceptions or
+    // SignatureException thrown)
+    private static boolean checkSignature(X509Certificate cert,
+            PublicKey pubKey, String sigProvider, String mdProvider)
+            throws CertificateEncodingException, NoSuchAlgorithmException,
+            NoSuchProviderException {
+        try {
+            if (sigProvider == null) {
+                cert.verify(pubKey);
+            } else {
+                cert.verify(pubKey, sigProvider);
+            }
+        } catch (SignatureException e) {
+            System.out.println("The signature is incorrect for certificate: ");
+            KeyStoreCertPrinter.printX509CertDetailed(cert, mdProvider);
+        } catch (Exception e) {
+            System.out.println(e);
+            System.out
+                    .println("Signature verification failed for certificate: ");
+            KeyStoreCertPrinter.printX509CertDetailed(cert, mdProvider);
+            return false;
+        }
+        return true;
+    }
+
+    // Searches for cert issuer's certificate in keyStore and checks if
+    // cert was signed using the private key corresponding to public key
+    // wrapped into the found certificate.
+    private static boolean findIssuerAndCheckSignature(KeyStore keyStore,
+            X509Certificate cert, String sigProvider, String mdProvider)
+            throws KeyStoreException, CertificateEncodingException,
+            NoSuchAlgorithmException, NoSuchProviderException {
+
+        Enumeration keyStoreAliases = keyStore.aliases();
+        while (keyStoreAliases.hasMoreElements()) {
+            // get a certificate from keyStore
+            X509Certificate nextKScert = (X509Certificate) keyStore
+                    .getCertificate((String) keyStoreAliases.nextElement());
+            if (nextKScert == null) {
+                continue;
+            }
+            if (Arrays.equals(cert.getIssuerX500Principal().getEncoded(),
+                    nextKScert.getSubjectX500Principal().getEncoded())) {
+                checkSignature(cert, keyStore.getCertificate(
+                        (String) keyStoreAliases.nextElement()).getPublicKey(),
+                        sigProvider, mdProvider);
+                return true;
+            }
+        }
+        return false;
     }
-    
+
     /**
      * Builds a certificate chain from the given X509Certificate newCert to a
      * self-signed root CA whose certificate is contained in the keystore or
@@ -102,8 +241,11 @@
         Collection trustedCerts = trustedSeparated[1];
         Collection selfSignedTAsCerts = trustedSeparated[2];
 
-        CertPathBuilderResult bldResult = buildCertPath(param.getProvider(),
-                newCert, selfSignedTAs, trustedCerts);
+        String certProvider = (param.getCertProvider() != null) ? param
+                .getCertProvider() : param.getProvider();
+
+        CertPathBuilderResult bldResult = buildCertPath(certProvider, newCert,
+                selfSignedTAs, trustedCerts);
 
         // The validation of the certificate path.
         // According to black-box testing, RI keytool doesn't perform
@@ -177,15 +319,16 @@
         Set selfSignedTAs = (Set) trustedSeparated[0];
         Collection trustedCerts = trustedSeparated[1];
 
-        return buildCertPath(param.getProvider(), newCert, selfSignedTAs,
-                trustedCerts);
+        String certProvider = (param.getCertProvider() != null) ? param
+                .getCertProvider() : param.getProvider();
+
+        return buildCertPath(certProvider, newCert, selfSignedTAs, trustedCerts);
     }
 
-    
     // Build a certificte chain up to the self-signed trust anchor, based on
     // trusted certificates given.
     // 
-    // @param provider
+    // @param certProvider
     // @param newCert
     //            is a certificate to build chain for.
     // @param selfSignedTAs
@@ -193,7 +336,7 @@
     // @param trustedCerts
     //            elements of trustedCerts are used as chain links It can be
     //            null if no intermediate certifictaes allowed.
-    private static CertPathBuilderResult buildCertPath(String provider,
+    private static CertPathBuilderResult buildCertPath(String certProvider,
             X509Certificate newCert, Set selfSignedTAs, Collection trustedCerts)
             throws NoSuchAlgorithmException, CertificateException, IOException,
             KeyStoreException, CertPathBuilderException, KeytoolException,
@@ -218,7 +361,7 @@
 
         if (trustedCerts != null) {
             CollectionCertStoreParameters trustedCertsCCSParams = 
-                    new CollectionCertStoreParameters(trustedCerts);
+                new CollectionCertStoreParameters(trustedCerts);
             CertStore trustedCertStore;
             try {
                 trustedCertStore = CertStore.getInstance("Collection",
@@ -236,17 +379,17 @@
 
         CertPathBuilder cpBuilder;
         try {
-            if (provider == null) {
+            if (certProvider == null) {
                 cpBuilder = CertPathBuilder.getInstance(strPKIX);
             } else {
-                cpBuilder = CertPathBuilder.getInstance(strPKIX, provider);
+                cpBuilder = CertPathBuilder.getInstance(strPKIX, certProvider);
             }
         } catch (NoSuchAlgorithmException e) {
             throw new NoSuchAlgorithmException("The algorithm " + strPKIX
                     + " is not available.", e);
         } catch (NoSuchProviderException e) {
             throw (NoSuchProviderException) new NoSuchProviderException(
-                    "The provider " + provider
+                    "The certProvider " + certProvider
                             + " is not found in the environment.").initCause(e);
         }
 
@@ -263,7 +406,6 @@
         return bldResult;
     }
 
-    
     // Separates the trusted certificates from keystore (and cacerts file if
     // "-trustcacerts" option is specified) into self-signed certificate
     // authority certificates and non-self-signed certifcates.
@@ -339,7 +481,7 @@
                 }
             }
         }
-        
+
         // if "-trustcacerts" is specified, add CAs from cacerts
         if (trustCaCerts) {
             KeyStore cacertsFile = null;
@@ -505,7 +647,7 @@
 
         return ordered;
     }
-    
+
     // orders a chain without a starting element given
     static X509Certificate[] orderChain(Collection<X509Certificate> certs)
             throws KeytoolException {
@@ -543,8 +685,7 @@
 
         return orderChain(certsList, certsList.get(startPos).getPublicKey());
     }
-            
-    
+
     /**
      * Checks if the X509Certificate cert is contained as a trusted certificate
      * entry in keystore and possibly cacerts file (if "-trustcacerts" option is

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertImporter.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertImporter.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertImporter.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/CertImporter.java Sun Aug  6 23:51:05 2006
@@ -68,6 +68,8 @@
         String alias = param.getAlias();
         KeyStore keyStore = param.getKeyStore();
         boolean contains = keyStore.containsAlias(alias);
+        String certProvider = (param.getCertProvider() != null) ? param
+                .getCertProvider() : param.getProvider();
 
         // if the alias already exists, try to import the certificate as
         // a cert reply
@@ -76,13 +78,13 @@
                         KeyStore.PrivateKeyEntry.class)) {
             // read the certificates
             Collection<X509Certificate> certCollection = CertReader.readCerts(
-                    param.getFileName(), false, param.getProvider());
+                    param.getFileName(), false, certProvider);
 
             importReply(param, certCollection);
         } else if (!contains) { // import a trusted certificate
             // read the certificate
             Collection<X509Certificate> trustedCert = CertReader.readCerts(
-                    param.getFileName(), true, param.getProvider());
+                    param.getFileName(), true, certProvider);
 
             importTrusted(param, trustedCert.iterator().next());
         } else {// if the existing entry is not a private key entry
@@ -234,8 +236,10 @@
                 } catch (Exception e) {
                     // if the certificate chain cannot be built
                     // print it and ask if it should be trusted or not.
-                    KeyStoreCertPrinter.printX509CertDetailed(newCert, param
-                            .getProvider());
+                    String mdProvider = (param.getMdProvider() != null) ? param
+                            .getMdProvider() : param.getProvider();
+                    KeyStoreCertPrinter.printX509CertDetailed(newCert,
+                            mdProvider);
                     addIt = ArgumentsParser.getConfirmation(
                             "Trust this certificate? [no] ", false);
                 }
@@ -297,11 +301,15 @@
             // If couldn't build full cert path for some reason,
             // ask user if the certificate should be trusted.
             System.out.println("Top-level certificate in the reply chain:\n");
-            KeyStoreCertPrinter.printX509CertDetailed(lastInChain, param
-                    .getProvider());
-            needAddChain = ArgumentsParser.getConfirmation("... is not trusted.\n"
-                    + "Do you still want to install the reply? [no]:  ", false);
-            
+            String mdProvider = (param.getMdProvider() != null) ? param
+                    .getMdProvider() : param.getProvider();
+            KeyStoreCertPrinter.printX509CertDetailed(lastInChain, mdProvider);
+            needAddChain = ArgumentsParser
+                    .getConfirmation(
+                            "... is not trusted.\n"
+                                    + "Do you still want to install the reply? [no]:  ",
+                            false);
+
             if (!needAddChain) {
                 System.out.println("The certificate reply is " + "not "
                         + "installed into the keystore.");

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/EntryManager.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/EntryManager.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/EntryManager.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/EntryManager.java Sun Aug  6 23:51:05 2006
@@ -33,8 +33,8 @@
  */
 public class EntryManager {
     /**
-     * Copies the private key and the certificate chain from the keystore entry
-     * identifiad by given alias into a newly created one with given destination
+     * Copies the key and the certificate chain (if any) from the keystore entry
+     * identified by given alias into a newly created one with given destination
      * alias. alias and destination alias are specified in param.
      * 
      * @param param

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/HelpPrinter.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/HelpPrinter.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/HelpPrinter.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/HelpPrinter.java Sun Aug  6 23:51:05 2006
@@ -20,11 +20,302 @@
  * Class for printing help messages .
  */
 public class HelpPrinter {
+    private static StringBuffer message;
+
+    final static String certReq = "-certreq";
+    final static String checkCRL = "-checkcrl";
+    final static String convert = "-convert";
+    final static String delete = "-delete";
+    final static String export = "-export";
+    final static String genKey = "-genkey";
+    final static String help = "-help";
+    final static String sImport = "-import";
+    final static String keyClone = "-keyclone";
+    final static String keyPasswd = "-keypasswd";
+    final static String list = "-list";
+    final static String printCert = "-printcert";
+    final static String selfCert = "-selfcert";
+    final static String storePasswd = "-storepasswd";
+    final static String verify = "-verify";
+    
+    final static String keyStore = " {-keystore <keystore_path>}";
+    final static String storeType = " {-storetype <store_type>}";
+    final static String keyPass = " {-keypass <key_password>}";
+    final static String oldKeyPass = " {-keypass <old_key_password>}";
+    final static String storePass = " {-storepass <store_password>}";
+    final static String provider = " {-provider <provider_name>}";
+    final static String certReqFile = " {-file <csr_file>}";
+    final static String certFile = " {-file <certificate_file>}";
+    final static String keyAlg = " {-keyalg <key_algorithm>}";
+    final static String sigAlg = " {-sigalg <signature_algorithm>}";
+    final static String keySize = " {-keysize <key_size>}";
+    final static String alias = " {-alias <alias>}";
+    final static String dName = " {-dname <X500_distinguished_dname>}";
+    final static String validity = " {-validity <validity_period>}";
+    final static String verbose = " {-v}";
+    final static String verboseOrRfc = " {-rfc | -v}";
+    final static String javaOption = " {-J<javaoption>}";
+    final static String crlFile = " {-crlfile <crl_file>}";
+    final static String convKeyStore = " {-convkeystore <result_store>}";
+    final static String convStoreType = " {-convtype <result_type>}";
+    final static String convStorePass = " {-convstorepass <result_store_pass>}";
+    final static String convKeys = " {-convkeys}";
+    final static String ca = " {-ca}";
+    final static String secretKey = " {-secretkey}";
+    final static String trustCAcerts = " {-trustcacerts}";
+    final static String noPrompt = " {-noprompt}";
+    final static String cacerts = " {-cacerts <cacerts_path>}";
+    final static String cacertsPass = " {-cacertspass <cacerts_password>}";
+    final static String x509version = " {-x509version <X509_version>}";
+    final static String dest = " {-dest <dest_alias>}";
+    final static String sNew = " {-new <new_password>}";
+    final static String issuer = " {-issuer <issuer_alias>}";
+    final static String issuerPass = " {-issuerpass <issuer_password>}";
+    final static String serialNum = " {-certserial <cert_serial_number>}";
+    final static String newLine = "\n";
+    final static String doubleNewLine = "\n\n";
+    final static String ksTypePassVProvCacerts = newLine + keyStore + storeType
+            + newLine + storePass + verbose + provider + newLine + cacerts
+            + cacertsPass + doubleNewLine;
+
     /**
      * Prints the help message.
      */
     static void printHelp() {
-        // TODO
-        System.out.println("Help message here");
+        if (message == null) {
+            message = new StringBuffer();
+            String tab = "\t";
+            String doubleTab = "\t\t";
+            String tripleTab = "\t\t\t";
+            message.append("\nKeytool usage:\n");
+            message.append("keytool {-<command_name>} {-<command_option>}"
+                    + " {<option_value>}... -J<java_option>\n\n");
+            message.append("Known commands:\n");
+            message.append(tab + certReq + doubleTab
+                    + "Generate certificate request\n");
+            message.append(tab + checkCRL + doubleTab
+                    + "Check certificates revocation status\n");
+            message.append(tab + convert + doubleTab
+                    + "Convert keystore to another format\n");
+            message.append(tab + delete + tripleTab
+                    + "Remove entry from keystore\n");
+            message.append(tab + export + tripleTab
+                    + "Export certificate to a file or stdout\n");
+            message.append(tab + genKey + tripleTab
+                    + "Secret key or key pair generation\n");
+            message.append(tab + help + tripleTab
+                    + "This help message or help on a command\n");
+            message.append(tab + sImport + tripleTab
+                    + "Import a certificate (chain) or a CSR reply\n");
+            message.append(tab + keyClone + doubleTab
+                    + "Duplicate a key entry\n");
+            message.append(tab + keyPasswd + doubleTab
+                    + "Change key password\n");
+            message.append(tab + printCert + doubleTab
+                    + "Print to stdout a certificate from file\n");
+            message.append(tab + selfCert + doubleTab
+                    + "Generate a self-signed certificate "
+                    + "with existing key\n");
+            message.append(tab + storePasswd + doubleTab
+                    + "Change keystore password\n");
+            message.append(tab + verify + tripleTab
+                    + "Verify a certificate chain\n");
+
+            message.append("\nHelp usage:\n");
+            message.append("keytool -help {<command_name>}\n");
+            message.append("E.g.:\t keytool -help genkey\n");
+        }
+        System.out.println(message);
     }
+
+    static void topicHelp(String topic) {
+        StringBuffer topicMsg = new StringBuffer();
+        if (topic.equalsIgnoreCase("certreq")) {
+            topicMsg.append(" Generates a Certificate Signing Request "
+                    + "(CSR). The request is generated\n");
+            topicMsg.append(" based on data taken from keystore entry "
+                    + "associated with alias given.\n");
+            topicMsg.append(" The certificate request "
+                    + "is printed to a file, if its name is supplied\n");
+            topicMsg.append(" or otherwise printed to stdout.\n");
+            topicMsg.append("\ncertreq Usage:\n");
+            topicMsg.append(certReq + alias + certReqFile + newLine + sigAlg
+                    + keyPass + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("checkcrl")) {
+            topicMsg.append(" Checks if the certificate given in the file "
+                    + "is contained in the CRL which\n");
+            topicMsg.append(" is stored in the CRL file. If the file "
+                    + "name is not given, stdin is used.\n");
+            topicMsg.append("\ncheckcrl Usage:\n");
+            topicMsg.append(checkCRL + certFile + crlFile
+                    + ksTypePassVProvCacerts);
+        } else if (topic.equalsIgnoreCase("convert")) {
+            topicMsg.append(" Converts keystore to another format.\n"
+                    + " If \"-convkeys\" option has been specified, "
+                    + "an attempt to convert\n key entries is performed."
+                    + " Only entries with password equal to \n"
+                    + " keystore password are converted.\n");
+            topicMsg.append("\nconvert Usage:\n");
+            topicMsg.append(convert + convStoreType + convKeyStore + newLine
+                    + convStorePass + convKeys + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("delete")) {
+            topicMsg.append(" Removes from the keystore the entry "
+                    + "associated with alias.\n");
+            topicMsg.append("\ndelete Usage:\n");
+            topicMsg.append(delete + alias + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("export")) {
+            topicMsg.append(" Reads an X.509 certificate associated with "
+                    + "alias and prints it into the\n");
+            topicMsg.append(" given file. If The file");
+            topicMsg.append(" name is not given, the certificate is printed\n"
+                    + " to stdout.\n");
+            topicMsg.append("\nexport Usage:\n");
+            topicMsg.append(export + verboseOrRfc + alias + certFile
+                    + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("genkey")) {
+            topicMsg.append(" Generates a key pair or a secret key."
+                    + " Key pair is composed of a private\n");
+            topicMsg.append(" and a public key. Wraps the public key "
+                    + "into a self-signed X.509\n");
+            topicMsg.append(" (v1, v2, v3) certificate and puts the "
+                    + "certificate into a single-element\n");
+            topicMsg.append(" certificate chain or signs the certificate "
+                    + "with private key from another\n");
+            topicMsg.append(" key entry and adds its chain to the newly "
+                    + "generated certificate . After\n");
+            topicMsg.append(" that adds to the keystore a new "
+                    + "entry containing the generated\n");
+            topicMsg.append(" private key and the chain. If a secret key is "
+                    + "generated it is put into a\n");
+            topicMsg
+                    .append(" secret key entry, with null certificate chain.\n");
+            topicMsg
+                    .append(" If \"-ca\" option is specified, generated certificate\n");
+            topicMsg
+                    .append(" will can be used for signing another certifictes.\n");
+            topicMsg
+                    .append(" If \"-secretkey\" option is specified, a secret key will.\n");
+            topicMsg
+                    .append(" be generated instead of key pair and a certificate which\n");
+            topicMsg.append(" are generated by default. \n");
+
+            topicMsg.append("\ngenkey usage\n");
+            topicMsg.append(genKey + alias + keyAlg + newLine + keySize
+                    + sigAlg + newLine + validity + dName + newLine
+                    + x509version + ca + serialNum + newLine + secretKey
+                    + keyPass + newLine + issuer + issuerPass
+                    + ksTypePassVProvCacerts);
+        } else if (topic.equalsIgnoreCase("help")) {
+            printHelp();
+        } else if (topic.equalsIgnoreCase("import")) {
+            topicMsg.append(" Reads an X.509 certificate or a PKCS#7 "
+                    + "formatted certificate chain from\n");
+            topicMsg.append(" the file specified in param and puts it "
+                    + "into the entry identified by the\n");
+            topicMsg.append(" supplied alias. If the input file is "
+                    + "not specified, the certificates are\n");
+            topicMsg.append(" read from the standard input.\n");
+            topicMsg.append("\nimport Usage:\n");
+            topicMsg.append(sImport + alias + certFile + newLine + noPrompt
+                    + trustCAcerts + newLine + keyPass + cacerts + newLine
+                    + cacertsPass + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("keyclone")) {
+            topicMsg.append(" Copies the key and the certificate "
+                    + "chain (if any) from the keystore entry\n");
+            topicMsg.append(" identified by given alias into a newly "
+                    + "created one with given destination.\n");
+            topicMsg.append("\nkeyclone Usage:\n");
+            topicMsg.append(keyClone + alias + dest + newLine + sNew + keyPass
+                    + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("keypasswd")) {
+            topicMsg.append(" Changes the key password to the new one.\n");
+            topicMsg.append("\nkeypasswd Usage:\n");
+            topicMsg.append(keyPasswd + alias + oldKeyPass + newLine + sNew
+                    + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("list")) {
+            topicMsg.append(" Prints the contents of the entry associated "
+                    + "with the alias given. \n");
+            topicMsg.append(" If no alias is specified, the contents of "
+                    + "the entire keystore are printed.\n");
+            topicMsg.append("\nlist Usage:\n");
+            topicMsg.append(list + verboseOrRfc + alias
+                    + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("printcert")) {
+            topicMsg.append(" Prints the detailed description of a "
+                    + "certificate in a human-readable\n");
+            topicMsg.append(" format: its owner and issuer, serial number, "
+                    + "validity period and\n");
+            topicMsg.append(" fingerprints.\n");
+            topicMsg.append("\nprintcert Usage:\n");
+            topicMsg.append(printCert + verbose + certFile + doubleNewLine);
+
+        } else if (topic.equalsIgnoreCase("selfcert")) {
+            topicMsg.append(" Generates an X.509 (v1, v2, v3) self-signed "
+                    + "certificate using a key pair\n");
+            topicMsg.append(" associated with alias. "
+                    + "If X.500 Distinguished Name is supplied it is \n");
+            topicMsg.append(" used as both subject and issuer of the"
+                    + "certificate. Otherwise the\n");
+            topicMsg.append(" distinguished name associated with alias is"
+                    + " used. Signature algorithm,\n");
+            topicMsg.append(" validity period and certificate serial"
+                    + " number are taken from command line if \n");
+            topicMsg.append(" defined there or "
+                    + "from the keystore entry identified by alias.\n");
+            topicMsg
+                    .append(" If \"-ca\" option is specified, generated certificate\n");
+            topicMsg
+                    .append(" will can be used for signing another certifictes.\n");
+            topicMsg
+                    .append(" If \"-secretkey\" option is specified, a secret key will.\n");
+            topicMsg
+                    .append(" be generated instead of key pair and a certificate which\n");
+            topicMsg.append(" are generated by default. \n");
+            topicMsg.append("\nselfcert Usage:\n");
+            topicMsg.append(selfCert + alias + dName + newLine + validity
+                    + sigAlg + newLine + keyPass + ca + serialNum
+                    + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("storepasswd")) {
+            topicMsg.append(" Changes the keystore password to the new one.\n");
+            topicMsg.append("\nstorepasswd Usage:\n");
+            topicMsg.append(storePasswd + sNew + ksTypePassVProvCacerts);
+
+        } else if (topic.equalsIgnoreCase("verify")) {
+            topicMsg.append(" A cerificate chain is built by looking up "
+                    + "the certificate of the issuer\n");
+            topicMsg.append(" of the current certificate. If a sertificate "
+                    + "is self-signed it is assumed\n");
+            topicMsg.append(" to be the root CA. After that the certificates "
+                    + "are searched in the lists\n");
+            topicMsg.append(" of revoked certificates. Certificate signatures "
+                    + "are checked and\n");
+            topicMsg.append(" certificate path is built in the same way as in "
+                    + "import operation. If an\n");
+            topicMsg.append(" error occurs the flow is not stopped but an "
+                    + "attempt to continue is made.\n");
+            topicMsg.append(" The results of the verification are"
+                    + " printed to stdout.\n");
+            topicMsg.append("\nverify Usage:\n");
+            topicMsg.append(verify + certFile + crlFile + newLine
+                    + trustCAcerts + cacerts + newLine + cacertsPass
+                    + ksTypePassVProvCacerts);
+
+        } else {
+            System.out.println("The option with name <" + topic
+                    + "> is unknown.");
+            printHelp();
+            return;
+        }
+        System.out.println(topicMsg);
+    }
+
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreCertPrinter.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreCertPrinter.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreCertPrinter.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreCertPrinter.java Sun Aug  6 23:51:05 2006
@@ -82,7 +82,8 @@
                     + ((keyStoreSize == 1) ? " entry \n" : " entries \n"));
         }
 
-        String provider = param.getProvider();
+        String mdProvider = (param.getMdProvider() != null) ? param
+                .getMdProvider() : param.getProvider();
 
         while (aliases.hasMoreElements()) {
             String currentAlias = (String) aliases.nextElement();
@@ -134,14 +135,14 @@
                     if (param.isVerbose()) {
                         // print out the first certificate
                         System.out.println("Certificate[1]:");
-                        printX509CertDetailed(x509cert, provider);
+                        printX509CertDetailed(x509cert, mdProvider);
                         if (!trustedEntry) {
                             for (int i = 1; i < certChain.length; i++) {
                                 System.out.println("Certificate[" + (i + 1)
                                         + "]:");
                                 printX509CertDetailed(
                                         (X509Certificate) certChain[i],
-                                        provider);
+                                        mdProvider);
                             }
                         }
                     }
@@ -197,10 +198,11 @@
                 String commaSpc = ", ";
                 System.out.print(currentAlias + commaSpc + creationDate
                         + commaSpc + entryType);
-                
+
                 if (!secretKeyEntry) {
-                    System.out.print(commaSpc + "\nCertificate fingerprint (MD5):  ");
-                    printMD(x509cert.getEncoded(), "MD5", provider);
+                    System.out.print(commaSpc
+                            + "\nCertificate fingerprint (MD5):  ");
+                    printMD(x509cert.getEncoded(), "MD5", mdProvider);
                 } else {
                     // If the key is explicitly asked to be printed
                     // by setting the alias, print it out, otherwise - do
@@ -313,9 +315,15 @@
     static void printCert(KeytoolParameters param)
             throws FileNotFoundException, CertificateException, IOException,
             KeytoolException, NoSuchAlgorithmException, NoSuchProviderException {
+
+        String provider = param.getProvider();
+        String certProvider = (param.getCertProvider() != null) ? param
+                .getCertProvider() : provider;
+        String mdProvider = (param.getMdProvider() != null) ? param
+                .getMdProvider() : provider;
         // get the certificate(s) from the file
         Collection certCollection = CertReader.readCerts(param.getFileName(),
-                false, param.getProvider());
+                false, certProvider);
         Iterator certIter = certCollection.iterator();
         int counter = 1;
 
@@ -323,7 +331,7 @@
         while (certIter.hasNext()) {
             X509Certificate cert = (X509Certificate) certIter.next();
             System.out.println("\nCertificate[" + counter + "]:");
-            printX509CertDetailed(cert, param.getProvider());
+            printX509CertDetailed(cert, mdProvider);
             ++counter;
         }
     }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreLoaderSaver.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreLoaderSaver.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreLoaderSaver.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeyStoreLoaderSaver.java Sun Aug  6 23:51:05 2006
@@ -59,15 +59,17 @@
         if (param.getStorePath() == null) {
             param.setStorePath(KeytoolParameters.defaultKeystorePath);
         }
+        String ksProvider = (param.getKsProvider() != null) ? param
+                .getKsProvider() : param.getProvider();
         KeyStore keyStore;
         if (new File(param.getStorePath()).exists()) {
             // load an existing store
             keyStore = loadStore(param.getStorePath(), param.getStoreType(),
-                    param.getStorePass(), param.getProvider());
+                    param.getStorePass(), ksProvider);
         } else {
             // create a new store if it doesn't exist
             keyStore = loadStore(null, param.getStoreType(), param
-                    .getStorePass(), param.getProvider());
+                    .getStorePass(), ksProvider);
             param.setNeedSaveKS(true);
         }
         param.setKeyStore(keyStore);

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeytoolParameters.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeytoolParameters.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeytoolParameters.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/KeytoolParameters.java Sun Aug  6 23:51:05 2006
@@ -59,9 +59,27 @@
     // type of the store. Default type is set in java.security file.
     private String storeType = KeyStore.getDefaultType();
 
-    // the name of the provider to use
+    // the name of the provider to use if specific provider is not given
     private String provider;
 
+    // the name of the provider to work with certificates  
+    private String certProvider;
+    
+    // the name of the provider to work with keys
+    private String keyProvider;
+    
+    // the name of the provider to work with message digests
+    private String mdProvider;
+    
+    // the name of the provider to work with signatures
+    private String sigProvider;
+    
+    // the name of the provider to work with keystore
+    private String ksProvider;
+    
+    // the name of the provider to work with keystore to convert to
+    private String convKsProvider;
+    
     // alias to access an entry in keystore
     private String alias;
 
@@ -154,6 +172,9 @@
     // certificate authorities (usually self-signed)
     private KeyStore cacerts;
     
+    // topic to print help on
+    private String helpTopic;
+    
     // command to perform
     private Command command = Command.HELP;
 
@@ -167,6 +188,13 @@
         storePath = null;
         storeType = KeyStore.getDefaultType();
         provider = null;
+        certProvider = null;
+        keyProvider = null;
+        mdProvider = null;
+        sigProvider = null;
+        ksProvider = null;
+        convKsProvider = null;
+        helpTopic = null;
         storePass = null;
         alias = null;
         keyAlg = null;
@@ -460,7 +488,8 @@
     }
 
     /**
-     * @return Returns the name of the provider to use
+     * @return Returns the name of the provider to use if specific provider is
+     *         not given
      */
     String getProvider() {
         return provider;
@@ -468,13 +497,106 @@
 
     /**
      * @param provider
-     *            the name of the provider to use
+     *            the name of the provider to use if specific provider is not
+     *            given
      */
     public void setProvider(String provider) {
         this.provider = provider;
     }
 
     /**
+     * @return the name of the provider to work with certificates
+     */
+    String getCertProvider() {
+        return certProvider;
+    }
+
+    /**
+     * @param certProvider
+     *            the name of the provider to work with certificates
+     */
+    public void setCertProvider(String certProvider) {
+        this.certProvider = certProvider;
+    }
+
+    /**
+     * @return the name of the provider to work with keystore to convert the
+     *         main keystore to
+     */
+    String getConvKsProvider() {
+        return convKsProvider;
+    }
+
+    /**
+     * @param convKsProvider
+     *            the name of the provider to work with keystore to convert the
+     *            main keystore to
+     */
+    public void setConvKsProvider(String convKsProvider) {
+        this.convKsProvider = convKsProvider;
+    }
+
+    /**
+     * @return the name of the provider to work with keys
+     */
+    String getKeyProvider() {
+        return keyProvider;
+    }
+
+    /**
+     * @param keyProvider
+     *            the name of the provider to work with keys
+     */
+    public void setKeyProvider(String keyProvider) {
+        this.keyProvider = keyProvider;
+    }
+
+    /**
+     * @return the name of the provider to work with keystore
+     */
+    String getKsProvider() {
+        return ksProvider;
+    }
+
+    /**
+     * @param ksProvider
+     *            the name of the provider to work with keystore
+     */
+    public void setKsProvider(String ksProvider) {
+        this.ksProvider = ksProvider;
+    }
+
+    /**
+     * @return the name of the provider to work with message digests
+     */
+    String getMdProvider() {
+        return mdProvider;
+    }
+
+    /**
+     * @param mdProvider
+     *            the name of the provider to work with message digests
+     */
+    public void setMdProvider(String mdProvider) {
+        this.mdProvider = mdProvider;
+    }
+
+    /**
+     * @return the name of the provider to work with signatures
+     */
+    String getSigProvider() {
+        return sigProvider;
+    }
+
+    /**
+     * @param sigProvider
+     *            the name of the provider to work with signatures
+     */
+    public void setSigProvider(String sigProvider) {
+        this.sigProvider = sigProvider;
+    }
+
+    /**
      * @return Returns true if the certificate should be printed or exported in
      *         printable format, false - if in binary format
      */
@@ -662,8 +784,8 @@
     }
 
     /**
-     * @param password
-     *            for the keystore to convert the current keystore to
+     * @param convertedKeyStorePass
+     *            password for the keystore to convert the current keystore to
      */
     public void setConvertedKeyStorePass(char [] convertedKeyStorePass) {
         this.convertedKeyStorePass = convertedKeyStorePass;
@@ -677,8 +799,8 @@
     }
 
     /**
-     * @param path
-     *            to the keystore to convert the current keystore to
+     * @param convertedKeyStorePath
+     *            path to the keystore to convert the current keystore to
      */
     public void setConvertedKeyStorePath(String convertedKeyStorePath) {
         this.convertedKeyStorePath = convertedKeyStorePath;
@@ -692,8 +814,8 @@
     }
 
     /**
-     * @param type
-     *            of the keystore to convert the current keystore to
+     * @param convertedKeyStoreType
+     *            type of the keystore to convert the current keystore to
      */
     public void setConvertedKeyStoreType(String convertedKeyStoreType) {
         this.convertedKeyStoreType = convertedKeyStoreType;
@@ -707,8 +829,8 @@
     }
 
     /**
-     * @param set
-     *            true if key entries should be converted, false - if not
+     * @param convertKeyEnties
+     *            set true if key entries should be converted, false - if not
      */
     public void setConvertKeyEntries(boolean convertKeyEnties) {
         this.convertKeyEntries = convertKeyEnties;
@@ -727,8 +849,8 @@
     }
 
     /**
-     * @param the
-     *            location of cacerts file, containing the certificates from
+     * @param cacertsPath
+     *            the location of cacerts file, containing the certificates from
      *            root certificate authorities (usually self-signed).
      */
     public void setCacertsPath(String cacertsPath) {
@@ -747,8 +869,8 @@
     }
 
     /**
-     * @param password
-     *            for cacerts keystore
+     * @param cacertsPass
+     *            password for cacerts keystore
      */
     public void setCacertsPass(char[] cacertsPass) {
         this.cacertsPass = cacertsPass;
@@ -769,8 +891,9 @@
             NoSuchAlgorithmException, CertificateException,
             NoSuchProviderException, IOException, KeytoolException {
         if (cacerts == null) {
+            String keyStoreProv = (ksProvider != null) ? ksProvider : provider;
             cacerts = KeyStoreLoaderSaver.loadStore(getCacertsPath(),
-                    storeType, getCacertsPass(), provider);
+                    storeType, getCacertsPass(), keyStoreProv);
         }
         return cacerts;
     }
@@ -782,5 +905,19 @@
      */
     void setCacerts(KeyStore cacerts) {
         this.cacerts = cacerts;
+    }
+
+    /**
+     * @return topic to print help on
+     */
+    String getHelpTopic() {
+        return helpTopic;
+}
+    /**
+     * @param helpTopic
+     *            topic to print help on
+     */
+    public void setHelpTopic(String helpTopic) {
+        this.helpTopic = helpTopic;
     }
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/Main.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/Main.java?rev=429254&r1=429253&r2=429254&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/Main.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/tools/src/main/java/org/apache/harmony/tools/keytool/Main.java Sun Aug  6 23:51:05 2006
@@ -37,6 +37,9 @@
             case LIST:
                 KeyStoreCertPrinter.list(param);
                 break;
+            case PRINTCERT:
+                KeyStoreCertPrinter.printCert(param);
+                break;
             case KEYCLONE:
                 EntryManager.keyClone(param);
                 break;
@@ -55,10 +58,15 @@
             case CHECK:
                 CRLManager.checkRevoked(param);
                 break;
+            case VERIFY:
+                CertChainVerifier.verifyChain(param);
+                break;
+            case CERTREQ:
+                CSRGenerator.certReq(param);
+                break;
             case HELP:
-                HelpPrinter.printHelp();
+            	HelpPrinter.printHelp();
                 break;
-
             // TODO: calls for other options.    
         }
     }
@@ -81,8 +89,8 @@
 
         // all commands except printcert and help work with a store
         if (command != Command.PRINTCERT && command != Command.HELP) {
-            // all commands that work with store except list and export 
-            // need store password to with keystore. 
+            // all commands that work with store except list and export
+            // need store password to with keystore.
             if (param.getStorePass() == null && command != Command.LIST
                     && command != Command.EXPORT) {
                 throw new KeytoolException(
@@ -91,14 +99,14 @@
             // prompt for additional parameters if some of the expected
             // ones have not been specified.
             ArgumentsParser.getAdditionalParameters(param);
-        }
 
-        // print the warning if store password is not set
-        if (param.getStorePass() == null) {
-            System.out
-                    .println("\nWARNING!!!\nThe integrity of the keystore data "
-                            + "has NOT been checked!\n"
-                            + "To check it you must provide your keystore password!\n");
+            // print the warning if store password is not set
+            if (param.getStorePass() == null) {
+                System.out.println("\nWARNING!!!\nThe integrity "
+                        + "of the keystore data has NOT been checked!\n"
+                        + "To check it you must provide"
+                        + " your keystore password!\n");
+            }
         }
 
         // the work is being done here