Fields Summary |
---|
private static String | keystoreFilenameKeystore name for CA credentials. |
private static String | keystorePasswordKeystore password. |
private static String | keyAliasAlias for CA keys. |
private static String | keyPasswordCA key password. |
private static String | CASignAlgorithm name for CA signature for new certificates. |
private static String[] | algorithmsSignature algorithm attributes - OID, crypto algorithm ID, signature
algorithm ID. |
private static boolean | initIs this authority initialized? |
private static X509Certificate | CACertCA certificate. |
private static PrivateKey | CAPrivKeyCA private key. |
private static long | SerialNumberCurrent serial number for new certificate. |
private static TLV | CASignatureAlgorithmTLV structure to be used in new certificates. |
private static TLV | CACertPointerTLV structure to be used for generation of new certificates. |
private TLV | CSRParsed certificate enrollment request. |
private TLV | CertificateGenerated certificate. |
private TLV | IssuerAndSerialNumberGenerated IssuerAndSerialNumber data structure. |
private String | StatusCurrent status of CA. |
Methods Summary |
---|
private boolean | checkSign()Verifies signature in certificate enrollment request.
String algorithmOID = CSR.child.next.child.getOID();
String cryptoAlg = "";
String signAlg = "";
for (int i = 0 ; i < algorithms.length; i++) {
if (algorithmOID.equals(algorithms[i][0])) {
cryptoAlg = algorithms[i][1];
signAlg = algorithms[i][2];
break;
}
}
byte[] subjectPKInfo = CSR.child.child.next.next.getDERData();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(subjectPKInfo);
KeyFactory factory = KeyFactory.getInstance(cryptoAlg);
PublicKey key = factory.generatePublic(keySpec);
Signature sig = Signature.getInstance(signAlg);
sig.initVerify(key);
sig.update(CSR.child.getDERData());
byte[] sign = CSR.child.next.next.getValue();
byte[] signature = new byte[sign.length - 1];
System.arraycopy(sign, 1, signature, 0, signature.length);
return sig.verify(signature);
|
private void | create()Creates a new certificate.
// Prepare TBSCertificate data structure
TLV TBSCert = new TLV(TLV.SEQUENCE_TYPE);
// serial number
BigInteger serialNumber = BigInteger.valueOf(getSerialNumber());
TLV current = new TLV(TLV.INTEGER_TYPE, serialNumber.toByteArray());
TBSCert.child = current;
// signature algorithm identifier (CA)
current.next = CASignatureAlgorithm.copy();
current = current.next;
// issuer
current.next = CACertPointer.next.next.next.next.copy();
current = current.next;
// validity
current.next = new TLV(TLV.SEQUENCE_TYPE);
current = current.next;
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
current.child = TLV.createUTCTime(calendar);
calendar.add(Calendar.DAY_OF_MONTH, 30);
current.child.next = TLV.createUTCTime(calendar);
// subject
current.next = CSR.child.child.next.copy();
current = current.next;
// subject public key info
current.next = CSR.child.child.next.next.copy();
// TBSCertificate is complete, now sign it
Signature s = Signature.getInstance(CASign);
s.initSign(CAPrivKey);
s.update(TBSCert.getDERData());
byte[] sign1 = s.sign();
byte[] sign2 = new byte[sign1.length + 1];
System.arraycopy(sign1, 0, sign2, 1, sign1.length);
// create Certificate data structure
Certificate = new TLV(TLV.SEQUENCE_TYPE);
// TBSCertificate
Certificate.child = TBSCert;
// signatureAlgorithm
current = CASignatureAlgorithm.copy();
TBSCert.next = current;
// signatureValue
current.next = new TLV(TLV.BITSTRING_TYPE, sign2);
// create IssuerAndSerialNumber data structure
IssuerAndSerialNumber = new TLV(TLV.SEQUENCE_TYPE);
IssuerAndSerialNumber.child = CACertPointer.next.next.next.next.copy();
IssuerAndSerialNumber.child.next = new TLV(TLV.INTEGER_TYPE,
serialNumber.toByteArray());
|
public boolean | createCertificate(byte[] data)Creates a new certificate.
if (! init) {
Status = "Can't load CA credentials.";
return false;
}
try {
CSR = new TLV(data, 0);
} catch (Exception e) {
Status = "Error parsing the CSR.";
return false;
}
try {
if (! checkSign()) {
Status = "Signature mismatch.";
return false;
}
} catch (Exception e) {
Status = "Can't check signature.";
return false;
}
try {
create();
} catch (Exception e) {
Status = "Can't create certificate.";
return false;
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("Last CSR:");
CSR.print(ps);
ps.println();
ps.println("Certificate:");
Certificate.print(ps);
ps.println();
ps.println("IssuerAndSerialNumber:");
IssuerAndSerialNumber.print(ps);
ps.close();
Status = os.toString();
return true;
|
public byte[] | getCertificate()Returns DER encoded new certificate.
return Certificate.getDERData();
|
public byte[] | getIssuerAndSerialNumber()Returns IssuerAndSerialNumber data structure for generated certificate.
return IssuerAndSerialNumber.getDERData();
|
public byte[] | getPkiPath()Returns PkiPath data structure for generated certificate.
TLV PkiPath = new TLV(TLV.SEQUENCE_TYPE);
try {
PkiPath.child = new TLV(CACert.getEncoded(), 0);
} catch (CertificateEncodingException e) {
// it was already requested during initialization without
// exception
}
PkiPath.child.next = Certificate;
return PkiPath.getDERData();
|
private static synchronized long | getSerialNumber()Returns the serial number value to be used for new certificate.
return SerialNumber++;
|
public java.lang.String | getStatus()Returns current status.
return Status;
|
public static synchronized boolean | init(java.lang.Object o)Initializes the CA.
if (init) {
return true;
}
try {
InputStream keystoreStream;
if (o == null) {
keystoreStream =
new FileInputStream(new File(keystoreFilename));
} else {
keystoreStream =
o.getClass().getResourceAsStream(keystoreFilename);
}
KeyStore jcaKeystore =
KeyStore.getInstance(KeyStore.getDefaultType());
try {
if (keystorePassword == null) {
jcaKeystore.load(keystoreStream, null);
} else {
jcaKeystore.load(keystoreStream,
keystorePassword.toCharArray());
}
} finally {
keystoreStream.close();
}
// retrieve CA certificate and private key
CACert = (java.security.cert.X509Certificate)
jcaKeystore.getCertificate(keyAlias);
CAPrivKey = (PrivateKey) jcaKeystore.getKey(keyAlias,
keyPassword.toCharArray());
String CASignOID = null;
for (int i = 0 ; i < algorithms.length; i++) {
if (CASign.equals(algorithms[i][2])) {
CASignOID = algorithms[i][0];
break;
}
}
if (CASignOID == null) {
return false;
}
// CA signature algorithm identifier
CASignatureAlgorithm = new TLV(TLV.SEQUENCE_TYPE);
CASignatureAlgorithm.child =
new TLV(TLV.OID_TYPE, TLV.StringToOID(CASignOID));
CASignatureAlgorithm.child.next =
new TLV(TLV.NULL_TYPE, new byte[0]);
// Parse CA certificate
CACertPointer = new TLV(CACert.getEncoded(), 0);
CACertPointer = CACertPointer.child.child;
if (CACertPointer.type == TLV.VERSION_TYPE) {
CACertPointer = CACertPointer.next;
}
// CACertPointer is at SerialNumber field
} catch (Exception e){
return false;
}
// serial number initial value
Calendar c = Calendar.getInstance();
long t = c.get(Calendar.YEAR) - 2000;
t = t * 365 + c.get(Calendar.DAY_OF_YEAR) - 1;
t = t * 24 + c.get(Calendar.HOUR_OF_DAY);
t = t * 60 + c.get(Calendar.MINUTE);
t = t * 60 + c.get(Calendar.SECOND);
t = t * 1000 + c.get(Calendar.MILLISECOND);
SerialNumber = t;
init = true;
return true;
|