]>
Commit | Line | Data |
---|---|---|
1 | /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ | |
2 | /* | |
3 | Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved. | |
4 | ||
5 | Redistribution and use in source and binary forms, with or without | |
6 | modification, are permitted provided that the following conditions are met: | |
7 | ||
8 | 1. Redistributions of source code must retain the above copyright notice, | |
9 | this list of conditions and the following disclaimer. | |
10 | ||
11 | 2. Redistributions in binary form must reproduce the above copyright | |
12 | notice, this list of conditions and the following disclaimer in | |
13 | the documentation and/or other materials provided with the distribution. | |
14 | ||
15 | 3. The names of the authors may not be used to endorse or promote products | |
16 | derived from this software without specific prior written permission. | |
17 | ||
18 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | |
19 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
20 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | |
21 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
24 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | |
29 | ||
30 | package com.jcraft.jsch; | |
31 | ||
32 | public class KeyPairRSA extends KeyPair{ | |
33 | private byte[] prv_array; | |
34 | private byte[] pub_array; | |
35 | private byte[] n_array; | |
36 | ||
37 | private byte[] p_array; // prime p | |
38 | private byte[] q_array; // prime q | |
39 | private byte[] ep_array; // prime exponent p | |
40 | private byte[] eq_array; // prime exponent q | |
41 | private byte[] c_array; // coefficient | |
42 | ||
43 | //private int key_size=0; | |
44 | private int key_size=1024; | |
45 | ||
46 | public KeyPairRSA(JSch jsch){ | |
47 | super(jsch); | |
48 | } | |
49 | ||
50 | void generate(int key_size) throws JSchException{ | |
51 | this.key_size=key_size; | |
52 | try{ | |
53 | Class c=Class.forName(jsch.getConfig("keypairgen.rsa")); | |
54 | KeyPairGenRSA keypairgen=(KeyPairGenRSA)(c.newInstance()); | |
55 | keypairgen.init(key_size); | |
56 | pub_array=keypairgen.getE(); | |
57 | prv_array=keypairgen.getD(); | |
58 | n_array=keypairgen.getN(); | |
59 | ||
60 | p_array=keypairgen.getP(); | |
61 | q_array=keypairgen.getQ(); | |
62 | ep_array=keypairgen.getEP(); | |
63 | eq_array=keypairgen.getEQ(); | |
64 | c_array=keypairgen.getC(); | |
65 | ||
66 | keypairgen=null; | |
67 | } | |
68 | catch(Exception e){ | |
69 | //System.err.println("KeyPairRSA: "+e); | |
70 | if(e instanceof Throwable) | |
71 | throw new JSchException(e.toString(), (Throwable)e); | |
72 | throw new JSchException(e.toString()); | |
73 | } | |
74 | } | |
75 | ||
76 | private static final byte[] begin=Util.str2byte("-----BEGIN RSA PRIVATE KEY-----"); | |
77 | private static final byte[] end=Util.str2byte("-----END RSA PRIVATE KEY-----"); | |
78 | ||
79 | byte[] getBegin(){ return begin; } | |
80 | byte[] getEnd(){ return end; } | |
81 | ||
82 | byte[] getPrivateKey(){ | |
83 | int content= | |
84 | 1+countLength(1) + 1 + // INTEGER | |
85 | 1+countLength(n_array.length) + n_array.length + // INTEGER N | |
86 | 1+countLength(pub_array.length) + pub_array.length + // INTEGER pub | |
87 | 1+countLength(prv_array.length) + prv_array.length+ // INTEGER prv | |
88 | 1+countLength(p_array.length) + p_array.length+ // INTEGER p | |
89 | 1+countLength(q_array.length) + q_array.length+ // INTEGER q | |
90 | 1+countLength(ep_array.length) + ep_array.length+ // INTEGER ep | |
91 | 1+countLength(eq_array.length) + eq_array.length+ // INTEGER eq | |
92 | 1+countLength(c_array.length) + c_array.length; // INTEGER c | |
93 | ||
94 | int total= | |
95 | 1+countLength(content)+content; // SEQUENCE | |
96 | ||
97 | byte[] plain=new byte[total]; | |
98 | int index=0; | |
99 | index=writeSEQUENCE(plain, index, content); | |
100 | index=writeINTEGER(plain, index, new byte[1]); // 0 | |
101 | index=writeINTEGER(plain, index, n_array); | |
102 | index=writeINTEGER(plain, index, pub_array); | |
103 | index=writeINTEGER(plain, index, prv_array); | |
104 | index=writeINTEGER(plain, index, p_array); | |
105 | index=writeINTEGER(plain, index, q_array); | |
106 | index=writeINTEGER(plain, index, ep_array); | |
107 | index=writeINTEGER(plain, index, eq_array); | |
108 | index=writeINTEGER(plain, index, c_array); | |
109 | return plain; | |
110 | } | |
111 | ||
112 | boolean parse(byte [] plain){ | |
113 | /* | |
114 | byte[] p_array; | |
115 | byte[] q_array; | |
116 | byte[] dmp1_array; | |
117 | byte[] dmq1_array; | |
118 | byte[] iqmp_array; | |
119 | */ | |
120 | try{ | |
121 | int index=0; | |
122 | int length=0; | |
123 | ||
124 | if(vendor==VENDOR_FSECURE){ | |
125 | if(plain[index]!=0x30){ // FSecure | |
126 | Buffer buf=new Buffer(plain); | |
127 | pub_array=buf.getMPIntBits(); | |
128 | prv_array=buf.getMPIntBits(); | |
129 | n_array=buf.getMPIntBits(); | |
130 | byte[] u_array=buf.getMPIntBits(); | |
131 | p_array=buf.getMPIntBits(); | |
132 | q_array=buf.getMPIntBits(); | |
133 | return true; | |
134 | } | |
135 | return false; | |
136 | } | |
137 | ||
138 | index++; // SEQUENCE | |
139 | length=plain[index++]&0xff; | |
140 | if((length&0x80)!=0){ | |
141 | int foo=length&0x7f; length=0; | |
142 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
143 | } | |
144 | ||
145 | if(plain[index]!=0x02)return false; | |
146 | index++; // INTEGER | |
147 | length=plain[index++]&0xff; | |
148 | if((length&0x80)!=0){ | |
149 | int foo=length&0x7f; length=0; | |
150 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
151 | } | |
152 | index+=length; | |
153 | ||
154 | //System.err.println("int: len="+length); | |
155 | //System.err.print(Integer.toHexString(plain[index-1]&0xff)+":"); | |
156 | //System.err.println(""); | |
157 | ||
158 | index++; | |
159 | length=plain[index++]&0xff; | |
160 | if((length&0x80)!=0){ | |
161 | int foo=length&0x7f; length=0; | |
162 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
163 | } | |
164 | n_array=new byte[length]; | |
165 | System.arraycopy(plain, index, n_array, 0, length); | |
166 | index+=length; | |
167 | /* | |
168 | System.err.println("int: N len="+length); | |
169 | for(int i=0; i<n_array.length; i++){ | |
170 | System.err.print(Integer.toHexString(n_array[i]&0xff)+":"); | |
171 | } | |
172 | System.err.println(""); | |
173 | */ | |
174 | index++; | |
175 | length=plain[index++]&0xff; | |
176 | if((length&0x80)!=0){ | |
177 | int foo=length&0x7f; length=0; | |
178 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
179 | } | |
180 | pub_array=new byte[length]; | |
181 | System.arraycopy(plain, index, pub_array, 0, length); | |
182 | index+=length; | |
183 | /* | |
184 | System.err.println("int: E len="+length); | |
185 | for(int i=0; i<pub_array.length; i++){ | |
186 | System.err.print(Integer.toHexString(pub_array[i]&0xff)+":"); | |
187 | } | |
188 | System.err.println(""); | |
189 | */ | |
190 | index++; | |
191 | length=plain[index++]&0xff; | |
192 | if((length&0x80)!=0){ | |
193 | int foo=length&0x7f; length=0; | |
194 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
195 | } | |
196 | prv_array=new byte[length]; | |
197 | System.arraycopy(plain, index, prv_array, 0, length); | |
198 | index+=length; | |
199 | /* | |
200 | System.err.println("int: prv len="+length); | |
201 | for(int i=0; i<prv_array.length; i++){ | |
202 | System.err.print(Integer.toHexString(prv_array[i]&0xff)+":"); | |
203 | } | |
204 | System.err.println(""); | |
205 | */ | |
206 | ||
207 | index++; | |
208 | length=plain[index++]&0xff; | |
209 | if((length&0x80)!=0){ | |
210 | int foo=length&0x7f; length=0; | |
211 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
212 | } | |
213 | p_array=new byte[length]; | |
214 | System.arraycopy(plain, index, p_array, 0, length); | |
215 | index+=length; | |
216 | /* | |
217 | System.err.println("int: P len="+length); | |
218 | for(int i=0; i<p_array.length; i++){ | |
219 | System.err.print(Integer.toHexString(p_array[i]&0xff)+":"); | |
220 | } | |
221 | System.err.println(""); | |
222 | */ | |
223 | index++; | |
224 | length=plain[index++]&0xff; | |
225 | if((length&0x80)!=0){ | |
226 | int foo=length&0x7f; length=0; | |
227 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
228 | } | |
229 | q_array=new byte[length]; | |
230 | System.arraycopy(plain, index, q_array, 0, length); | |
231 | index+=length; | |
232 | /* | |
233 | System.err.println("int: q len="+length); | |
234 | for(int i=0; i<q_array.length; i++){ | |
235 | System.err.print(Integer.toHexString(q_array[i]&0xff)+":"); | |
236 | } | |
237 | System.err.println(""); | |
238 | */ | |
239 | index++; | |
240 | length=plain[index++]&0xff; | |
241 | if((length&0x80)!=0){ | |
242 | int foo=length&0x7f; length=0; | |
243 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
244 | } | |
245 | ep_array=new byte[length]; | |
246 | System.arraycopy(plain, index, ep_array, 0, length); | |
247 | index+=length; | |
248 | /* | |
249 | System.err.println("int: ep len="+length); | |
250 | for(int i=0; i<ep_array.length; i++){ | |
251 | System.err.print(Integer.toHexString(ep_array[i]&0xff)+":"); | |
252 | } | |
253 | System.err.println(""); | |
254 | */ | |
255 | index++; | |
256 | length=plain[index++]&0xff; | |
257 | if((length&0x80)!=0){ | |
258 | int foo=length&0x7f; length=0; | |
259 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
260 | } | |
261 | eq_array=new byte[length]; | |
262 | System.arraycopy(plain, index, eq_array, 0, length); | |
263 | index+=length; | |
264 | /* | |
265 | System.err.println("int: eq len="+length); | |
266 | for(int i=0; i<eq_array.length; i++){ | |
267 | System.err.print(Integer.toHexString(eq_array[i]&0xff)+":"); | |
268 | } | |
269 | System.err.println(""); | |
270 | */ | |
271 | index++; | |
272 | length=plain[index++]&0xff; | |
273 | if((length&0x80)!=0){ | |
274 | int foo=length&0x7f; length=0; | |
275 | while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } | |
276 | } | |
277 | c_array=new byte[length]; | |
278 | System.arraycopy(plain, index, c_array, 0, length); | |
279 | index+=length; | |
280 | /* | |
281 | System.err.println("int: c len="+length); | |
282 | for(int i=0; i<c_array.length; i++){ | |
283 | System.err.print(Integer.toHexString(c_array[i]&0xff)+":"); | |
284 | } | |
285 | System.err.println(""); | |
286 | */ | |
287 | } | |
288 | catch(Exception e){ | |
289 | //System.err.println(e); | |
290 | return false; | |
291 | } | |
292 | return true; | |
293 | } | |
294 | ||
295 | ||
296 | public byte[] getPublicKeyBlob(){ | |
297 | byte[] foo=super.getPublicKeyBlob(); | |
298 | if(foo!=null) return foo; | |
299 | ||
300 | if(pub_array==null) return null; | |
301 | ||
302 | Buffer buf=new Buffer(sshrsa.length+4+ | |
303 | pub_array.length+4+ | |
304 | n_array.length+4); | |
305 | buf.putString(sshrsa); | |
306 | buf.putString(pub_array); | |
307 | buf.putString(n_array); | |
308 | return buf.buffer; | |
309 | } | |
310 | ||
311 | private static final byte[] sshrsa=Util.str2byte("ssh-rsa"); | |
312 | byte[] getKeyTypeName(){return sshrsa;} | |
313 | public int getKeyType(){return RSA;} | |
314 | ||
315 | public int getKeySize(){return key_size; } | |
316 | public void dispose(){ | |
317 | super.dispose(); | |
318 | Util.bzero(prv_array); | |
319 | } | |
320 | } |