throws IOException, GeneralSecurityException {
X509Certificate cert;
byte[] der;
TLV tbsCert;
TLV subjectName;
RSAPublicKey rsaKey;
String owner;
long notBefore;
long notAfter;
byte[] rawModulus;
int i;
int keyLen;
byte[] modulus;
byte[] exponent;
Vector keys;
// get the cert from the keystore
try {
cert = (X509Certificate)jcaKeystore.getCertificate(alias);
} catch (ClassCastException cce) {
throw new CertificateException("Certificate not X.509 type");
}
if (cert == null) {
throw new CertificateException("Certificate not found");
}
/*
* J2SE reorders the attributes when building a printable name
* so we must build a printable name on our own.
*/
/*
* TBSCertificate ::= SEQUENCE {
* version [0] EXPLICIT Version DEFAULT v1,
* serialNumber CertificateSerialNumber,
* signature AlgorithmIdentifier,
* issuer Name,
* validity Validity,
* subject Name,
* subjectPublicKeyInfo SubjectPublicKeyInfo,
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
* -- If present, version shall be v2 or v3
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
* -- If present, version shall be v2 or v3
* extensions [3] EXPLICIT Extensions OPTIONAL
* -- If present, version shall be v3
* }
*/
der = cert.getTBSCertificate();
tbsCert = new TLV(der, 0);
// walk down the tree of TLVs to find the subject name
try {
// Top level a is Sequence, drop down to the first child
subjectName = tbsCert.child;
// skip the version if present.
if (subjectName.type == TLV.VERSION_TYPE) {
subjectName = subjectName.next;
}
// skip the serial number
subjectName = subjectName.next;
// skip the signature alg. id.
subjectName = subjectName.next;
// skip the issuer
subjectName = subjectName.next;
// skip the validity
subjectName = subjectName.next;
owner = parseDN(der, subjectName);
} catch (NullPointerException e) {
throw new CertificateException("TBSCertificate corrupt 1");
} catch (IndexOutOfBoundsException e) {
throw new CertificateException("TBSCertificate corrupt 2");
}
notBefore = cert.getNotBefore().getTime();
notAfter = cert.getNotAfter().getTime();
// get the key from the cert
try {
rsaKey = (RSAPublicKey)cert.getPublicKey();
} catch (ClassCastException cce) {
throw new RuntimeException("Key in certificate is not an RSA key");
}
// get the key parameters from the key
rawModulus = rsaKey.getModulus().toByteArray();
/*
* the modulus is given as the minimum positive integer,
* will not padded to the bit size of the key, or may have a extra
* pad to make it positive. SSL expects the key to be signature
* bit size. but we cannot get that from the key, so we should
* remove any zero pad bytes and then pad out to a multiple of 8 bytes
*/
for (i = 0; i < rawModulus.length && rawModulus[i] == 0; i++);
keyLen = rawModulus.length - i;
keyLen = (keyLen + 7) / 8 * 8;
modulus = new byte[keyLen];
int k, j;
for (k = rawModulus.length - 1, j = keyLen - 1;
k >= 0 && j >= 0; k--, j--) {
modulus[j] = rawModulus[k];
}
exponent = rsaKey.getPublicExponent().toByteArray();
// add the key
keys = keystore.findKeys(owner);
if (keys != null) {
boolean duplicateKey = false;