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 PrivateKeyImpl class in "org.apache.harmony.security" package. 21 * 22 * 2. See a compatibility with RI comments 23 * in the below "DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec)" constructor. 24 */ 25 26 27 package org.apache.harmony.security.provider.crypto; 28 29 import java.io.IOException; 30 import java.io.NotActiveException; 31 import java.math.BigInteger; 32 import java.security.interfaces.DSAParams; 33 import java.security.interfaces.DSAPrivateKey; 34 import java.security.spec.DSAParameterSpec; 35 import java.security.spec.DSAPrivateKeySpec; 36 import java.security.spec.InvalidKeySpecException; 37 import java.security.spec.PKCS8EncodedKeySpec; 38 import org.apache.harmony.security.PrivateKeyImpl; 39 import org.apache.harmony.security.asn1.ASN1Integer; 40 import org.apache.harmony.security.pkcs8.PrivateKeyInfo; 41 import org.apache.harmony.security.utils.AlgNameMapper; 42 import org.apache.harmony.security.x509.AlgorithmIdentifier; 43 44 /** 45 * The class provides DSAPrivateKey functionality by extending a class implementing PrivateKey 46 * and implementing methods defined in both interfaces, DSAKey and DSAPrivateKey 47 */ 48 public class DSAPrivateKeyImpl extends PrivateKeyImpl implements DSAPrivateKey { 49 50 /** 51 * @serial 52 */ 53 private static final long serialVersionUID = -4716227614104950081L; 54 55 private BigInteger x, g, p, q; 56 57 private transient DSAParams params; 58 59 /** 60 * Creates object from DSAPrivateKeySpec. 61 * 62 * @param keySpec - a DSAPrivateKeySpec object 63 */ 64 public DSAPrivateKeyImpl(DSAPrivateKeySpec keySpec) { 65 66 super("DSA"); 67 68 PrivateKeyInfo pki; 69 70 g = keySpec.getG(); 71 p = keySpec.getP(); 72 q = keySpec.getQ(); 73 74 ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p 75 .toByteArray(), q.toByteArray(), g.toByteArray()); 76 77 AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper 78 .map2OID("DSA"), 79 threeInts.getEncoded()); 80 x = keySpec.getX(); 81 82 pki = new PrivateKeyInfo(0, ai, ASN1Integer.getInstance().encode( 83 x.toByteArray()), null); 84 85 setEncoding(pki.getEncoded()); 86 87 params = new DSAParameterSpec(p, q, g); 88 } 89 90 /** 91 * Creates object from PKCS8EncodedKeySpec. 92 * 93 * @param keySpec - a XPKCS8EncodedKeySpec object 94 * 95 * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format 96 */ 97 public DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec) 98 throws InvalidKeySpecException { 99 100 super("DSA"); 101 102 AlgorithmIdentifier ai; 103 ThreeIntegerSequence threeInts = null; 104 105 String alg, algName; 106 107 byte[] encoding = keySpec.getEncoded(); 108 109 PrivateKeyInfo privateKeyInfo = null; 110 111 try { 112 privateKeyInfo = (PrivateKeyInfo) PrivateKeyInfo.ASN1 113 .decode(encoding); 114 } catch (IOException e) { 115 throw new InvalidKeySpecException("Failed to decode keySpec encoding: " + e); 116 } 117 118 try { 119 x = new BigInteger((byte[]) ASN1Integer.getInstance().decode( 120 privateKeyInfo.getPrivateKey())); 121 } catch (IOException e) { 122 throw new InvalidKeySpecException("Failed to decode parameters: " + e); 123 } 124 125 ai = privateKeyInfo.getAlgorithmIdentifier(); 126 try { 127 threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1 128 .decode(ai.getParameters()); 129 } catch (IOException e) { 130 throw new InvalidKeySpecException("Failed to decode parameters: " + e); 131 } 132 p = new BigInteger(threeInts.p); 133 q = new BigInteger(threeInts.q); 134 g = new BigInteger(threeInts.g); 135 params = new DSAParameterSpec(p, q, g); 136 setEncoding(encoding); 137 138 /* 139 * the following code implements RI behavior 140 */ 141 alg = ai.getAlgorithm(); 142 algName = AlgNameMapper.map2AlgName(alg); 143 setAlgorithm(algName == null ? alg : algName); 144 } 145 146 public BigInteger getX() { 147 return x; 148 } 149 150 public DSAParams getParams() { 151 return params; 152 } 153 154 private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException { 155 in.defaultReadObject(); 156 params = new DSAParameterSpec(p, q, g); 157 } 158 159 } 160