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: * TODO
020: * 1. The class extends the PublicKeyImpl class in "org.apache.harmony.security" package.
021: *
022: * 2. The class uses methods in the auxiliary non-public "ThreeIntegerSequence" class
023: * defined along with the "DSAPrivateKeyImpl" class.
024: *
025: * 3. See a compatibility with RI comments
026: * in the below "DSAPublicKeyImpl(X509EncodedKeySpec keySpec)" constructor.
027: */
028:
029: package org.apache.harmony.security.provider.crypto;
030:
031: import java.io.IOException;
032: import java.io.NotActiveException;
033:
034: import java.math.BigInteger;
035:
036: import java.security.interfaces.DSAPublicKey;
037: import java.security.interfaces.DSAParams;
038:
039: import java.security.spec.DSAPublicKeySpec;
040: import java.security.spec.InvalidKeySpecException;
041: import java.security.spec.DSAParameterSpec;
042: import java.security.spec.X509EncodedKeySpec;
043:
044: import org.apache.harmony.security.utils.AlgNameMapper;
045: import org.apache.harmony.security.x509.AlgorithmIdentifier;
046: import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
047:
048: import org.apache.harmony.security.asn1.ASN1Integer;
049:
050: import org.apache.harmony.security.internal.nls.Messages;
051:
052: import org.apache.harmony.security.PublicKeyImpl;
053:
054: /**
055: * The class provides DSAPublicKey functionality by extending a class implementing PublicKey
056: * and implementing methods defined in both interfaces, DSAKey and DSAPublicKey
057: */
058: public class DSAPublicKeyImpl extends PublicKeyImpl implements
059: DSAPublicKey {
060:
061: /**
062: * @serial
063: */
064: private static final long serialVersionUID = -2279672131310978336L;
065:
066: private BigInteger y, g, p, q;
067:
068: private transient DSAParams params;
069:
070: /**
071: * Creates object from DSAPublicKeySpec.
072: *
073: * @param keySpec - a DSAPublicKeySpec object
074: */
075: public DSAPublicKeyImpl(DSAPublicKeySpec keySpec) {
076:
077: super ("DSA"); //$NON-NLS-1$
078:
079: SubjectPublicKeyInfo spki;
080:
081: p = keySpec.getP();
082: q = keySpec.getQ();
083: g = keySpec.getG();
084:
085: ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
086: .toByteArray(), q.toByteArray(), g.toByteArray());
087:
088: AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper
089: .map2OID("DSA"), //$NON-NLS-1$
090: threeInts.getEncoded());
091:
092: y = keySpec.getY();
093:
094: spki = new SubjectPublicKeyInfo(ai, ASN1Integer.getInstance()
095: .encode(y.toByteArray()));
096: setEncoding(spki.getEncoded());
097:
098: params = (DSAParams) (new DSAParameterSpec(p, q, g));
099: }
100:
101: /**
102: * Creates object from X509EncodedKeySpec.
103: *
104: * @param keySpec - a X509EncodedKeySpec object
105: *
106: * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format
107: */
108: public DSAPublicKeyImpl(X509EncodedKeySpec keySpec)
109: throws InvalidKeySpecException {
110:
111: super ("DSA"); //$NON-NLS-1$
112:
113: AlgorithmIdentifier ai;
114: ThreeIntegerSequence threeInts = null;
115:
116: SubjectPublicKeyInfo subjectPublicKeyInfo = null;
117:
118: byte encoding[] = keySpec.getEncoded();
119:
120: String alg, algName;
121:
122: try {
123: subjectPublicKeyInfo = (SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1
124: .decode(encoding);
125: } catch (IOException e) {
126: throw new InvalidKeySpecException(Messages.getString(
127: "security.19A", e)); //$NON-NLS-1$
128: }
129:
130: try {
131: y = new BigInteger((byte[]) ASN1Integer.getInstance()
132: .decode(subjectPublicKeyInfo.getSubjectPublicKey()));
133: } catch (IOException e) {
134: throw new InvalidKeySpecException(Messages.getString(
135: "security.19B", e)); //$NON-NLS-1$
136: }
137:
138: ai = subjectPublicKeyInfo.getAlgorithmIdentifier();
139:
140: try {
141: threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1
142: .decode(ai.getParameters());
143: } catch (IOException e) {
144: throw new InvalidKeySpecException(Messages.getString(
145: "security.19B", e)); //$NON-NLS-1$
146: }
147: p = new BigInteger(threeInts.p);
148: q = new BigInteger(threeInts.q);
149: g = new BigInteger(threeInts.g);
150: params = (DSAParams) (new DSAParameterSpec(p, q, g));
151:
152: setEncoding(encoding);
153:
154: /*
155: * the following code implements RI behavior
156: */
157: alg = ai.getAlgorithm();
158: algName = AlgNameMapper.map2AlgName(alg);
159: setAlgorithm(algName == null ? alg : algName);
160: }
161:
162: /**
163: * @return
164: * a value of a public key (y).
165: */
166: public BigInteger getY() {
167: return y;
168: }
169:
170: /**
171: * @return
172: * DSA key parameters (p, q, g).
173: */
174: public DSAParams getParams() {
175: return params;
176: }
177:
178: private void readObject(java.io.ObjectInputStream in)
179: throws NotActiveException, IOException,
180: ClassNotFoundException {
181: in.defaultReadObject();
182: params = new DSAParameterSpec(p, q, g);
183: }
184:
185: }
|