blob: 56e4f4a98bad798f96b924c306e973c273e0227c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1996-2003 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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> 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 * <p>
53 * <code><pre>
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></code>
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 // XXX deprecated for general use
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 paramter "P"
117 * @param q the DSS/DSA paramter "Q"
118 * @param g the DSS/DSA paramter "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 paramter "P"
134 * @param q the DSS/DSA paramter "Q"
135 * @param g the DSS/DSA paramter "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}