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 KeyPairRSA extends KeyPair {
033: private byte[] prv_array;
034: private byte[] pub_array;
035: private byte[] n_array;
036:
037: private byte[] p_array; // prime p
038: private byte[] q_array; // prime q
039: private byte[] ep_array; // prime exponent p
040: private byte[] eq_array; // prime exponent q
041: private byte[] c_array; // coefficient
042:
043: //private int key_size=0;
044: private int key_size = 1024;
045:
046: public KeyPairRSA(JSch jsch) {
047: super (jsch);
048: }
049:
050: void generate(int key_size) throws JSchException {
051: this .key_size = key_size;
052: try {
053: Class c = Class.forName(jsch.getConfig("keypairgen.rsa"));
054: KeyPairGenRSA keypairgen = (KeyPairGenRSA) (c.newInstance());
055: keypairgen.init(key_size);
056: pub_array = keypairgen.getE();
057: prv_array = keypairgen.getD();
058: n_array = keypairgen.getN();
059:
060: p_array = keypairgen.getP();
061: q_array = keypairgen.getQ();
062: ep_array = keypairgen.getEP();
063: eq_array = keypairgen.getEQ();
064: c_array = keypairgen.getC();
065:
066: keypairgen = null;
067: } catch (Exception e) {
068: //System.err.println("KeyPairRSA: "+e);
069: if (e instanceof Throwable)
070: throw new JSchException(e.toString(), (Throwable) e);
071: throw new JSchException(e.toString());
072: }
073: }
074:
075: private static final byte[] begin = "-----BEGIN RSA PRIVATE KEY-----"
076: .getBytes();
077: private static final byte[] end = "-----END RSA PRIVATE KEY-----"
078: .getBytes();
079:
080: byte[] getBegin() {
081: return begin;
082: }
083:
084: byte[] getEnd() {
085: return end;
086: }
087:
088: byte[] getPrivateKey() {
089: int content = 1 + countLength(1) + 1 + // INTEGER
090: 1 + countLength(n_array.length) + n_array.length + // INTEGER N
091: 1 + countLength(pub_array.length) + pub_array.length + // INTEGER pub
092: 1 + countLength(prv_array.length) + prv_array.length + // INTEGER prv
093: 1 + countLength(p_array.length) + p_array.length + // INTEGER p
094: 1 + countLength(q_array.length) + q_array.length + // INTEGER q
095: 1 + countLength(ep_array.length) + ep_array.length + // INTEGER ep
096: 1 + countLength(eq_array.length) + eq_array.length + // INTEGER eq
097: 1 + countLength(c_array.length) + c_array.length; // INTEGER c
098:
099: int total = 1 + countLength(content) + content; // SEQUENCE
100:
101: byte[] plain = new byte[total];
102: int index = 0;
103: index = writeSEQUENCE(plain, index, content);
104: index = writeINTEGER(plain, index, new byte[1]); // 0
105: index = writeINTEGER(plain, index, n_array);
106: index = writeINTEGER(plain, index, pub_array);
107: index = writeINTEGER(plain, index, prv_array);
108: index = writeINTEGER(plain, index, p_array);
109: index = writeINTEGER(plain, index, q_array);
110: index = writeINTEGER(plain, index, ep_array);
111: index = writeINTEGER(plain, index, eq_array);
112: index = writeINTEGER(plain, index, c_array);
113: return plain;
114: }
115:
116: boolean parse(byte[] plain) {
117: /*
118: byte[] p_array;
119: byte[] q_array;
120: byte[] dmp1_array;
121: byte[] dmq1_array;
122: byte[] iqmp_array;
123: */
124: try {
125: int index = 0;
126: int length = 0;
127:
128: if (vendor == VENDOR_FSECURE) {
129: if (plain[index] != 0x30) { // FSecure
130: Buffer buf = new Buffer(plain);
131: pub_array = buf.getMPIntBits();
132: prv_array = buf.getMPIntBits();
133: n_array = buf.getMPIntBits();
134: byte[] u_array = buf.getMPIntBits();
135: p_array = buf.getMPIntBits();
136: q_array = buf.getMPIntBits();
137: return true;
138: }
139: return false;
140: }
141:
142: index++; // SEQUENCE
143: length = plain[index++] & 0xff;
144: if ((length & 0x80) != 0) {
145: int foo = length & 0x7f;
146: length = 0;
147: while (foo-- > 0) {
148: length = (length << 8) + (plain[index++] & 0xff);
149: }
150: }
151:
152: if (plain[index] != 0x02)
153: return false;
154: index++; // INTEGER
155: length = plain[index++] & 0xff;
156: if ((length & 0x80) != 0) {
157: int foo = length & 0x7f;
158: length = 0;
159: while (foo-- > 0) {
160: length = (length << 8) + (plain[index++] & 0xff);
161: }
162: }
163: index += length;
164:
165: //System.err.println("int: len="+length);
166: //System.err.print(Integer.toHexString(plain[index-1]&0xff)+":");
167: //System.err.println("");
168:
169: index++;
170: length = plain[index++] & 0xff;
171: if ((length & 0x80) != 0) {
172: int foo = length & 0x7f;
173: length = 0;
174: while (foo-- > 0) {
175: length = (length << 8) + (plain[index++] & 0xff);
176: }
177: }
178: n_array = new byte[length];
179: System.arraycopy(plain, index, n_array, 0, length);
180: index += length;
181: /*
182: System.err.println("int: N len="+length);
183: for(int i=0; i<n_array.length; i++){
184: System.err.print(Integer.toHexString(n_array[i]&0xff)+":");
185: }
186: System.err.println("");
187: */
188: index++;
189: length = plain[index++] & 0xff;
190: if ((length & 0x80) != 0) {
191: int foo = length & 0x7f;
192: length = 0;
193: while (foo-- > 0) {
194: length = (length << 8) + (plain[index++] & 0xff);
195: }
196: }
197: pub_array = new byte[length];
198: System.arraycopy(plain, index, pub_array, 0, length);
199: index += length;
200: /*
201: System.err.println("int: E len="+length);
202: for(int i=0; i<pub_array.length; i++){
203: System.err.print(Integer.toHexString(pub_array[i]&0xff)+":");
204: }
205: System.err.println("");
206: */
207: index++;
208: length = plain[index++] & 0xff;
209: if ((length & 0x80) != 0) {
210: int foo = length & 0x7f;
211: length = 0;
212: while (foo-- > 0) {
213: length = (length << 8) + (plain[index++] & 0xff);
214: }
215: }
216: prv_array = new byte[length];
217: System.arraycopy(plain, index, prv_array, 0, length);
218: index += length;
219: /*
220: System.err.println("int: prv len="+length);
221: for(int i=0; i<prv_array.length; i++){
222: System.err.print(Integer.toHexString(prv_array[i]&0xff)+":");
223: }
224: System.err.println("");
225: */
226:
227: index++;
228: length = plain[index++] & 0xff;
229: if ((length & 0x80) != 0) {
230: int foo = length & 0x7f;
231: length = 0;
232: while (foo-- > 0) {
233: length = (length << 8) + (plain[index++] & 0xff);
234: }
235: }
236: p_array = new byte[length];
237: System.arraycopy(plain, index, p_array, 0, length);
238: index += length;
239: /*
240: System.err.println("int: P len="+length);
241: for(int i=0; i<p_array.length; i++){
242: System.err.print(Integer.toHexString(p_array[i]&0xff)+":");
243: }
244: System.err.println("");
245: */
246: index++;
247: length = plain[index++] & 0xff;
248: if ((length & 0x80) != 0) {
249: int foo = length & 0x7f;
250: length = 0;
251: while (foo-- > 0) {
252: length = (length << 8) + (plain[index++] & 0xff);
253: }
254: }
255: q_array = new byte[length];
256: System.arraycopy(plain, index, q_array, 0, length);
257: index += length;
258: /*
259: System.err.println("int: q len="+length);
260: for(int i=0; i<q_array.length; i++){
261: System.err.print(Integer.toHexString(q_array[i]&0xff)+":");
262: }
263: System.err.println("");
264: */
265: index++;
266: length = plain[index++] & 0xff;
267: if ((length & 0x80) != 0) {
268: int foo = length & 0x7f;
269: length = 0;
270: while (foo-- > 0) {
271: length = (length << 8) + (plain[index++] & 0xff);
272: }
273: }
274: ep_array = new byte[length];
275: System.arraycopy(plain, index, ep_array, 0, length);
276: index += length;
277: /*
278: System.err.println("int: ep len="+length);
279: for(int i=0; i<ep_array.length; i++){
280: System.err.print(Integer.toHexString(ep_array[i]&0xff)+":");
281: }
282: System.err.println("");
283: */
284: index++;
285: length = plain[index++] & 0xff;
286: if ((length & 0x80) != 0) {
287: int foo = length & 0x7f;
288: length = 0;
289: while (foo-- > 0) {
290: length = (length << 8) + (plain[index++] & 0xff);
291: }
292: }
293: eq_array = new byte[length];
294: System.arraycopy(plain, index, eq_array, 0, length);
295: index += length;
296: /*
297: System.err.println("int: eq len="+length);
298: for(int i=0; i<eq_array.length; i++){
299: System.err.print(Integer.toHexString(eq_array[i]&0xff)+":");
300: }
301: System.err.println("");
302: */
303: index++;
304: length = plain[index++] & 0xff;
305: if ((length & 0x80) != 0) {
306: int foo = length & 0x7f;
307: length = 0;
308: while (foo-- > 0) {
309: length = (length << 8) + (plain[index++] & 0xff);
310: }
311: }
312: c_array = new byte[length];
313: System.arraycopy(plain, index, c_array, 0, length);
314: index += length;
315: /*
316: System.err.println("int: c len="+length);
317: for(int i=0; i<c_array.length; i++){
318: System.err.print(Integer.toHexString(c_array[i]&0xff)+":");
319: }
320: System.err.println("");
321: */
322: } catch (Exception e) {
323: //System.err.println(e);
324: return false;
325: }
326: return true;
327: }
328:
329: public byte[] getPublicKeyBlob() {
330: byte[] foo = super .getPublicKeyBlob();
331: if (foo != null)
332: return foo;
333:
334: if (pub_array == null)
335: return null;
336:
337: Buffer buf = new Buffer(sshrsa.length + 4 + pub_array.length
338: + 4 + n_array.length + 4);
339: buf.putString(sshrsa);
340: buf.putString(pub_array);
341: buf.putString(n_array);
342: return buf.buffer;
343: }
344:
345: private static final byte[] sshrsa = "ssh-rsa".getBytes();
346:
347: byte[] getKeyTypeName() {
348: return sshrsa;
349: }
350:
351: public int getKeyType() {
352: return RSA;
353: }
354:
355: public int getKeySize() {
356: return key_size;
357: }
358:
359: public void dispose() {
360: super.dispose();
361: Util.bzero(prv_array);
362: }
363: }
|