001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.satsa.pki;
028:
029: import java.util.Calendar;
030: import java.util.TimeZone;
031: import com.sun.satsa.util.*;
032:
033: import com.sun.midp.i18n.Resource;
034: import com.sun.midp.i18n.ResourceConstants;
035:
036: /**
037: * This class represents WIM certificate.
038: */
039: class Certificate {
040:
041: /** Certificate label. */
042: String label;
043:
044: /** Certificate ID. */
045: byte[] id;
046:
047: /** Issuer certificate ID. */
048: byte[] requestId;
049:
050: /** Parsed X.509 certificate or null if its not loaded. */
051: TLV cert;
052:
053: /**
054: * Location (path, offset, length) of certificate DF entry on
055: * card.
056: */
057: Location header;
058:
059: /** Location (path, offset, length) of certificate on card. */
060: Location body;
061:
062: /**
063: * Verifies if this certificate is expired.
064: * @return true if the certificate is expired.
065: */
066: boolean isExpired() {
067:
068: Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
069: try {
070: return c.before(getValidity(cert, true))
071: || c.after(getValidity(cert, false));
072: } catch (TLVException e) {
073: return true;
074: }
075: }
076:
077: /**
078: * Verifies if this certificate was issued by subject of the
079: * specified certificate. Returns false for self-signed certificates.
080: * @param next certificate
081: * @return true if the certificate was issued by subject of the
082: * specified certificate.
083: */
084: boolean isIssuedBy(Certificate next) {
085: TLV issuer = getIssuer();
086: return (requestId != null)
087: && Utils.byteMatch(requestId, next.id)
088: && (!RFC2253Name.compare(issuer, getSubject()))
089: && RFC2253Name.compare(issuer, next.getSubject());
090: }
091:
092: /**
093: * Returns serial number of this certificate. The result can be used
094: * only for comparison, not for the construction of new DER
095: * structure.
096: * @return TLV object containing serial number.
097: */
098: TLV getSerialNumber() {
099: return cert.child.child.skipOptional(0xa0);
100: }
101:
102: /**
103: * Returns issuer name for this certificate which can be used
104: * only for comparison.
105: * @return TLV object containing issuer name.
106: */
107: TLV getIssuer() {
108: return cert.child.child.skipOptional(0xa0).next.next;
109: }
110:
111: /**
112: * Returns subject name for this certificate which can be used
113: * only for comparison.
114: * @return TLV object containing subject name.
115: */
116: TLV getSubject() {
117: return getIssuer().next.next;
118: }
119:
120: /**
121: * Returns new IssuerAndSerialNumber TLV object which can be used
122: * as element of new data structure.
123: * @return IssuerAndSerialNumber TLV object
124: */
125: TLV getIssuerAndSerialNumber() {
126:
127: TLV t = TLV.createSequence();
128: t.setChild(getIssuer().copy())
129: .setNext(getSerialNumber().copy());
130: return t;
131: }
132:
133: /**
134: * Returns key algorithm identifier for this certificate which can
135: * be used as element of new data structure.
136: * @return key algorithm identifier
137: */
138: TLV getKeyAlgorithmID() {
139: return getSubject().next.child.copy();
140: }
141:
142: /**
143: * Returns notBefore or notAfter date for the given certificate.
144: * @param cert parsed x.509 certificate.
145: * @param notBefore if true returns notBefore field value,
146: * otherwise - notAfter.
147: * @return the requested date
148: * @throws TLVException in case of parsing error
149: */
150: static Calendar getValidity(TLV cert, boolean notBefore)
151: throws TLVException {
152:
153: try {
154: TLV t = cert.child.child.skipOptional(0xa0).next.next.next.child;
155: if (!notBefore) {
156: t = t.next;
157: }
158: return t.getTime();
159: } catch (NullPointerException npe) {
160: throw new TLVException("Invalid certificate");
161: }
162: }
163:
164: /**
165: * Returns description of given certificate (subject, issuer, serial
166: * number and validity).
167: * @param cert parsed certificate
168: * @return certificate description or null if any error occurs
169: */
170: static String getInfo(TLV cert) {
171:
172: try {
173: TLV sn = cert.child.child.skipOptional(0xa0);
174: TLV issuer = sn.next.next;
175: TLV subject = issuer.next.next;
176:
177: String result;
178: result =
179: // "Subject"
180: Resource
181: .getString(ResourceConstants.JSR177_CERTIFICATE_SUBJECT)
182: + ": " + RFC2253Name.NameToString(subject);
183: result += "\n\n"
184: +
185: // "Issuer"
186: Resource
187: .getString(ResourceConstants.JSR177_CERTIFICATE_ISSUER)
188: + ": " + RFC2253Name.NameToString(issuer);
189:
190: String s;
191: try {
192: s = "" + sn.getInteger();
193: } catch (TLVException e) {
194: s = "0x"
195: + Utils.hexNumber(sn.data, sn.valueOffset,
196: sn.length);
197: }
198: result += "\n\n"
199: +
200: // "Serial number"
201: Resource
202: .getString(ResourceConstants.JSR177_CERTIFICATE_SN)
203: + ": " + s;
204:
205: return result
206: + "\n\n"
207: +
208: // "Valid from"
209: Resource
210: .getString(ResourceConstants.JSR177_CERTIFICATE_VALIDFROM)
211: + " "
212: + Utils.calendarToString(getValidity(cert, true))
213: + " "
214: +
215: // "through"
216: Resource
217: .getString(ResourceConstants.JSR177_CERTIFICATE_VALIDTILL)
218: + " "
219: + Utils.calendarToString(getValidity(cert, false));
220: } catch (TLVException tlve) { // ignored
221: } catch (IllegalArgumentException iae) { // ignored
222: } catch (NullPointerException npe) { // ignored
223: }
224: return null;
225: }
226:
227: /*
228: * IMPL_NOTE remove after debugging
229: /**
230: * Debug output.
231: * /
232: void print() {
233: System.out.println("----------------------------");
234: System.out.println("Certificate");
235: System.out.println("label " + label);
236: System.out.println("id " +
237: Utils.hexEncode(id, 0, id.length, 9999));
238: System.out.print("header ");
239: header.print();
240: System.out.print("body ");
241: body.print();
242: System.out.println("");
243: }
244: */
245: }
|