The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
| 3 | * contributor license agreements. See the NOTICE file distributed with |
| 4 | * this work for additional information regarding copyright ownership. |
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
| 6 | * (the "License"); you may not use this file except in compliance with |
| 7 | * the License. You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | */ |
| 17 | |
| 18 | /* |
| 19 | * TODO |
| 20 | * 1. The class extends the PublicKeyImpl class in "org.apache.harmony.security" package. |
| 21 | * |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 22 | * 2. The class uses methods in the auxiliary non-public "ThreeIntegerSequence" class |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 23 | * defined along with the "DSAPrivateKeyImpl" class. |
| 24 | * |
| 25 | * 3. See a compatibility with RI comments |
| 26 | * in the below "DSAPublicKeyImpl(X509EncodedKeySpec keySpec)" constructor. |
| 27 | */ |
| 28 | |
| 29 | package org.apache.harmony.security.provider.crypto; |
| 30 | |
| 31 | import java.io.IOException; |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 32 | import java.io.NotActiveException; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 33 | import java.math.BigInteger; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 34 | import java.security.interfaces.DSAParams; |
Jesse Wilson | 7365de1 | 2010-08-11 15:21:19 -0700 | [diff] [blame] | 35 | import java.security.interfaces.DSAPublicKey; |
| 36 | import java.security.spec.DSAParameterSpec; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 37 | import java.security.spec.DSAPublicKeySpec; |
| 38 | import java.security.spec.InvalidKeySpecException; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 39 | import java.security.spec.X509EncodedKeySpec; |
Jesse Wilson | 7365de1 | 2010-08-11 15:21:19 -0700 | [diff] [blame] | 40 | import org.apache.harmony.security.PublicKeyImpl; |
| 41 | import org.apache.harmony.security.asn1.ASN1Integer; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 42 | import org.apache.harmony.security.utils.AlgNameMapper; |
| 43 | import org.apache.harmony.security.x509.AlgorithmIdentifier; |
| 44 | import org.apache.harmony.security.x509.SubjectPublicKeyInfo; |
| 45 | |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 46 | /** |
| 47 | * The class provides DSAPublicKey functionality by extending a class implementing PublicKey |
| 48 | * and implementing methods defined in both interfaces, DSAKey and DSAPublicKey |
| 49 | */ |
| 50 | public class DSAPublicKeyImpl extends PublicKeyImpl implements DSAPublicKey { |
| 51 | |
| 52 | /** |
| 53 | * @serial |
| 54 | */ |
| 55 | private static final long serialVersionUID = -2279672131310978336L; |
| 56 | |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 57 | private BigInteger y, g, p, q; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 58 | |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 59 | private transient DSAParams params; |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 60 | |
| 61 | /** |
| 62 | * Creates object from DSAPublicKeySpec. |
| 63 | * |
| 64 | * @param keySpec - a DSAPublicKeySpec object |
| 65 | */ |
| 66 | public DSAPublicKeyImpl(DSAPublicKeySpec keySpec) { |
| 67 | |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 68 | super("DSA"); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 69 | |
| 70 | SubjectPublicKeyInfo spki; |
| 71 | |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 72 | p = keySpec.getP(); |
| 73 | q = keySpec.getQ(); |
| 74 | g = keySpec.getG(); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 75 | |
| 76 | ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p |
| 77 | .toByteArray(), q.toByteArray(), g.toByteArray()); |
| 78 | |
| 79 | AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 80 | .map2OID("DSA"), |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 81 | threeInts.getEncoded()); |
| 82 | |
| 83 | y = keySpec.getY(); |
| 84 | |
| 85 | spki = new SubjectPublicKeyInfo(ai, ASN1Integer.getInstance().encode( |
| 86 | y.toByteArray())); |
| 87 | setEncoding(spki.getEncoded()); |
| 88 | |
| 89 | params = (DSAParams) (new DSAParameterSpec(p, q, g)); |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * Creates object from X509EncodedKeySpec. |
| 94 | * |
| 95 | * @param keySpec - a X509EncodedKeySpec object |
| 96 | * |
| 97 | * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format |
| 98 | */ |
| 99 | public DSAPublicKeyImpl(X509EncodedKeySpec keySpec) |
| 100 | throws InvalidKeySpecException { |
| 101 | |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 102 | super("DSA"); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 103 | |
| 104 | AlgorithmIdentifier ai; |
| 105 | ThreeIntegerSequence threeInts = null; |
| 106 | |
| 107 | SubjectPublicKeyInfo subjectPublicKeyInfo = null; |
| 108 | |
Elliott Hughes | 171dc20 | 2010-09-02 11:06:55 -0700 | [diff] [blame] | 109 | byte[] encoding = keySpec.getEncoded(); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 110 | |
| 111 | String alg, algName; |
| 112 | |
| 113 | try { |
| 114 | subjectPublicKeyInfo = (SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1 |
| 115 | .decode(encoding); |
| 116 | } catch (IOException e) { |
Elliott Hughes | 897538a | 2010-05-28 20:00:47 -0700 | [diff] [blame] | 117 | throw new InvalidKeySpecException("Failed to decode keySpec encoding: " + e); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | try { |
| 121 | y = new BigInteger((byte[]) ASN1Integer.getInstance().decode( |
| 122 | subjectPublicKeyInfo.getSubjectPublicKey())); |
| 123 | } catch (IOException e) { |
Elliott Hughes | 897538a | 2010-05-28 20:00:47 -0700 | [diff] [blame] | 124 | throw new InvalidKeySpecException("Failed to decode parameters: " + e); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | ai = subjectPublicKeyInfo.getAlgorithmIdentifier(); |
| 128 | |
| 129 | try { |
| 130 | threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1 |
| 131 | .decode(ai.getParameters()); |
| 132 | } catch (IOException e) { |
Elliott Hughes | 897538a | 2010-05-28 20:00:47 -0700 | [diff] [blame] | 133 | throw new InvalidKeySpecException("Failed to decode parameters: " + e); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 134 | } |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 135 | p = new BigInteger(threeInts.p); |
| 136 | q = new BigInteger(threeInts.q); |
| 137 | g = new BigInteger(threeInts.g); |
| 138 | params = (DSAParams) (new DSAParameterSpec(p, q, g)); |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 139 | |
| 140 | setEncoding(encoding); |
| 141 | |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 142 | /* |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 143 | * the following code implements RI behavior |
| 144 | */ |
| 145 | alg = ai.getAlgorithm(); |
| 146 | algName = AlgNameMapper.map2AlgName(alg); |
| 147 | setAlgorithm(algName == null ? alg : algName); |
| 148 | } |
| 149 | |
| 150 | /** |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 151 | * @return |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 152 | * a value of a public key (y). |
| 153 | */ |
| 154 | public BigInteger getY() { |
| 155 | return y; |
| 156 | } |
| 157 | |
| 158 | /** |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 159 | * @return |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 160 | * DSA key parameters (p, q, g). |
| 161 | */ |
| 162 | public DSAParams getParams() { |
| 163 | return params; |
| 164 | } |
Elliott Hughes | f33eae7 | 2010-05-13 12:36:25 -0700 | [diff] [blame] | 165 | |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 166 | private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException { |
Elliott Hughes | 9efa300 | 2010-10-18 13:54:56 -0700 | [diff] [blame] | 167 | in.defaultReadObject(); |
| 168 | params = new DSAParameterSpec(p, q, g); |
Elliott Hughes | 2f9e468 | 2009-10-09 17:21:46 -0700 | [diff] [blame] | 169 | } |
The Android Open Source Project | adc854b | 2009-03-03 19:28:47 -0800 | [diff] [blame] | 170 | |
| 171 | } |