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 
26 package sun.security.provider;
27 
28 import java.util.*;
29 import java.io.*;
30 import java.math.BigInteger;
31 import java.security.InvalidKeyException;
32 import java.security.ProviderException;
33 import java.security.AlgorithmParameters;
34 import java.security.spec.DSAParameterSpec;
35 import java.security.spec.InvalidParameterSpecException;
36 import java.security.interfaces.DSAParams;
37 
38 import sun.security.x509.AlgIdDSA;
39 import sun.security.pkcs.PKCS8Key;
40 import sun.security.util.Debug;
41 import sun.security.util.DerValue;
42 import sun.security.util.DerInputStream;
43 import sun.security.util.DerOutputStream;
44 
45 /**
46  * A PKCS#8 private key for the Digital Signature Algorithm.
47  *
48  * @author Benjamin Renaud
49  *
50  *
51  * @see DSAPublicKey
52  * @see AlgIdDSA
53  * @see DSA
54  */
55 
56 public final class DSAPrivateKey extends PKCS8Key
57 implements java.security.interfaces.DSAPrivateKey, Serializable {
58 
59     /** use serialVersionUID from JDK 1.1. for interoperability */
60     private static final long serialVersionUID = -3244453684193605938L;
61 
62     /* the private key */
63     private BigInteger x;
64 
65     /*
66      * Keep this constructor for backwards compatibility with JDK1.1.
67      */
DSAPrivateKey()68     public DSAPrivateKey() {
69     }
70 
71     /**
72      * Make a DSA private key out of a private key and three parameters.
73      */
DSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g)74     public DSAPrivateKey(BigInteger x, BigInteger p,
75                          BigInteger q, BigInteger g)
76     throws InvalidKeyException {
77         this.x = x;
78         algid = new AlgIdDSA(p, q, g);
79 
80         try {
81             key = new DerValue(DerValue.tag_Integer,
82                                x.toByteArray()).toByteArray();
83             encode();
84         } catch (IOException e) {
85             InvalidKeyException ike = new InvalidKeyException(
86                 "could not DER encode x: " + e.getMessage());
87             ike.initCause(e);
88             throw ike;
89         }
90     }
91 
92     /**
93      * Make a DSA private key from its DER encoding (PKCS #8).
94      */
DSAPrivateKey(byte[] encoded)95     public DSAPrivateKey(byte[] encoded) throws InvalidKeyException {
96         clearOldKey();
97         decode(encoded);
98     }
99 
100     /**
101      * Returns the DSA parameters associated with this key, or null if the
102      * parameters could not be parsed.
103      */
getParams()104     public DSAParams getParams() {
105         try {
106             if (algid instanceof DSAParams) {
107                 return (DSAParams)algid;
108             } else {
109                 DSAParameterSpec paramSpec;
110                 AlgorithmParameters algParams = algid.getParameters();
111                 if (algParams == null) {
112                     return null;
113                 }
114                 paramSpec = algParams.getParameterSpec(DSAParameterSpec.class);
115                 return (DSAParams)paramSpec;
116             }
117         } catch (InvalidParameterSpecException e) {
118             return null;
119         }
120     }
121 
122     /**
123      * Get the raw private key, x, without the parameters.
124      *
125      * @see getParameters
126      */
getX()127     public BigInteger getX() {
128         return x;
129     }
130 
clearOldKey()131     private void clearOldKey() {
132         int i;
133         if (this.encodedKey != null) {
134             for (i = 0; i < this.encodedKey.length; i++) {
135                 this.encodedKey[i] = (byte)0x00;
136             }
137         }
138         if (this.key != null) {
139             for (i = 0; i < this.key.length; i++) {
140                 this.key[i] = (byte)0x00;
141             }
142         }
143     }
144 
parseKeyBits()145     protected void parseKeyBits() throws InvalidKeyException {
146         try {
147             DerInputStream in = new DerInputStream(key);
148             x = in.getBigInteger();
149         } catch (IOException e) {
150             InvalidKeyException ike = new InvalidKeyException(e.getMessage());
151             ike.initCause(e);
152             throw ike;
153         }
154     }
155 }
156