Requirement
Build the following:
RMC.java
package com.jtech.security;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.*;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.*;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.nio.charset.*;
import java.util.Date;
import java.util.Hashtable;
import java.util.Vector;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERInputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.misc.NetscapeCertType;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.X509V1CertificateGenerator;
import org.bouncycastle.jce.X509V3CertificateGenerator;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
//
// A class that will create a certificate and store it
//
public class RMC
{
static char[] passwd = { 'x', 'x', 'x', 'l', 'x', 'e', 'r', 'o', 'm', 'x', 'x' };
//
// Constant used by CA cert
//
// signers name
private static final String ISSUER = "C=RT, O=YourGroup, OU=RT Primary Certificate";
// subjects name - the same as we are self signed.
private static final String SUBJECT = "C=RT, O=YourGroup, OU=RT Primary Certificate";
// Key
private RSAPublicKeySpec _pubKeySpec;
private RSAPrivateCrtKeySpec _privKeySpec;
private RSAPublicKeySpec _intPubKeySpec;
private RSAPrivateCrtKeySpec _intPrivKeySpec;
private RSAPublicKeySpec _caPubKeySpec;
private RSAPrivateCrtKeySpec _caPrivKeySpec;
// Certificate
private Certificate caCert;
private Certificate interCert;
private Certificate _targetCert;
private X509V1CertificateGenerator _v1CertGen = new X509V1CertificateGenerator();
private X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator();
//
// create the subject key identifier.
//
public SubjectKeyIdentifier createSubjectKeyId(PublicKey pubKey)
{
try
{
ByteArrayInputStream bIn = new ByteArrayInputStream(pubKey.getEncoded());
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
(ASN1Sequence)new DERInputStream(bIn).readObject());
return new SubjectKeyIdentifier(info);
}
catch (Exception e)
{
throw new RuntimeException("ERROR: Creating Subject Key ID");
}
}
//
// create the authority key identifier.
//
public AuthorityKeyIdentifier createAuthorityKeyId( PublicKey pubKey,
X509Name name,
int sNumber)
{
try
{
ByteArrayInputStream bIn = new ByteArrayInputStream(pubKey.getEncoded());
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
(ASN1Sequence)new DERInputStream(bIn).readObject());
GeneralName genName = new GeneralName(name);
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(genName);
return new AuthorityKeyIdentifier( info,
new GeneralNames(new DERSequence(v)),
BigInteger.valueOf(sNumber));
}
catch (Exception e)
{
throw new RuntimeException("ERROR: Creating AuthorityKeyId");
}
}
public AuthorityKeyIdentifier createAuthorityKeyId(PublicKey pubKey)
{
try
{
ByteArrayInputStream bIn = new ByteArrayInputStream(pubKey.getEncoded());
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
(ASN1Sequence)new DERInputStream(bIn).readObject());
return new AuthorityKeyIdentifier(info);
}
catch (Exception e)
{
throw new RuntimeException("ERROR: Creating AuthorityKeyId");
}
}
/**
* we generate the CA's certificate
*/
public Certificate createMasterCert( PublicKey pubKey,
PrivateKey privKey,
String caIssuer,
String caSubject)
throws Exception
{
//
// create the certificate - version 1
//
//
// this is actually optional - but if you want to have control
// over setting the friendly name this is the way to do it...
//
return cert;
}
/**
* we generate an intermediate certificate signed by our CA
*/
public Certificate createIntermediateCert( PublicKey pubKey,
PrivateKey caPrivKey,
PublicKey caPubKey)
throws Exception
{
//
// signers name table - another way of doing it.
//
//
// subject name table.
//
//
// create the certificate - version 3
//
//
// extensions
//
//
// this is actually optional - but if you want to have control
// over setting the friendly name this is the way to do it...
//
return cert;
}
public String readFile(String fileName)
{
String curLine = "";
String totalLine = "";
try
{
// Build the String
}
catch (Exception exception)
{
exception.printStackTrace();
}
return totalLine;
}
// readCert - Reads in a certificate file and returns the certificate
// object
public Certificate readCert(String fileName)
{
Certificate cert = null;
try {
// Build the String
FileInputStream fis = new FileInputStream(fileName);
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0) {
cert = cf.generateCertificate(bis);
//System.out.println(cert.toString());
}
} catch (Exception exception) {
exception.printStackTrace();
}
return cert;
}
/**
* we generate a certificate signed by our CA's intermediate certficate
*/
public Certificate createCert( PublicKey pubKey,
PrivateKey caPrivKey,
PublicKey caPubKey,
String cn,
String cnEmail)
throws Exception
{
//
// signers name table.
//
//
// subjects name table.
//
//
// create the certificate - version 3
//
//
// add the extensions
//
// OID (Object Identifier) Extension Name
// 2.5.29.14 SubjectKeyIdentifier
// 2.5.29.15 KeyUsage
// 2.5.29.16 PrivateKeyUsage
// 2.5.29.17 SubjectAlternativeName
// 2.5.29.18 IssuerAlternativeName
// 2.5.29.19 BasicConstraints
// 2.5.29.30 NameConstraints
// 2.5.29.33 PolicyMappings
// 2.5.29.35 AuthorityKeyIdentifier
// 2.5.29.36 PolicyConstraints
//
// this is also optional - in the sense that if you leave this
// out the keystore will add it automatically, note though that
// for the browser to recognise the associated private key this
// you should at least use the pkcs_9_localKeyId OID and set it
// to the same as you do for the private key's localKeyId.
//
return _targetCert;
}
//
// This method writes a certificate to a file.
//
public static void export2File(java.security.cert.Certificate cert, File file, boolean binary)
{
try
{
// Get the encoded form which is suitable for exporting
byte[] buf = cert.getEncoded();
os.close();
}
catch (CertificateEncodingException e)
{
// Catch certificate info
e.printStackTrace();
}
catch (IOException e)
{
// Catch other exception
e.printStackTrace();
}
}
private void initKeys()
{
//
// personal keys
//
//
// intermediate keys.
//
//
// ca keys
//
return;
}
//
// Constructor that reads from a file
//
public RMC(String fileName) {
String cert = new String ();
_targetCert = readCert(fileName);
}
//
// Constructor to build a certificate
//
public RMC(String caIssuer, String caSubject, String cn, String cnEmail)
{
try
{
// Add the security provider
// Initialize all the keys
// set up the keys
// Create the certificate chain
}
catch (Exception e)
{
// Handle exception
e.printStackTrace();
}
return;
}
//
// Return the target cert
// All the Java Certificate API could then be used upon
//
public Certificate getTargetCert()
{
return _targetCert;
}
public String getRoleInfo()
{
byte[] roleValue = ((X509Certificate)_targetCert).getExtensionValue("2.5.29.40");
return (new String(roleValue));
}
//
// Export Base 64 format certificate
//
public void exportB64Cert(String fileName)
{
export2File(_targetCert, new File(fileName), false);
}
//
// Export binary format certificate
public void exportBINCert(String fileName)
{
export2File(_targetCert, new File(fileName), true);
}
}
NsCTestDriver
A test driver program that uses all the functionalities in RMC. Implement:
Copyright 1996-2003 OpenLoop Computing. All rights reserved.