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.crypto;
028:
029: import com.sun.satsa.util.TLV;
030: import com.sun.satsa.util.TLVException;
031: import com.sun.satsa.util.Utils;
032:
033: import java.security.PublicKey;
034: import java.security.spec.KeySpec;
035: import java.security.spec.InvalidKeySpecException;
036: import java.security.spec.X509EncodedKeySpec;
037:
038: /**
039: * This class represents an RSA public key.
040: */
041: public class RSAPublicKey implements PublicKey {
042:
043: /** OID for RSA crypto algorithm, 1.2.840.113549.1.1.1. */
044: private static byte[] RSA_OID = { 0x2A, (byte) 0x86, 0x48,
045: (byte) 0x86, (byte) 0xF7, 0x0D, 0x01, 0x01, 0x01 };
046: /** Key object. */
047: private com.sun.midp.crypto.RSAPublicKey key;
048:
049: /** Key length in bytes. */
050: private int keyLen;
051:
052: /** Specification of the key material. */
053: private X509EncodedKeySpec keySpec;
054:
055: /**
056: * Constructs an RSAPublicKey object.
057: * @param keySpec specification of the key material
058: * @throws InvalidKeySpecException if key specification is invalid
059: */
060: public RSAPublicKey(KeySpec keySpec) throws InvalidKeySpecException {
061:
062: if (!(keySpec instanceof X509EncodedKeySpec)) {
063: throw new InvalidKeySpecException();
064: }
065:
066: this .keySpec = (X509EncodedKeySpec) keySpec;
067:
068: byte[] data = getEncoded();
069:
070: /*
071: * SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {
072: * algorithm AlgorithmIdentifier {{IOSet}},
073: * subjectPublicKey BIT STRING
074: * }
075: *
076: * AlgorithmIdentifier ::= SEQUENCE {
077: * algorithm OBJECT IDENTIFIER,
078: * parameters ANY DEFINED BY algorithm OPTIONAL
079: * }
080: *
081: */
082:
083: try {
084: TLV t = new TLV(data, 0);
085:
086: t = t.child; // AlgorithmIdentifier
087: if (!Utils.byteMatch(data, t.child.valueOffset,
088: t.child.length, RSA_OID, 0, RSA_OID.length)) {
089: throw new InvalidKeySpecException(
090: "Invalid algorithm identifier");
091: }
092:
093: t = t.next; // subjectPublicKey
094:
095: /*
096: * RSAPublicKey ::= SEQUENCE {
097: * modulus INTEGER, -- n
098: * publicExponent INTEGER -- e --
099: * }
100: */
101:
102: // the first byte of value in BIT STRING is the number of
103: // unused bits
104: t = new TLV(data, t.valueOffset + 1);
105:
106: t = t.child; // modulus
107:
108: int offset = t.valueOffset;
109: int len = t.length;
110: while (data[offset] == 0) {
111: offset++;
112: len--;
113: }
114:
115: keyLen = ((len + 7) / 8) * 8;
116:
117: t = t.next;
118:
119: key = new com.sun.midp.crypto.RSAPublicKey(data, offset,
120: len, data, t.valueOffset, t.length);
121: } catch (InvalidKeySpecException ikse) {
122: throw ikse;
123: } catch (NullPointerException npe) {
124: throw new InvalidKeySpecException();
125: } catch (TLVException tlve) {
126: throw new InvalidKeySpecException();
127: }
128: }
129:
130: /**
131: * Returns key object.
132: * @return key object
133: */
134: public com.sun.midp.crypto.RSAPublicKey getKey() {
135: return key;
136: }
137:
138: /**
139: * Returns the size of key in bytes.
140: * @return size of key in bytes
141: */
142: public int getKeySize() {
143: return keyLen;
144: }
145:
146: /**
147: * Returns the standard algorithm name for this key.
148: * @return the name of the algorithm associated with this key.
149: */
150: public String getAlgorithm() {
151: return "RSA";
152: }
153:
154: /**
155: * Returns the name of the primary encoding format of this key.
156: * @return the primary encoding format of the key.
157: */
158: public String getFormat() {
159: return keySpec.getFormat();
160: }
161:
162: /**
163: * Returns the key in its primary encoding format, or null
164: * if this key does not support encoding.
165: * @return the encoded key.
166: */
167: public byte[] getEncoded() {
168: return keySpec.getEncoded();
169: }
170: }
|