AlgIdDSA.java revision 12318:bee34b1dcbf1
1/* 2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.security.x509; 27 28import java.io.IOException; 29import java.math.BigInteger; 30import java.security.*; 31import java.security.interfaces.DSAParams; 32 33import sun.security.util.*; 34 35 36/** 37 * This class identifies DSS/DSA Algorithm variants, which are distinguished 38 * by using different algorithm parameters <em>P, Q, G</em>. It uses the 39 * NIST/IETF standard DER encoding. These are used to implement the Digital 40 * Signature Standard (DSS), FIPS 186. 41 * 42 * <P><em><b>NOTE:</b></em> DSS/DSA Algorithm IDs may be created without these 43 * parameters. Use of DSS/DSA in modes where parameters are 44 * either implicit (e.g. a default applicable to a site or a larger scope), 45 * or are derived from some Certificate Authority's DSS certificate, is 46 * not supported directly. The application is responsible for creating a key 47 * containing the required parameters prior to using the key in cryptographic 48 * operations. The follwoing is an example of how this may be done assuming 49 * that we have a certificate called <code>currentCert</code> which doesn't 50 * contain DSS/DSA parameters and we need to derive DSS/DSA parameters 51 * from a CA's certificate called <code>caCert</code>. 52 * 53 * <pre>{@code 54 * // key containing parameters to use 55 * DSAPublicKey cAKey = (DSAPublicKey)(caCert.getPublicKey()); 56 * // key without parameters 57 * DSAPublicKey nullParamsKey = (DSAPublicKey)(currentCert.getPublicKey()); 58 * 59 * DSAParams cAKeyParams = cAKey.getParams(); 60 * KeyFactory kf = KeyFactory.getInstance("DSA"); 61 * DSAPublicKeySpec ks = new DSAPublicKeySpec(nullParamsKey.getY(), 62 * cAKeyParams.getP(), 63 * cAKeyParams.getQ(), 64 * cAKeyParams.getG()); 65 * DSAPublicKey usableKey = kf.generatePublic(ks); 66 * }</pre> 67 * 68 * @see java.security.interfaces.DSAParams 69 * @see java.security.interfaces.DSAPublicKey 70 * @see java.security.KeyFactory 71 * @see java.security.spec.DSAPublicKeySpec 72 * 73 * @author David Brownell 74 */ 75public final 76class AlgIdDSA extends AlgorithmId implements DSAParams 77{ 78 79 private static final long serialVersionUID = 3437177836797504046L; 80 81 /* 82 * The three unsigned integer parameters. 83 */ 84 private BigInteger p , q, g; 85 86 /** Returns the DSS/DSA parameter "P" */ 87 public BigInteger getP () { return p; } 88 89 /** Returns the DSS/DSA parameter "Q" */ 90 public BigInteger getQ () { return q; } 91 92 /** Returns the DSS/DSA parameter "G" */ 93 public BigInteger getG () { return g; } 94 95 /** 96 * Default constructor. The OID and parameters must be 97 * deserialized before this algorithm ID is used. 98 */ 99 @Deprecated 100 public AlgIdDSA () {} 101 102 AlgIdDSA (DerValue val) throws IOException 103 { super(val.getOID()); } 104 105 /** 106 * Construct an AlgIdDSA from an X.509 encoded byte array. 107 */ 108 public AlgIdDSA (byte[] encodedAlg) throws IOException 109 { super (new DerValue(encodedAlg).getOID()); } 110 111 /** 112 * Constructs a DSS/DSA Algorithm ID from unsigned integers that 113 * define the algorithm parameters. Those integers are encoded 114 * as big-endian byte arrays. 115 * 116 * @param p the DSS/DSA parameter "P" 117 * @param q the DSS/DSA parameter "Q" 118 * @param g the DSS/DSA parameter "G" 119 */ 120 public AlgIdDSA (byte[] p, byte[] q, byte[] g) 121 throws IOException 122 { 123 this (new BigInteger (1, p), 124 new BigInteger (1, q), 125 new BigInteger (1, g)); 126 } 127 128 /** 129 * Constructs a DSS/DSA Algorithm ID from numeric parameters. 130 * If all three are null, then the parameters portion of the algorithm id 131 * is set to null. See note in header regarding use. 132 * 133 * @param p the DSS/DSA parameter "P" 134 * @param q the DSS/DSA parameter "Q" 135 * @param g the DSS/DSA parameter "G" 136 */ 137 public AlgIdDSA (BigInteger p, BigInteger q, BigInteger g) 138 { 139 super (DSA_oid); 140 141 if (p != null || q != null || g != null) { 142 if (p == null || q == null || g == null) 143 throw new ProviderException("Invalid parameters for DSS/DSA" + 144 " Algorithm ID"); 145 try { 146 this.p = p; 147 this.q = q; 148 this.g = g; 149 initializeParams (); 150 151 } catch (IOException e) { 152 /* this should not happen */ 153 throw new ProviderException ("Construct DSS/DSA Algorithm ID"); 154 } 155 } 156 } 157 158 /** 159 * Returns "DSA", indicating the Digital Signature Algorithm (DSA) as 160 * defined by the Digital Signature Standard (DSS), FIPS 186. 161 */ 162 public String getName () 163 { return "DSA"; } 164 165 166 /* 167 * For algorithm IDs which haven't been created from a DER encoded 168 * value, "params" must be created. 169 */ 170 private void initializeParams () 171 throws IOException 172 { 173 DerOutputStream out = new DerOutputStream (); 174 175 out.putInteger(p); 176 out.putInteger(q); 177 out.putInteger(g); 178 params = new DerValue (DerValue.tag_Sequence,out.toByteArray ()); 179 } 180 181 /** 182 * Parses algorithm parameters P, Q, and G. They're found 183 * in the "params" member, which never needs to be changed. 184 */ 185 protected void decodeParams () 186 throws IOException 187 { 188 if (params == null) 189 throw new IOException("DSA alg params are null"); 190 if (params.tag != DerValue.tag_Sequence) 191 throw new IOException("DSA alg parsing error"); 192 193 params.data.reset (); 194 195 this.p = params.data.getBigInteger(); 196 this.q = params.data.getBigInteger(); 197 this.g = params.data.getBigInteger(); 198 199 if (params.data.available () != 0) 200 throw new IOException ("AlgIdDSA params, extra="+ 201 params.data.available ()); 202 } 203 204 205 /* 206 * Returns a formatted string describing the parameters. 207 */ 208 public String toString () 209 { return paramsToString (); } 210 211 /* 212 * Returns a string describing the parameters. 213 */ 214 protected String paramsToString () 215 { 216 if (params == null) 217 return " null\n"; 218 else 219 return 220 "\n p:\n" + Debug.toHexString(p) + 221 "\n q:\n" + Debug.toHexString(q) + 222 "\n g:\n" + Debug.toHexString(g) + 223 "\n"; 224 } 225} 226