Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4307 - (show annotations) (download) (as text)
Tue Feb 15 09:00:01 2011 UTC (13 years, 1 month ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 20946 byte(s)
鍵の種類を増やせるように整理した
  enum hostkey_type を ssh_keytype にリネームした
機能が重複している構造体・コードを削除した
  CRYPTKeyPair を削除、Key を使うようにした
  key_from_blob を使うようにした
1 /*
2 Copyright (c) 2011, TeraTerm Project
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other materials
13 provided with the distribution.
14
15 The name of Robert O'Callahan may not be used to endorse or promote products derived from
16 this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "ttxssh.h"
30 #include "key.h"
31
32 #include <openssl/rsa.h>
33 #include <openssl/dsa.h>
34
35 #define INTBLOB_LEN 20
36 #define SIGBLOB_LEN (2*INTBLOB_LEN)
37
38 //////////////////////////////////////////////////////////////////////////////
39 //
40 // Key verify function
41 //
42 //////////////////////////////////////////////////////////////////////////////
43
44 //
45 // DSS
46 //
47
48 int ssh_dss_verify(DSA *key,
49 u_char *signature, u_int signaturelen,
50 u_char *data, u_int datalen)
51 {
52 DSA_SIG *sig;
53 const EVP_MD *evp_md = EVP_sha1();
54 EVP_MD_CTX md;
55 unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
56 unsigned int len, dlen;
57 int ret;
58 char *ptr;
59
60 OpenSSL_add_all_digests();
61
62 if (key == NULL) {
63 return -2;
64 }
65
66 ptr = signature;
67
68 // step1
69 if (signaturelen == 0x28) {
70 // workaround for SSH-2.0-2.0* and SSH-2.0-2.1* (2006.11.18 maya)
71 ptr -= 4;
72 }
73 else {
74 len = get_uint32_MSBfirst(ptr);
75 ptr += 4;
76 if (strncmp("ssh-dss", ptr, len) != 0) {
77 return -3;
78 }
79 ptr += len;
80 }
81
82 // step2
83 len = get_uint32_MSBfirst(ptr);
84 ptr += 4;
85 sigblob = ptr;
86 ptr += len;
87
88 if (len != SIGBLOB_LEN) {
89 return -4;
90 }
91
92 /* parse signature */
93 if ((sig = DSA_SIG_new()) == NULL)
94 return -5;
95 if ((sig->r = BN_new()) == NULL)
96 return -6;
97 if ((sig->s = BN_new()) == NULL)
98 return -7;
99 BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
100 BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
101
102 /* sha1 the data */
103 EVP_DigestInit(&md, evp_md);
104 EVP_DigestUpdate(&md, data, datalen);
105 EVP_DigestFinal(&md, digest, &dlen);
106
107 ret = DSA_do_verify(digest, dlen, sig, key);
108 memset(digest, 'd', sizeof(digest));
109
110 DSA_SIG_free(sig);
111
112 return ret;
113 }
114
115
116 //
117 // RSA
118 //
119
120 /*
121 * See:
122 * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
123 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
124 */
125 /*
126 * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
127 * oiw(14) secsig(3) algorithms(2) 26 }
128 */
129 static const u_char id_sha1[] = {
130 0x30, 0x21, /* type Sequence, length 0x21 (33) */
131 0x30, 0x09, /* type Sequence, length 0x09 */
132 0x06, 0x05, /* type OID, length 0x05 */
133 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
134 0x05, 0x00, /* NULL */
135 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
136 };
137 /*
138 * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
139 * rsadsi(113549) digestAlgorithm(2) 5 }
140 */
141 static const u_char id_md5[] = {
142 0x30, 0x20, /* type Sequence, length 0x20 (32) */
143 0x30, 0x0c, /* type Sequence, length 0x09 */
144 0x06, 0x08, /* type OID, length 0x05 */
145 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
146 0x05, 0x00, /* NULL */
147 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
148 };
149
150 static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
151 u_char *sigbuf, u_int siglen, RSA *rsa)
152 {
153 u_int ret, rsasize, oidlen = 0, hlen = 0;
154 int len;
155 const u_char *oid = NULL;
156 u_char *decrypted = NULL;
157
158 ret = 0;
159 switch (type) {
160 case NID_sha1:
161 oid = id_sha1;
162 oidlen = sizeof(id_sha1);
163 hlen = 20;
164 break;
165 case NID_md5:
166 oid = id_md5;
167 oidlen = sizeof(id_md5);
168 hlen = 16;
169 break;
170 default:
171 goto done;
172 break;
173 }
174 if (hashlen != hlen) {
175 //error("bad hashlen");
176 goto done;
177 }
178 rsasize = RSA_size(rsa);
179 if (siglen == 0 || siglen > rsasize) {
180 //error("bad siglen");
181 goto done;
182 }
183 decrypted = malloc(rsasize);
184 if (decrypted == NULL)
185 return 1; // error
186
187 if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
188 RSA_PKCS1_PADDING)) < 0) {
189 //error("RSA_public_decrypt failed: %s",
190 // ERR_error_string(ERR_get_error(), NULL));
191 goto done;
192 }
193 if (len != hlen + oidlen) {
194 //error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
195 goto done;
196 }
197 if (memcmp(decrypted, oid, oidlen) != 0) {
198 //error("oid mismatch");
199 goto done;
200 }
201 if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
202 //error("hash mismatch");
203 goto done;
204 }
205 ret = 1;
206 done:
207 if (decrypted)
208 free(decrypted);
209 return ret;
210 }
211
212 int ssh_rsa_verify(RSA *key,
213 u_char *signature, u_int signaturelen,
214 u_char *data, u_int datalen)
215 {
216 const EVP_MD *evp_md;
217 EVP_MD_CTX md;
218 // char *ktype;
219 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
220 u_int len, dlen, modlen;
221 // int rlen, ret, nid;
222 int ret, nid;
223 char *ptr;
224
225 OpenSSL_add_all_digests();
226
227 if (key == NULL) {
228 return -2;
229 }
230 if (BN_num_bits(key->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
231 return -3;
232 }
233 //debug_print(41, signature, signaturelen);
234 ptr = signature;
235
236 // step1
237 len = get_uint32_MSBfirst(ptr);
238 ptr += 4;
239 if (strncmp("ssh-rsa", ptr, len) != 0) {
240 return -4;
241 }
242 ptr += len;
243
244 // step2
245 len = get_uint32_MSBfirst(ptr);
246 ptr += 4;
247 sigblob = ptr;
248 ptr += len;
249 #if 0
250 rlen = get_uint32_MSBfirst(ptr);
251 if (rlen != 0) {
252 return -1;
253 }
254 #endif
255
256 /* RSA_verify expects a signature of RSA_size */
257 modlen = RSA_size(key);
258 if (len > modlen) {
259 return -5;
260
261 } else if (len < modlen) {
262 u_int diff = modlen - len;
263 sigblob = realloc(sigblob, modlen);
264 memmove(sigblob + diff, sigblob, len);
265 memset(sigblob, 0, diff);
266 len = modlen;
267 }
268
269 /* sha1 the data */
270 // nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
271 nid = NID_sha1;
272 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
273 //error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
274 return -6;
275 }
276 EVP_DigestInit(&md, evp_md);
277 EVP_DigestUpdate(&md, data, datalen);
278 EVP_DigestFinal(&md, digest, &dlen);
279
280 ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key);
281
282 memset(digest, 'd', sizeof(digest));
283 memset(sigblob, 's', len);
284 //free(sigblob);
285 //debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
286
287 return ret;
288 }
289
290 int key_verify(Key *key,
291 unsigned char *signature, unsigned int signaturelen,
292 unsigned char *data, unsigned int datalen)
293 {
294 int ret = 0;
295
296 if (key->type == KEY_RSA) {
297 ret = ssh_rsa_verify(key->rsa, signature, signaturelen, data, datalen);
298
299 }
300 else if (key->type == KEY_DSA) {
301 ret = ssh_dss_verify(key->dsa, signature, signaturelen, data, datalen);
302
303 }
304 else {
305 return -1;
306 }
307
308 return (ret); // success
309 }
310
311 //
312 // RSA�\����������
313 //
314 RSA *duplicate_RSA(RSA *src)
315 {
316 RSA *rsa = NULL;
317
318 rsa = RSA_new();
319 if (rsa == NULL)
320 goto error;
321 rsa->n = BN_new();
322 rsa->e = BN_new();
323 if (rsa->n == NULL || rsa->e == NULL) {
324 RSA_free(rsa);
325 goto error;
326 }
327
328 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
329 BN_copy(rsa->n, src->n);
330 BN_copy(rsa->e, src->e);
331
332 error:
333 return (rsa);
334 }
335
336
337 //
338 // DSA�\����������
339 //
340 DSA *duplicate_DSA(DSA *src)
341 {
342 DSA *dsa = NULL;
343
344 dsa = DSA_new();
345 if (dsa == NULL)
346 goto error;
347 dsa->p = BN_new();
348 dsa->q = BN_new();
349 dsa->g = BN_new();
350 dsa->pub_key = BN_new();
351 if (dsa->p == NULL ||
352 dsa->q == NULL ||
353 dsa->g == NULL ||
354 dsa->pub_key == NULL) {
355 DSA_free(dsa);
356 goto error;
357 }
358
359 // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
360 BN_copy(dsa->p, src->p);
361 BN_copy(dsa->q, src->q);
362 BN_copy(dsa->g, src->g);
363 BN_copy(dsa->pub_key, src->pub_key);
364
365 error:
366 return (dsa);
367 }
368
369
370 char* key_fingerprint_raw(Key *k, int *dgst_raw_length)
371 {
372 const EVP_MD *md = NULL;
373 EVP_MD_CTX ctx;
374 char *blob = NULL;
375 char *retval = NULL;
376 int len = 0;
377 int nlen, elen;
378 RSA *rsa;
379
380 *dgst_raw_length = 0;
381
382 // MD5�A���S���Y�����g�p����
383 md = EVP_md5();
384
385 switch (k->type) {
386 case KEY_RSA1:
387 rsa = make_key(NULL, k->bits, k->exp, k->mod);
388 nlen = BN_num_bytes(rsa->n);
389 elen = BN_num_bytes(rsa->e);
390 len = nlen + elen;
391 blob = malloc(len);
392 if (blob == NULL) {
393 // TODO:
394 }
395 BN_bn2bin(rsa->n, blob);
396 BN_bn2bin(rsa->e, blob + nlen);
397 RSA_free(rsa);
398 break;
399
400 case KEY_DSA:
401 case KEY_RSA:
402 key_to_blob(k, &blob, &len);
403 break;
404
405 case KEY_UNSPEC:
406 return retval;
407 break;
408
409 default:
410 //fatal("key_fingerprint_raw: bad key type %d", k->type);
411 break;
412 }
413
414 if (blob != NULL) {
415 retval = malloc(EVP_MAX_MD_SIZE);
416 if (retval == NULL) {
417 // TODO:
418 }
419 EVP_DigestInit(&ctx, md);
420 EVP_DigestUpdate(&ctx, blob, len);
421 EVP_DigestFinal(&ctx, retval, dgst_raw_length);
422 memset(blob, 0, len);
423 free(blob);
424 } else {
425 //fatal("key_fingerprint_raw: blob is null");
426 }
427 return retval;
428 }
429
430
431 const char *
432 key_type(const Key *k)
433 {
434 switch (k->type) {
435 case KEY_RSA1:
436 return "RSA1";
437 case KEY_RSA:
438 return "RSA";
439 case KEY_DSA:
440 return "DSA";
441 }
442 return "unknown";
443 }
444
445 unsigned int
446 key_size(const Key *k)
447 {
448 switch (k->type) {
449 case KEY_RSA1:
450 // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
451 return k->bits;
452 case KEY_RSA:
453 return BN_num_bits(k->rsa->n);
454 case KEY_DSA:
455 return BN_num_bits(k->dsa->p);
456 }
457 return 0;
458 }
459
460 // based on OpenSSH 5.1
461 #define FLDBASE 8
462 #define FLDSIZE_Y (FLDBASE + 1)
463 #define FLDSIZE_X (FLDBASE * 2 + 1)
464 static char *
465 key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
466 {
467 /*
468 * Chars to be used after each other every time the worm
469 * intersects with itself. Matter of taste.
470 */
471 char *augmentation_string = " .o+=*BOX@%&#/^SE";
472 char *retval, *p;
473 unsigned char field[FLDSIZE_X][FLDSIZE_Y];
474 unsigned int i, b;
475 int x, y;
476 size_t len = strlen(augmentation_string) - 1;
477
478 retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
479
480 /* initialize field */
481 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
482 x = FLDSIZE_X / 2;
483 y = FLDSIZE_Y / 2;
484
485 /* process raw key */
486 for (i = 0; i < dgst_raw_len; i++) {
487 int input;
488 /* each byte conveys four 2-bit move commands */
489 input = dgst_raw[i];
490 for (b = 0; b < 4; b++) {
491 /* evaluate 2 bit, rest is shifted later */
492 x += (input & 0x1) ? 1 : -1;
493 y += (input & 0x2) ? 1 : -1;
494
495 /* assure we are still in bounds */
496 x = max(x, 0);
497 y = max(y, 0);
498 x = min(x, FLDSIZE_X - 1);
499 y = min(y, FLDSIZE_Y - 1);
500
501 /* augment the field */
502 field[x][y]++;
503 input = input >> 2;
504 }
505 }
506
507 /* mark starting point and end point*/
508 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
509 field[x][y] = len;
510
511 /* fill in retval */
512 _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k));
513 p = strchr(retval, '\0');
514
515 /* output upper border */
516 for (i = p - retval - 1; i < FLDSIZE_X; i++)
517 *p++ = '-';
518 *p++ = '+';
519 *p++ = '\r';
520 *p++ = '\n';
521
522 /* output content */
523 for (y = 0; y < FLDSIZE_Y; y++) {
524 *p++ = '|';
525 for (x = 0; x < FLDSIZE_X; x++)
526 *p++ = augmentation_string[min(field[x][y], len)];
527 *p++ = '|';
528 *p++ = '\r';
529 *p++ = '\n';
530 }
531
532 /* output lower border */
533 *p++ = '+';
534 for (i = 0; i < FLDSIZE_X; i++)
535 *p++ = '-';
536 *p++ = '+';
537
538 return retval;
539 }
540 #undef FLDBASE
541 #undef FLDSIZE_Y
542 #undef FLDSIZE_X
543
544 //
545 // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
546 //
547 char *key_fingerprint(Key *key, enum fp_rep dgst_rep)
548 {
549 char *retval = NULL;
550 unsigned char *dgst_raw;
551 int dgst_raw_len;
552 int i, retval_len;
553
554 // fingerprint���n�b�V���l�i�o�C�i���j��������
555 dgst_raw = key_fingerprint_raw(key, &dgst_raw_len);
556
557 if (dgst_rep == SSH_FP_HEX) {
558 // 16�i�\�L����������
559 retval_len = dgst_raw_len * 3 + 1;
560 retval = malloc(retval_len);
561 retval[0] = '\0';
562 for (i = 0; i < dgst_raw_len; i++) {
563 char hex[4];
564 _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
565 strncat_s(retval, retval_len, hex, _TRUNCATE);
566 }
567
568 /* Remove the trailing ':' character */
569 retval[(dgst_raw_len * 3) - 1] = '\0';
570
571 } else if (dgst_rep == SSH_FP_RANDOMART) {
572 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
573
574 } else {
575
576 }
577
578 memset(dgst_raw, 0, dgst_raw_len);
579 free(dgst_raw);
580
581 return (retval);
582 }
583
584
585 //
586 // �L�[����������������
587 //
588 void key_free(Key *key)
589 {
590 switch (key->type) {
591 case KEY_RSA1:
592 case KEY_RSA:
593 if (key->rsa != NULL)
594 RSA_free(key->rsa);
595 key->rsa = NULL;
596 break;
597
598 case KEY_DSA:
599 if (key->dsa != NULL)
600 DSA_free(key->dsa);
601 key->dsa = NULL;
602 break;
603 }
604 free(key);
605 }
606
607 //
608 // �L�[���������������p����
609 //
610 char *get_sshname_from_key(Key *key)
611 {
612 if (key->type == KEY_RSA) {
613 return "ssh-rsa";
614 } else if (key->type == KEY_DSA) {
615 return "ssh-dss";
616 } else {
617 return "ssh-unknown";
618 }
619 }
620
621
622 //
623 // �L�[������������������������
624 //
625 enum ssh_keytype get_keytype_from_name(char *name)
626 {
627 if (strcmp(name, "rsa1") == 0) {
628 return KEY_RSA1;
629 } else if (strcmp(name, "rsa") == 0) {
630 return KEY_RSA;
631 } else if (strcmp(name, "dsa") == 0) {
632 return KEY_DSA;
633 } else if (strcmp(name, "ssh-rsa") == 0) {
634 return KEY_RSA;
635 } else if (strcmp(name, "ssh-dss") == 0) {
636 return KEY_DSA;
637 }
638 return KEY_UNSPEC;
639 }
640
641
642 //
643 // �L�[���������o�b�t�@���������� (for SSH2)
644 // NOTE:
645 //
646 int key_to_blob(Key *key, char **blobp, int *lenp)
647 {
648 buffer_t *b;
649 char *sshname;
650 int len;
651 int ret = 1; // success
652
653 b = buffer_init();
654 sshname = get_sshname_from_key(key);
655
656 if (key->type == KEY_RSA) {
657 buffer_put_string(b, sshname, strlen(sshname));
658 buffer_put_bignum2(b, key->rsa->e);
659 buffer_put_bignum2(b, key->rsa->n);
660
661 } else if (key->type == KEY_DSA) {
662 buffer_put_string(b, sshname, strlen(sshname));
663 buffer_put_bignum2(b, key->dsa->p);
664 buffer_put_bignum2(b, key->dsa->q);
665 buffer_put_bignum2(b, key->dsa->g);
666 buffer_put_bignum2(b, key->dsa->pub_key);
667
668 } else {
669 ret = 0;
670 goto error;
671
672 }
673
674 len = buffer_len(b);
675 if (lenp != NULL)
676 *lenp = len;
677 if (blobp != NULL) {
678 *blobp = malloc(len);
679 if (*blobp == NULL) {
680 ret = 0;
681 goto error;
682 }
683 memcpy(*blobp, buffer_ptr(b), len);
684 }
685
686 error:
687 buffer_free(b);
688
689 return (ret);
690 }
691
692
693 //
694 // �o�b�t�@�����L�[�����������o��(for SSH2)
695 // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
696 //
697 Key *key_from_blob(char *data, int blen)
698 {
699 int keynamelen;
700 char key[128];
701 RSA *rsa = NULL;
702 DSA *dsa = NULL;
703 Key *hostkey; // hostkey
704 enum ssh_keytype type;
705
706 hostkey = malloc(sizeof(Key));
707 if (hostkey == NULL)
708 goto error;
709
710 memset(hostkey, 0, sizeof(Key));
711
712 keynamelen = get_uint32_MSBfirst(data);
713 if (keynamelen >= sizeof(key)) {
714 goto error;
715 }
716 data += 4;
717 memcpy(key, data, keynamelen);
718 key[keynamelen] = 0;
719 data += keynamelen;
720
721 type = get_keytype_from_name(key);
722
723 if (type == KEY_RSA) { // RSA key
724 rsa = RSA_new();
725 if (rsa == NULL) {
726 goto error;
727 }
728 rsa->n = BN_new();
729 rsa->e = BN_new();
730 if (rsa->n == NULL || rsa->e == NULL) {
731 goto error;
732 }
733
734 buffer_get_bignum2(&data, rsa->e);
735 buffer_get_bignum2(&data, rsa->n);
736
737 hostkey->type = type;
738 hostkey->rsa = rsa;
739
740 }
741 else if (type == KEY_DSA) { // DSA key
742 dsa = DSA_new();
743 if (dsa == NULL) {
744 goto error;
745 }
746 dsa->p = BN_new();
747 dsa->q = BN_new();
748 dsa->g = BN_new();
749 dsa->pub_key = BN_new();
750 if (dsa->p == NULL ||
751 dsa->q == NULL ||
752 dsa->g == NULL ||
753 dsa->pub_key == NULL) {
754 goto error;
755 }
756
757 buffer_get_bignum2(&data, dsa->p);
758 buffer_get_bignum2(&data, dsa->q);
759 buffer_get_bignum2(&data, dsa->g);
760 buffer_get_bignum2(&data, dsa->pub_key);
761
762 hostkey->type = type;
763 hostkey->dsa = dsa;
764
765 } else {
766 // unknown key
767 goto error;
768
769 }
770
771 return (hostkey);
772
773 error:
774 if (rsa != NULL)
775 RSA_free(rsa);
776 if (dsa != NULL)
777 DSA_free(dsa);
778
779 return NULL;
780 }
781
782
783 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
784 {
785 buffer_t *msg = NULL;
786 char *s;
787
788 msg = buffer_init();
789 if (msg == NULL) {
790 // TODO: error check
791 return FALSE;
792 }
793
794 if (keypair->type == KEY_RSA) { // RSA
795 const EVP_MD *evp_md = EVP_sha1();
796 EVP_MD_CTX md;
797 u_char digest[EVP_MAX_MD_SIZE], *sig;
798 u_int slen, dlen, len;
799 int ok, nid = NID_sha1;
800
801 // �_�C�W�F�X�g�l���v�Z
802 EVP_DigestInit(&md, evp_md);
803 EVP_DigestUpdate(&md, data, datalen);
804 EVP_DigestFinal(&md, digest, &dlen);
805
806 slen = RSA_size(keypair->rsa);
807 sig = malloc(slen);
808 if (sig == NULL)
809 goto error;
810
811 // �d�q�������v�Z
812 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
813 memset(digest, 'd', sizeof(digest));
814 if (ok != 1) { // error
815 free(sig);
816 goto error;
817 }
818 // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
819 if (len < slen) {
820 u_int diff = slen - len;
821 memmove(sig + diff, sig, len);
822 memset(sig, 0, diff);
823
824 } else if (len > slen) {
825 free(sig);
826 goto error;
827
828 } else {
829 // do nothing
830
831 }
832
833 s = get_sshname_from_key(keypair);
834 buffer_put_string(msg, s, strlen(s));
835 buffer_append_length(msg, sig, slen);
836 len = buffer_len(msg);
837
838 // setting
839 *siglen = len;
840 *sigptr = malloc(len);
841 if (*sigptr == NULL) {
842 free(sig);
843 goto error;
844 }
845 memcpy(*sigptr, buffer_ptr(msg), len);
846 free(sig);
847
848 }
849 else if (keypair->type == KEY_DSA) { // DSA
850 DSA_SIG *sig;
851 const EVP_MD *evp_md = EVP_sha1();
852 EVP_MD_CTX md;
853 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
854 u_int rlen, slen, len, dlen;
855
856 // �_�C�W�F�X�g���v�Z
857 EVP_DigestInit(&md, evp_md);
858 EVP_DigestUpdate(&md, data, datalen);
859 EVP_DigestFinal(&md, digest, &dlen);
860
861 // DSA�d�q�������v�Z
862 sig = DSA_do_sign(digest, dlen, keypair->dsa);
863 memset(digest, 'd', sizeof(digest));
864 if (sig == NULL) {
865 goto error;
866 }
867
868 // BIGNUM�����o�C�i���l��������
869 rlen = BN_num_bytes(sig->r);
870 slen = BN_num_bytes(sig->s);
871 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
872 DSA_SIG_free(sig);
873 goto error;
874 }
875 memset(sigblob, 0, SIGBLOB_LEN);
876 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
877 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
878 DSA_SIG_free(sig);
879
880 // setting
881 s = get_sshname_from_key(keypair);
882 buffer_put_string(msg, s, strlen(s));
883 buffer_append_length(msg, sigblob, sizeof(sigblob));
884 len = buffer_len(msg);
885
886 // setting
887 *siglen = len;
888 *sigptr = malloc(len);
889 if (*sigptr == NULL) {
890 goto error;
891 }
892 memcpy(*sigptr, buffer_ptr(msg), len);
893
894 }
895 else {
896 buffer_free(msg);
897 return FALSE;
898 }
899
900 buffer_free(msg);
901 return TRUE;
902
903 error:
904 buffer_free(msg);
905
906 return FALSE;
907 }
908
909
910 BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
911 {
912 buffer_t *msg = NULL;
913 Key *keypair;
914 char *s;
915
916 msg = buffer_init();
917 if (msg == NULL) {
918 // TODO: error check
919 return FALSE;
920 }
921
922 keypair = pvar->auth_state.cur_cred.key_pair;
923
924 if (keypair->type == KEY_RSA) { // RSA
925 s = get_sshname_from_key(keypair);
926 buffer_put_string(msg, s, strlen(s));
927 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
928 buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
929
930 }
931 else if (keypair->type == KEY_RSA) { // DSA
932 s = get_sshname_from_key(keypair);
933 buffer_put_string(msg, s, strlen(s));
934 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
935 buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
936 buffer_put_bignum2(msg, keypair->dsa->g); // ����
937 buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
938
939 }
940 else {
941 return FALSE;
942
943 }
944
945 *blobptr = msg;
946 *bloblen = buffer_len(msg);
947
948 return TRUE;
949 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26