/*
* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.mj.impl.security.common;
import java.util.Date;
import java.util.Calendar;
/**
* MIDP authentication is build around X.509 Public Key Infrastructure so that
* MIDlet suites are signed using public key certificates.
* This class encapsulates a certificate info used in MIDP authentication
*/
public class Certificate implements javax.microedition.pki.Certificate
{
private String issuer = null;
private String subject = null;
private String organization = null;
private String notBefore = null;
private String notAfter = null;
private String serialNumber = null;
private String fingerprint = null;
private String algName = null;
private String certType = null;
private String version = null;
private long timeNotAfter;
private long timeNotBefore;
public Certificate(String issuer, String subject, String organization, String notBefore, String notAfter, String serialNumber, String fingerprint)
{
this.issuer = issuer;
this.subject = subject;
this.organization = organization;
this.notBefore = notBefore;
this.notAfter = notAfter;
this.serialNumber = serialNumber;
this.fingerprint = fingerprint;
}
public Certificate(String issuer, String subject, long timenotBefore, long timenotAfter, String serialNumber, String algName, String version, String certType)
{
this.issuer = issuer;
this.subject = subject;
this.notBefore = notBefore;
this.notAfter = notAfter;
this.serialNumber = serialNumber;
this.algName = algName;
this.timeNotAfter = timenotAfter;
this.timeNotBefore = timenotBefore;
this.certType = certType;
this.version = version;
}
public Certificate(Certificate otherCert)
{
if (otherCert != null)
{
this.issuer = otherCert.getIssuer();
this.subject = otherCert.getSubject();
this.organization = otherCert.getOrganization();
this.notBefore = otherCert.getDateNotBefore();
this.notAfter = otherCert.getDateNotAfter();
this.serialNumber = otherCert.getSerialNumber();
this.fingerprint = otherCert.getFingerprint();
}
}
/**
* Getter for the issuer of the certificate
*
* @return The name of the entity which issued the certificate
*/
public String getIssuer()
{
return issuer;
}
/**
* Getter for the certificate validity's start date
*
* @return The start date of the certificate's validity
*/
public Date getValidFrom()
{
return str2Date(notBefore);
}
/**
* Getter for the certificate validity's end date
*
* @return The end date of the certificate's validity
*/
public Date getValidUntil()
{
return str2Date(notAfter);
}
/**
* Getter for the serial number of the certificate
*
* @return The serial number of the certificate
*/
public String getSerialNumber()
{
return serialNumber;
}
/**
* Getter for the fingerprint of the certificate
*
* @return The fingerprint of the certificate
*/
public String getFingerprint()
{
return fingerprint;
}
/**
* Getter for the subject of the certificate
*
* @return The name of the entity to which the certificate has been issued
*/
public String getSubject()
{
return subject;
}
/**
* Getter for the organization of the certificate
*
* @return The name of the organization to which the certificate has been
* issued
*/
public String getOrganization()
{
return organization;
}
/*
* The format of the returned string is YYYYMMDDHHMMSS,
* where YYYY represents the year,
* MM is the month (counting January as 01), and
* DD is the day of the month (01 to 31)
* HH is the hour (0-24)
* MM is the minutes (0-60)
* SS is the seconds (0-60)
*/
public String getDateNotAfter()
{
return notAfter;
}
/*
* The format of the returned string is YYYYMMDDHHMMSS,
* where YYYY represents the year,
* MM is the month (counting January as 01), and
* DD is the day of the month (01 to 31)
* HH is the hour (0-24)
* MM is the minutes (0-60)
* SS is the seconds (0-60)
*/
public String getDateNotBefore()
{
return notBefore;
}
/**
* Gets the time before which this Certificate may not be used from the
* validity period.
*
* @return the time
*/
public long getNotBefore()
{
return timeNotBefore;
}
/**
* Gets the time after which this Certificate may not be used from the
* validity period.
*
* @return the time
*/
public long getNotAfter()
{
return timeNotAfter;
}
/**
* Get the type of the certificate
*
* @return the type field
*/
public String getType()
{
return certType;
}
/**
* Get the version of the certificate
*
* @return the version field
*/
public String getVersion()
{
return version;
}
/**
* Get the signature algorithm used for the certificate
*
* @return the alg name
*/
public String getSigAlgName()
{
return algName;
}
/*
* Returns the content of the fingerprint split into groups of 4 characters
* separated by ' '
*
* @return The formatted fingerprint
*/
public String getFormattedFingerprint()
{
if (fingerprint == null)
{
return null;
}
StringBuffer sb = new StringBuffer();
for (int i=0; i<fingerprint.length(); i++)
{
sb.append(fingerprint.charAt(i));
if ((i+1)%4 == 0)
{
// insert the separator
sb.append(' ');
}
}
return sb.toString();
}
/*
* Formats the issuer according to following syntax:
* CN", "O", "OU", "C", "ST", "L
* where CN = common name
* O = organization name
* OU = organization unit name
* C = country name
* ST = state or province name
* L = locality name
* e.g. Issuer, Org, Sub-org, FI, Unknown, Tampere
*/
public String getFormattedIssuer()
{
return formatDN(getIssuer());
}
/*
* Formats the subject according to following syntax:
* CN", "O", "OU", "C", "ST", "L
* where CN = common name
* O = organization name
* OU = organization unit name
* C = country name
* ST = state or province name
* L = locality name
* e.g. subject, Org, Sub-org, FI, Unknown, Tampere
*/
public String getFormattedSubject()
{
return formatDN(getSubject());
}
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("\nIssuer:").append(getIssuer())
.append("\nSubject:").append(getSubject())
.append("\nOrganization:").append(getOrganization())
.append("\nValidFrom:").append(getDateNotBefore())
.append("\nValidUntil:").append(getDateNotAfter())
.append("\nSerialNumber:").append(getSerialNumber())
.append("\nFingerprint:").append(getFingerprint());
return sb.toString();
}
/*
* Builds a Date object out of a string represented as YYYYMMDDHHMMSS
* where YYYY represents the year,
* MM is the month (counting January as 01), and
* DD is the day of the month (01 to 31)
* HH is the hour (0-24)
* MM is the minutes (0-60)
* SS is the seconds (0-60)
*/
private Date str2Date(String str)
{
if (str != null
&& str.length() == 14)
{
try
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(str.substring(0,4)));
// Calendar.MONTH begins from 0 (0=January, 1=Februrary, ...)
cal.set(Calendar.MONTH, Integer.parseInt(str.substring(4,6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(str.substring(6,8)));
cal.set(Calendar.HOUR, Integer.parseInt(str.substring(8,10)));
cal.set(Calendar.MINUTE, Integer.parseInt(str.substring(10,12)));
cal.set(Calendar.SECOND, Integer.parseInt(str.substring(12,14)));
return cal.getTime();
}
catch (NumberFormatException e)
{
}
catch (ArrayIndexOutOfBoundsException e) {}
}
return null;
}
/*
* Formats a distinguished name (DN) according to following syntax:
* CN", "O", "OU", "C", "ST", "L
* where CN = common name
* O = organization name
* OU = organization unit name
* C = country name
* ST = state or province name
* L = locality name
*/
private String formatDN(String DN)
{
if (DN != null)
{
StringBuffer buf = new StringBuffer();
// common name
String tmp = getToken(DN, "/CN=");
if (tmp != null)
{
buf.append(tmp);
}
// organization name
tmp = getToken(DN, "/O=");
if (tmp != null)
{
if (buf.length() > 0)
{
buf.append(", ");
}
buf.append(tmp);
}
// organization unit name
tmp = getToken(DN, "/OU=");
if (tmp != null)
{
if (buf.length() > 0)
{
buf.append(", ");
}
buf.append(tmp);
}
// country name
tmp = getToken(DN, "/C=");
if (tmp != null)
{
if (buf.length() > 0)
{
buf.append(", ");
}
buf.append(tmp);
}
// state or province name
tmp = getToken(DN, "/ST=");
if (tmp != null)
{
if (buf.length() > 0)
{
buf.append(", ");
}
buf.append(tmp);
}
// locality name
tmp = getToken(DN, "/L=");
if (tmp != null)
{
if (buf.length() > 0)
{
buf.append(", ");
}
buf.append(tmp);
}
return buf.toString();
}
return null;
}
private String getToken(String str, String sep)
{
int startIndex = str.indexOf(sep);
if (startIndex != -1)
{
startIndex += sep.length();
int endIndex = str.indexOf("/", startIndex);
if (endIndex == -1)
{
endIndex = str.length();
}
return str.substring(startIndex, endIndex);
}
return null;
}
}