1 /*
2  * Copyright (c) 1997, 2011, 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 
26 package sun.security.provider;
27 
28 import java.io.*;
29 import java.math.BigInteger;
30 import java.security.AlgorithmParametersSpi;
31 import java.security.spec.AlgorithmParameterSpec;
32 import java.security.spec.DSAParameterSpec;
33 import java.security.spec.InvalidParameterSpecException;
34 
35 import sun.security.util.Debug;
36 import sun.security.util.DerValue;
37 import sun.security.util.DerOutputStream;
38 
39 /**
40  * This class implements the parameter set used by the
41  * Digital Signature Algorithm as specified in the FIPS 186
42  * standard.
43  *
44  * @author Jan Luehe
45  *
46  *
47  * @since 1.2
48  */
49 
50 public class DSAParameters extends AlgorithmParametersSpi {
51 
52     // the prime (p)
53     protected BigInteger p;
54 
55     // the sub-prime (q)
56     protected BigInteger q;
57 
58     // the base (g)
59     protected BigInteger g;
60 
engineInit(AlgorithmParameterSpec paramSpec)61     protected void engineInit(AlgorithmParameterSpec paramSpec)
62         throws InvalidParameterSpecException {
63             if (!(paramSpec instanceof DSAParameterSpec)) {
64                 throw new InvalidParameterSpecException
65                     ("Inappropriate parameter specification");
66             }
67             this.p = ((DSAParameterSpec)paramSpec).getP();
68             this.q = ((DSAParameterSpec)paramSpec).getQ();
69             this.g = ((DSAParameterSpec)paramSpec).getG();
70     }
71 
engineInit(byte[] params)72     protected void engineInit(byte[] params) throws IOException {
73         DerValue encodedParams = new DerValue(params);
74 
75         if (encodedParams.tag != DerValue.tag_Sequence) {
76             throw new IOException("DSA params parsing error");
77         }
78 
79         encodedParams.data.reset();
80 
81         this.p = encodedParams.data.getBigInteger();
82         this.q = encodedParams.data.getBigInteger();
83         this.g = encodedParams.data.getBigInteger();
84 
85         if (encodedParams.data.available() != 0) {
86             throw new IOException("encoded params have " +
87                                   encodedParams.data.available() +
88                                   " extra bytes");
89         }
90     }
91 
engineInit(byte[] params, String decodingMethod)92     protected void engineInit(byte[] params, String decodingMethod)
93         throws IOException {
94             engineInit(params);
95     }
96 
97     protected <T extends AlgorithmParameterSpec>
engineGetParameterSpec(Class<T> paramSpec)98         T engineGetParameterSpec(Class<T> paramSpec)
99         throws InvalidParameterSpecException
100     {
101             try {
102                 Class<?> dsaParamSpec = Class.forName
103                     ("java.security.spec.DSAParameterSpec");
104                 if (dsaParamSpec.isAssignableFrom(paramSpec)) {
105                     return paramSpec.cast(
106                             new DSAParameterSpec(this.p, this.q, this.g));
107                 } else {
108                     throw new InvalidParameterSpecException
109                         ("Inappropriate parameter Specification");
110                 }
111             } catch (ClassNotFoundException e) {
112                 throw new InvalidParameterSpecException
113                     ("Unsupported parameter specification: " + e.getMessage());
114             }
115     }
116 
engineGetEncoded()117     protected byte[] engineGetEncoded() throws IOException {
118         DerOutputStream out = new DerOutputStream();
119         DerOutputStream bytes = new DerOutputStream();
120 
121         bytes.putInteger(p);
122         bytes.putInteger(q);
123         bytes.putInteger(g);
124         out.write(DerValue.tag_Sequence, bytes);
125         return out.toByteArray();
126     }
127 
engineGetEncoded(String encodingMethod)128     protected byte[] engineGetEncoded(String encodingMethod)
129         throws IOException {
130             return engineGetEncoded();
131     }
132 
133     /*
134      * Returns a formatted string describing the parameters.
135      */
engineToString()136     protected String engineToString() {
137         return "\n\tp: " + Debug.toHexString(p)
138             + "\n\tq: " + Debug.toHexString(q)
139             + "\n\tg: " + Debug.toHexString(g)
140             + "\n";
141     }
142 }
143