in modules/jdktools/src/main/java/org/apache/harmony/tools/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 + ">.");
}
}