001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexander Y. Kleymenov
020: * @version $Revision$
021: */package org.apache.harmony.security.x509;
022:
023: import java.security.KeyFactory;
024: import java.security.NoSuchAlgorithmException;
025: import java.security.PublicKey;
026: import java.security.spec.InvalidKeySpecException;
027: import java.security.spec.X509EncodedKeySpec;
028:
029: import org.apache.harmony.security.asn1.ASN1BitString;
030: import org.apache.harmony.security.asn1.ASN1Sequence;
031: import org.apache.harmony.security.asn1.ASN1Type;
032: import org.apache.harmony.security.asn1.BerInputStream;
033: import org.apache.harmony.security.asn1.BitString;
034: import org.apache.harmony.security.utils.AlgNameMapper;
035:
036: /**
037: * The class encapsulates the ASN.1 DER encoding/decoding work
038: * with the following structure which is a part of X.509 certificate
039: * (as specified in RFC 3280 -
040: * Internet X.509 Public Key Infrastructure.
041: * Certificate and Certificate Revocation List (CRL) Profile.
042: * http://www.ietf.org/rfc/rfc3280.txt):
043: *
044: * <pre>
045: * SubjectPublicKeyInfo ::= SEQUENCE {
046: * algorithm AlgorithmIdentifier,
047: * subjectPublicKey BIT STRING
048: * }
049: * </pre>
050: */
051: public class SubjectPublicKeyInfo {
052:
053: // the value of algorithmID field of the structure
054: private AlgorithmIdentifier algorithmID;
055: // the value of subjectPublicKey field of the structure
056: private byte[] subjectPublicKey;
057: // the public key corresponding to this SubjectPublicKeyInfo
058: private PublicKey publicKey;
059: // the value of unusedBits field of the structure
060: private int unusedBits;
061: // the ASN.1 encoded form of SubjectPublicKeyInfo
062: private byte[] encoding;
063:
064: /**
065: * TODO
066: * @param algID: AlgorithmIdentifier
067: * @param subjectPublicKey: byte[]
068: */
069: public SubjectPublicKeyInfo(AlgorithmIdentifier algID,
070: byte[] subjectPublicKey) {
071: this (algID, subjectPublicKey, 0);
072: }
073:
074: /**
075: * TODO
076: * @param algID: AlgorithmIdentifier
077: * @param subjectPublicKey: byte[]
078: * @param unused: int
079: */
080: public SubjectPublicKeyInfo(AlgorithmIdentifier algID,
081: byte[] subjectPublicKey, int unused) {
082: this (algID, subjectPublicKey, 0, null);
083: }
084:
085: //
086: // TODO
087: // @param algID: AlgorithmIdentifier
088: // @param subjectPublicKey: byte[]
089: // @param unused: int
090: // @param encoding: byte[]
091: //
092: private SubjectPublicKeyInfo(AlgorithmIdentifier algID,
093: byte[] subjectPublicKey, int unused, byte[] encoding) {
094: this .algorithmID = algID;
095: this .subjectPublicKey = subjectPublicKey;
096: this .unusedBits = unused;
097: this .encoding = encoding;
098: }
099:
100: /**
101: * Returns the value of algorithmIdentifier field of the structure.
102: * @return algorithmIdentifier
103: */
104: public AlgorithmIdentifier getAlgorithmIdentifier() {
105: return algorithmID;
106: }
107:
108: /**
109: * Returns the value of subjectPublicKey field of the structure.
110: * @return subjectPublicKey
111: */
112: public byte[] getSubjectPublicKey() {
113: return subjectPublicKey;
114: }
115:
116: /**
117: * Returns the value of unusedBits field of the structure.
118: * @return unusedBits
119: */
120: public int getUnusedBits() {
121: return unusedBits;
122: }
123:
124: /**
125: * Returns ASN.1 encoded form of this X.509 SubjectPublicKeyInfo value.
126: * @return a byte array containing ASN.1 encode form.
127: */
128: public byte[] getEncoded() {
129: if (encoding == null) {
130: encoding = ASN1.encode(this );
131: }
132: return encoding;
133: }
134:
135: /**
136: * Returns The PublicKey corresponding to this SubjectPublicKeyInfo
137: * instance.
138: * @return public key corresponding to this SubjectPublicKeyInfo.
139: */
140: public PublicKey getPublicKey() {
141: if (publicKey == null) {
142: String alg_oid = algorithmID.getAlgorithm();
143: try {
144: String alg = AlgNameMapper.map2AlgName(alg_oid);
145:
146: if (alg == null) {
147: alg = alg_oid;
148: }
149: publicKey = KeyFactory.getInstance(alg).generatePublic(
150: new X509EncodedKeySpec(getEncoded()));
151: } catch (InvalidKeySpecException e) {
152: } catch (NoSuchAlgorithmException e) {
153: }
154: if (publicKey == null) {
155: publicKey = new X509PublicKey(alg_oid, getEncoded(),
156: subjectPublicKey);
157: }
158: }
159: return publicKey;
160: }
161:
162: public static final ASN1Sequence ASN1 = new ASN1Sequence(
163: new ASN1Type[] { AlgorithmIdentifier.ASN1,
164: ASN1BitString.getInstance() }) {
165:
166: protected Object getDecodedObject(BerInputStream in) {
167: Object[] values = (Object[]) in.content;
168: return new SubjectPublicKeyInfo(
169: (AlgorithmIdentifier) values[0],
170: ((BitString) values[1]).bytes,
171: ((BitString) values[1]).unusedBits, in.getEncoded());
172: }
173:
174: protected void getValues(Object object, Object[] values) {
175:
176: SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) object;
177:
178: values[0] = spki.algorithmID;
179: values[1] = new BitString(spki.subjectPublicKey,
180: spki.unusedBits);
181: }
182: };
183: }
|