001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch;
031:
032: public class KeyPairDSA extends KeyPair {
033: private byte[] P_array;
034: private byte[] Q_array;
035: private byte[] G_array;
036: private byte[] pub_array;
037: private byte[] prv_array;
038:
039: //private int key_size=0;
040: private int key_size = 1024;
041:
042: public KeyPairDSA(JSch jsch) {
043: super (jsch);
044: }
045:
046: void generate(int key_size) throws JSchException {
047: this .key_size = key_size;
048: try {
049: Class c = Class.forName(jsch.getConfig("keypairgen.dsa"));
050: KeyPairGenDSA keypairgen = (KeyPairGenDSA) (c.newInstance());
051: keypairgen.init(key_size);
052: P_array = keypairgen.getP();
053: Q_array = keypairgen.getQ();
054: G_array = keypairgen.getG();
055: pub_array = keypairgen.getY();
056: prv_array = keypairgen.getX();
057:
058: keypairgen = null;
059: } catch (Exception e) {
060: //System.err.println("KeyPairDSA: "+e);
061: if (e instanceof Throwable)
062: throw new JSchException(e.toString(), (Throwable) e);
063: throw new JSchException(e.toString());
064: }
065: }
066:
067: private static final byte[] begin = "-----BEGIN DSA PRIVATE KEY-----"
068: .getBytes();
069: private static final byte[] end = "-----END DSA PRIVATE KEY-----"
070: .getBytes();
071:
072: byte[] getBegin() {
073: return begin;
074: }
075:
076: byte[] getEnd() {
077: return end;
078: }
079:
080: byte[] getPrivateKey() {
081: int content = 1 + countLength(1) + 1 + // INTEGER
082: 1 + countLength(P_array.length) + P_array.length + // INTEGER P
083: 1 + countLength(Q_array.length) + Q_array.length + // INTEGER Q
084: 1 + countLength(G_array.length) + G_array.length + // INTEGER G
085: 1 + countLength(pub_array.length) + pub_array.length + // INTEGER pub
086: 1 + countLength(prv_array.length) + prv_array.length; // INTEGER prv
087:
088: int total = 1 + countLength(content) + content; // SEQUENCE
089:
090: byte[] plain = new byte[total];
091: int index = 0;
092: index = writeSEQUENCE(plain, index, content);
093: index = writeINTEGER(plain, index, new byte[1]); // 0
094: index = writeINTEGER(plain, index, P_array);
095: index = writeINTEGER(plain, index, Q_array);
096: index = writeINTEGER(plain, index, G_array);
097: index = writeINTEGER(plain, index, pub_array);
098: index = writeINTEGER(plain, index, prv_array);
099: return plain;
100: }
101:
102: boolean parse(byte[] plain) {
103: try {
104:
105: if (vendor == VENDOR_FSECURE) {
106: if (plain[0] != 0x30) { // FSecure
107: Buffer buf = new Buffer(plain);
108: buf.getInt();
109: P_array = buf.getMPIntBits();
110: G_array = buf.getMPIntBits();
111: Q_array = buf.getMPIntBits();
112: pub_array = buf.getMPIntBits();
113: prv_array = buf.getMPIntBits();
114: return true;
115: }
116: return false;
117: }
118:
119: int index = 0;
120: int length = 0;
121:
122: if (plain[index] != 0x30)
123: return false;
124: index++; // SEQUENCE
125: length = plain[index++] & 0xff;
126: if ((length & 0x80) != 0) {
127: int foo = length & 0x7f;
128: length = 0;
129: while (foo-- > 0) {
130: length = (length << 8) + (plain[index++] & 0xff);
131: }
132: }
133:
134: if (plain[index] != 0x02)
135: return false;
136: index++; // INTEGER
137: length = plain[index++] & 0xff;
138: if ((length & 0x80) != 0) {
139: int foo = length & 0x7f;
140: length = 0;
141: while (foo-- > 0) {
142: length = (length << 8) + (plain[index++] & 0xff);
143: }
144: }
145: index += length;
146:
147: index++;
148: length = plain[index++] & 0xff;
149: if ((length & 0x80) != 0) {
150: int foo = length & 0x7f;
151: length = 0;
152: while (foo-- > 0) {
153: length = (length << 8) + (plain[index++] & 0xff);
154: }
155: }
156: P_array = new byte[length];
157: System.arraycopy(plain, index, P_array, 0, length);
158: index += length;
159:
160: index++;
161: length = plain[index++] & 0xff;
162: if ((length & 0x80) != 0) {
163: int foo = length & 0x7f;
164: length = 0;
165: while (foo-- > 0) {
166: length = (length << 8) + (plain[index++] & 0xff);
167: }
168: }
169: Q_array = new byte[length];
170: System.arraycopy(plain, index, Q_array, 0, length);
171: index += length;
172:
173: index++;
174: length = plain[index++] & 0xff;
175: if ((length & 0x80) != 0) {
176: int foo = length & 0x7f;
177: length = 0;
178: while (foo-- > 0) {
179: length = (length << 8) + (plain[index++] & 0xff);
180: }
181: }
182: G_array = new byte[length];
183: System.arraycopy(plain, index, G_array, 0, length);
184: index += length;
185:
186: index++;
187: length = plain[index++] & 0xff;
188: if ((length & 0x80) != 0) {
189: int foo = length & 0x7f;
190: length = 0;
191: while (foo-- > 0) {
192: length = (length << 8) + (plain[index++] & 0xff);
193: }
194: }
195: pub_array = new byte[length];
196: System.arraycopy(plain, index, pub_array, 0, length);
197: index += length;
198:
199: index++;
200: length = plain[index++] & 0xff;
201: if ((length & 0x80) != 0) {
202: int foo = length & 0x7f;
203: length = 0;
204: while (foo-- > 0) {
205: length = (length << 8) + (plain[index++] & 0xff);
206: }
207: }
208: prv_array = new byte[length];
209: System.arraycopy(plain, index, prv_array, 0, length);
210: index += length;
211: } catch (Exception e) {
212: //System.err.println(e);
213: //e.printStackTrace();
214: return false;
215: }
216: return true;
217: }
218:
219: public byte[] getPublicKeyBlob() {
220: byte[] foo = super .getPublicKeyBlob();
221: if (foo != null)
222: return foo;
223:
224: if (P_array == null)
225: return null;
226:
227: Buffer buf = new Buffer(sshdss.length + 4 + P_array.length + 4
228: + Q_array.length + 4 + G_array.length + 4
229: + pub_array.length + 4);
230: buf.putString(sshdss);
231: buf.putString(P_array);
232: buf.putString(Q_array);
233: buf.putString(G_array);
234: buf.putString(pub_array);
235: return buf.buffer;
236: }
237:
238: private static final byte[] sshdss = "ssh-dss".getBytes();
239:
240: byte[] getKeyTypeName() {
241: return sshdss;
242: }
243:
244: public int getKeyType() {
245: return DSA;
246: }
247:
248: public int getKeySize() {
249: return key_size;
250: }
251:
252: public void dispose() {
253: super.dispose();
254: Util.bzero(prv_array);
255: }
256: }
|