//*****************************************************************************
//*
//* (c) Copyright 2002. Glub Tech, Incorporated. All Rights Reserved.
//*
//* $Id: SSLCertificate.java 37 2009-05-11 22:46:15Z gary $
//*
//*****************************************************************************
package com.glub.secureftp.bean;
import java.lang.String;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.Hashtable;
import java.util.StringTokenizer;
/**
* The <code>SSLCertificate</code> class contains useful information about
* an SSL (X509) certificate.
*
* @author Brian Knight
* @version $Revision: 47 $, $Date: 2009-05-16 10:10:12 -0700 (Sat, 16 May 2009) $
* @since 2.1.3
*/
public class SSLCertificate {
X509Certificate cert;
Hashtable subject, issuer;
/**
* Create a <code>SSLCertificate</code> object.
*
* @param cert the X509 certificate.
*/
public SSLCertificate(X509Certificate cert) {
this.cert = cert;
if ( null != cert ) {
subject = parsePrincipalString(cert.getSubjectDN().toString());
issuer = parsePrincipalString(cert.getIssuerDN().toString());
}
else {
subject = new Hashtable();
subject.put( "CN", "Unknown (peer not authenticated)" );
issuer = new Hashtable();
issuer.put( "CN", "Unknown (peer not authenticated)" );
}
}
/**
* Returns the X.509 certificate.
*
* @return the X.509 certificate
*/
public X509Certificate getX509Certificate() {
return cert;
}
/**
* Returns the crypto fingerprint of the certificate.
*
* @return the crypto fingerprint of the certificate.
*/
public String getFingerprint() {
byte[] b;
if ( null == cert ) {
return "";
}
try {
MessageDigest md = MessageDigest.getInstance("MD5");
b = md.digest(cert.getEncoded());
}
catch (Exception e) {
return "<error occurred while calculating fingerprint>";
}
char[] c = new char[(b.length * 3) - 1];
int j = 0;
char hexdigits[] = { '0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F' };
if (b == null || b.length <= 0)
return null;
c[j++] = hexdigits[(b[0] & 0xff) >> 4];
c[j++] = hexdigits[(b[0] & 0xf)];
for (int i = 1; i < b.length; i++) {
c[j++] = ':';
c[j++] = hexdigits[(b[i] & 0xff) >> 4];
c[j++] = hexdigits[(b[i] & 0xf)];
}
return new String(c);
}
/**
* Returns the serial number of the certificate.
*
* @return the serial number of the certificate.
*/
public String getSerialNumber() {
if ( null == cert ) return "";
return cert.getSerialNumber().toString();
}
/**
* Returns the starting date of the certificate.
*
* @return the starting date of the certificate.
*/
public Date getStartDate() {
if ( null == cert ) return new Date();
return cert.getNotBefore();
}
/**
* Returns the ending date of the certificate.
*
* @return the ending date of the certificate.
*/
public Date getEndDate() {
if ( null == cert ) return new Date();
return cert.getNotAfter();
}
/**
* Returns the common name of the certificate.
* <p>
* Usually this is the hostname of the server.
*
* @return the common name of the certificate.
*/
public String getCN() { return (String) subject.get("CN"); }
/**
* Returns the e-mail address associated with the certificate.
*
* @return the e-mail address associated with the certificate.
*/
public String getEmail() { return (String) subject.get("EMail"); }
/**
* Returns the organizational unit associated with the certificate.
*
* @return the organizational unit associated with the certificate.
*/
public String getOU() { return (String) subject.get("OU"); }
/**
* Returns the organization associated with the certificate.
*
* @return the organization associated with the certificate.
*/
public String getOrg() { return (String) subject.get("O"); }
/**
* Returns the locality (or city) associated with the certificate.
*
* @return the locality (or city) associated with the certificate.
*/
public String getLocality() { return (String) subject.get("L"); }
/**
* Returns the state associated with the certificate.
*
* @return the state associated with the certificate.
*/
public String getState() { return (String) subject.get("ST"); }
/**
* Returns the country associated with the certificate.
*
* @return the country associated with the certificate.
*/
public String getCountry() { return (String) subject.get("C"); }
/**
* Returns the common name of the certificate issuer.
*
* @return the common name of the certificate issuer.
*/
public String getIssuerCN() { return (String) issuer.get("CN"); }
/**
* Returns the e-mail address associated with the certificate issuer.
*
* @return the e-mail address associated with the certificate issuer.
*/
public String getIssuerEmail() { return (String) issuer.get("EMail"); }
/**
* Returns the organizational unit associated with the certificate issuer.
*
* @return the organizational unit associated with the certificate issuer.
*/
public String getIssuerOU() { return (String) issuer.get("OU"); }
/**
* Returns the organization associated with the certificate issuer.
*
* @return the organization associated with the certificate issuer.
*/
public String getIssuerOrg() { return (String) issuer.get("O"); }
/**
* Returns the locality (or city) associated with the certificate issuer.
*
* @return the locality (or city) associated with the certificate issuer.
*/
public String getIssuerLocality() { return (String) issuer.get("L"); }
/**
* Returns the state associated with the certificate issuer.
*
* @return the state associated with the certificate issuer.
*/
public String getIssuerState() { return (String) issuer.get("ST"); }
/**
* Returns the country associated with the certificate issuer.
*
* @return the country associated with the certificate issuer.
*/
public String getIssuerCountry() { return (String) issuer.get("C"); }
/**
* Return the bit strength of the RSA certificate
*
* @return the bit strength of the RSA certificate (-1 if unknown).
*/
public int getBitStrength() {
int result = -1;
PublicKey publicKey = null;
if ( null != cert &&
(publicKey = cert.getPublicKey()) instanceof RSAPublicKey ) {
result = ((RSAPublicKey)publicKey).getModulus().bitLength();
}
return result;
}
private Hashtable parsePrincipalString(String p) {
Hashtable table = new Hashtable();
StringTokenizer tok = new StringTokenizer(p, ",");
while (tok.hasMoreTokens()) {
String temp = tok.nextToken().trim();
int index = temp.indexOf('=');
if (index <= 0)
continue;
String key = temp.substring(0, index);
String value = temp.substring(index + 1);
if ( value.startsWith("\"") && tok.hasMoreTokens() ) {
while ( !value.endsWith("\"") && tok.hasMoreTokens() ) {
value += ", " + tok.nextToken().trim();
}
value = value.substring(1, value.length()-1);
}
table.put(key, value);
}
return table;
}
}