Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4531 - (hide annotations) (download) (as text)
Tue Jul 26 08:50:11 2011 UTC (12 years, 8 months ago) by doda
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 27396 byte(s)
RFC 4255 "Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints" 対応の準備
http://tools.ietf.org/html/rfc4255

VerifyHostKeyDNS = 1 にすると、ホスト鍵の検証を行う。
検証するだけで検証結果は使ってないけれど。

DNSSEC 未対応の問題が有るので、その部分について検討中。
解決する目途が立っていないので、もしかするとお蔵入りするかも。

Windows95/98/Me/NT4 では動かないかも。

1 maya 4304 /*
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 "key.h"
30 maya 4321 #include "kex.h"
31 maya 4304
32     #include <openssl/rsa.h>
33     #include <openssl/dsa.h>
34 maya 4321 #include <openssl/ecdsa.h>
35 maya 4304
36     #define INTBLOB_LEN 20
37     #define SIGBLOB_LEN (2*INTBLOB_LEN)
38    
39     //////////////////////////////////////////////////////////////////////////////
40     //
41     // Key verify function
42     //
43     //////////////////////////////////////////////////////////////////////////////
44    
45     //
46     // DSS
47     //
48    
49     int ssh_dss_verify(DSA *key,
50     u_char *signature, u_int signaturelen,
51     u_char *data, u_int datalen)
52     {
53     DSA_SIG *sig;
54     const EVP_MD *evp_md = EVP_sha1();
55     EVP_MD_CTX md;
56     unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
57     unsigned int len, dlen;
58     int ret;
59     char *ptr;
60    
61     OpenSSL_add_all_digests();
62    
63     if (key == NULL) {
64     return -2;
65     }
66    
67     ptr = signature;
68    
69     // step1
70     if (signaturelen == 0x28) {
71     // workaround for SSH-2.0-2.0* and SSH-2.0-2.1* (2006.11.18 maya)
72     ptr -= 4;
73     }
74     else {
75     len = get_uint32_MSBfirst(ptr);
76     ptr += 4;
77     if (strncmp("ssh-dss", ptr, len) != 0) {
78     return -3;
79     }
80     ptr += len;
81     }
82    
83     // step2
84     len = get_uint32_MSBfirst(ptr);
85     ptr += 4;
86     sigblob = ptr;
87     ptr += len;
88    
89     if (len != SIGBLOB_LEN) {
90     return -4;
91     }
92    
93     /* parse signature */
94     if ((sig = DSA_SIG_new()) == NULL)
95     return -5;
96     if ((sig->r = BN_new()) == NULL)
97     return -6;
98     if ((sig->s = BN_new()) == NULL)
99     return -7;
100     BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
101     BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
102    
103     /* sha1 the data */
104     EVP_DigestInit(&md, evp_md);
105     EVP_DigestUpdate(&md, data, datalen);
106     EVP_DigestFinal(&md, digest, &dlen);
107    
108     ret = DSA_do_verify(digest, dlen, sig, key);
109     memset(digest, 'd', sizeof(digest));
110    
111     DSA_SIG_free(sig);
112    
113     return ret;
114     }
115    
116    
117     //
118     // RSA
119     //
120    
121     /*
122     * See:
123     * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
124     * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
125     */
126     /*
127     * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
128     * oiw(14) secsig(3) algorithms(2) 26 }
129     */
130     static const u_char id_sha1[] = {
131     0x30, 0x21, /* type Sequence, length 0x21 (33) */
132     0x30, 0x09, /* type Sequence, length 0x09 */
133     0x06, 0x05, /* type OID, length 0x05 */
134     0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
135     0x05, 0x00, /* NULL */
136     0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
137     };
138     /*
139     * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
140     * rsadsi(113549) digestAlgorithm(2) 5 }
141     */
142     static const u_char id_md5[] = {
143     0x30, 0x20, /* type Sequence, length 0x20 (32) */
144     0x30, 0x0c, /* type Sequence, length 0x09 */
145     0x06, 0x08, /* type OID, length 0x05 */
146     0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
147     0x05, 0x00, /* NULL */
148     0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
149     };
150    
151     static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
152     u_char *sigbuf, u_int siglen, RSA *rsa)
153     {
154     u_int ret, rsasize, oidlen = 0, hlen = 0;
155     int len;
156     const u_char *oid = NULL;
157     u_char *decrypted = NULL;
158    
159     ret = 0;
160     switch (type) {
161     case NID_sha1:
162     oid = id_sha1;
163     oidlen = sizeof(id_sha1);
164     hlen = 20;
165     break;
166     case NID_md5:
167     oid = id_md5;
168     oidlen = sizeof(id_md5);
169     hlen = 16;
170     break;
171     default:
172     goto done;
173     break;
174     }
175     if (hashlen != hlen) {
176     //error("bad hashlen");
177     goto done;
178     }
179     rsasize = RSA_size(rsa);
180     if (siglen == 0 || siglen > rsasize) {
181     //error("bad siglen");
182     goto done;
183     }
184     decrypted = malloc(rsasize);
185     if (decrypted == NULL)
186     return 1; // error
187    
188     if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
189     RSA_PKCS1_PADDING)) < 0) {
190     //error("RSA_public_decrypt failed: %s",
191     // ERR_error_string(ERR_get_error(), NULL));
192     goto done;
193     }
194     if (len != hlen + oidlen) {
195     //error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
196     goto done;
197     }
198     if (memcmp(decrypted, oid, oidlen) != 0) {
199     //error("oid mismatch");
200     goto done;
201     }
202     if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
203     //error("hash mismatch");
204     goto done;
205     }
206     ret = 1;
207     done:
208     if (decrypted)
209     free(decrypted);
210     return ret;
211     }
212    
213     int ssh_rsa_verify(RSA *key,
214     u_char *signature, u_int signaturelen,
215     u_char *data, u_int datalen)
216     {
217     const EVP_MD *evp_md;
218     EVP_MD_CTX md;
219     // char *ktype;
220     u_char digest[EVP_MAX_MD_SIZE], *sigblob;
221     u_int len, dlen, modlen;
222     // int rlen, ret, nid;
223     int ret, nid;
224     char *ptr;
225    
226     OpenSSL_add_all_digests();
227    
228     if (key == NULL) {
229     return -2;
230     }
231     if (BN_num_bits(key->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
232     return -3;
233     }
234     //debug_print(41, signature, signaturelen);
235     ptr = signature;
236    
237     // step1
238     len = get_uint32_MSBfirst(ptr);
239     ptr += 4;
240     if (strncmp("ssh-rsa", ptr, len) != 0) {
241     return -4;
242     }
243     ptr += len;
244    
245     // step2
246     len = get_uint32_MSBfirst(ptr);
247     ptr += 4;
248     sigblob = ptr;
249     ptr += len;
250     #if 0
251     rlen = get_uint32_MSBfirst(ptr);
252     if (rlen != 0) {
253     return -1;
254     }
255     #endif
256    
257     /* RSA_verify expects a signature of RSA_size */
258     modlen = RSA_size(key);
259     if (len > modlen) {
260     return -5;
261    
262     } else if (len < modlen) {
263     u_int diff = modlen - len;
264     sigblob = realloc(sigblob, modlen);
265     memmove(sigblob + diff, sigblob, len);
266     memset(sigblob, 0, diff);
267     len = modlen;
268     }
269    
270     /* sha1 the data */
271     // nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
272     nid = NID_sha1;
273     if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
274     //error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
275     return -6;
276     }
277     EVP_DigestInit(&md, evp_md);
278     EVP_DigestUpdate(&md, data, datalen);
279     EVP_DigestFinal(&md, digest, &dlen);
280    
281     ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key);
282    
283     memset(digest, 'd', sizeof(digest));
284     memset(sigblob, 's', len);
285     //free(sigblob);
286     //debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
287    
288     return ret;
289     }
290    
291 maya 4378 int ssh_ecdsa_verify(EC_KEY *key, ssh_keytype keytype,
292 maya 4321 u_char *signature, u_int signaturelen,
293     u_char *data, u_int datalen)
294     {
295     ECDSA_SIG *sig;
296     const EVP_MD *evp_md;
297     EVP_MD_CTX md;
298     unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
299     unsigned int len, dlen;
300     int ret, nid = NID_undef;
301     char *ptr;
302    
303     OpenSSL_add_all_digests();
304    
305     if (key == NULL) {
306     return -2;
307     }
308    
309     ptr = signature;
310    
311     len = get_uint32_MSBfirst(ptr);
312     ptr += 4;
313 maya 4378 if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) {
314 maya 4321 return -3;
315     }
316     ptr += len;
317    
318     len = get_uint32_MSBfirst(ptr);
319     ptr += 4;
320     sigblob = ptr;
321     ptr += len;
322    
323     /* parse signature */
324     if ((sig = ECDSA_SIG_new()) == NULL)
325     return -4;
326     if ((sig->r = BN_new()) == NULL)
327     return -5;
328     if ((sig->s = BN_new()) == NULL)
329     return -6;
330    
331     buffer_get_bignum2(&sigblob, sig->r);
332     buffer_get_bignum2(&sigblob, sig->s);
333     if (sigblob != ptr) {
334     return -7;
335     }
336    
337     /* hash the data */
338 maya 4327 nid = keytype_to_hash_nid(keytype);
339 maya 4321 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
340     return -8;
341     }
342     EVP_DigestInit(&md, evp_md);
343     EVP_DigestUpdate(&md, data, datalen);
344     EVP_DigestFinal(&md, digest, &dlen);
345    
346     ret = ECDSA_do_verify(digest, dlen, sig, key);
347     memset(digest, 'd', sizeof(digest));
348    
349     ECDSA_SIG_free(sig);
350    
351     return ret;
352     }
353    
354 maya 4307 int key_verify(Key *key,
355 maya 4304 unsigned char *signature, unsigned int signaturelen,
356     unsigned char *data, unsigned int datalen)
357     {
358     int ret = 0;
359    
360 maya 4321 switch (key->type) {
361     case KEY_RSA:
362 maya 4307 ret = ssh_rsa_verify(key->rsa, signature, signaturelen, data, datalen);
363 maya 4321 break;
364     case KEY_DSA:
365 maya 4307 ret = ssh_dss_verify(key->dsa, signature, signaturelen, data, datalen);
366 maya 4321 break;
367     case KEY_ECDSA256:
368     case KEY_ECDSA384:
369     case KEY_ECDSA521:
370     ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen);
371     break;
372     default:
373 maya 4304 return -1;
374     }
375    
376     return (ret); // success
377     }
378    
379     //
380     // RSA�\����������
381     //
382     RSA *duplicate_RSA(RSA *src)
383     {
384     RSA *rsa = NULL;
385    
386     rsa = RSA_new();
387     if (rsa == NULL)
388     goto error;
389     rsa->n = BN_new();
390     rsa->e = BN_new();
391     if (rsa->n == NULL || rsa->e == NULL) {
392     RSA_free(rsa);
393     goto error;
394     }
395    
396     // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
397     BN_copy(rsa->n, src->n);
398     BN_copy(rsa->e, src->e);
399    
400     error:
401     return (rsa);
402     }
403    
404    
405     //
406     // DSA�\����������
407     //
408     DSA *duplicate_DSA(DSA *src)
409     {
410     DSA *dsa = NULL;
411    
412     dsa = DSA_new();
413     if (dsa == NULL)
414     goto error;
415     dsa->p = BN_new();
416     dsa->q = BN_new();
417     dsa->g = BN_new();
418     dsa->pub_key = BN_new();
419     if (dsa->p == NULL ||
420     dsa->q == NULL ||
421     dsa->g == NULL ||
422     dsa->pub_key == NULL) {
423     DSA_free(dsa);
424     goto error;
425     }
426    
427     // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
428     BN_copy(dsa->p, src->p);
429     BN_copy(dsa->q, src->q);
430     BN_copy(dsa->g, src->g);
431     BN_copy(dsa->pub_key, src->pub_key);
432    
433     error:
434     return (dsa);
435     }
436    
437    
438 doda 4531 char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length)
439 maya 4304 {
440     const EVP_MD *md = NULL;
441     EVP_MD_CTX ctx;
442     char *blob = NULL;
443     char *retval = NULL;
444     int len = 0;
445     int nlen, elen;
446     RSA *rsa;
447    
448     *dgst_raw_length = 0;
449    
450 doda 4531 switch (dgst_type) {
451     case SSH_FP_MD5:
452     md = EVP_md5();
453     break;
454     case SSH_FP_SHA1:
455     md = EVP_sha1();
456     break;
457     default:
458     md = EVP_md5();
459     }
460 maya 4304
461     switch (k->type) {
462     case KEY_RSA1:
463     rsa = make_key(NULL, k->bits, k->exp, k->mod);
464     nlen = BN_num_bytes(rsa->n);
465     elen = BN_num_bytes(rsa->e);
466     len = nlen + elen;
467     blob = malloc(len);
468     if (blob == NULL) {
469     // TODO:
470     }
471     BN_bn2bin(rsa->n, blob);
472     BN_bn2bin(rsa->e, blob + nlen);
473     RSA_free(rsa);
474     break;
475    
476     case KEY_DSA:
477     case KEY_RSA:
478 maya 4321 case KEY_ECDSA256:
479     case KEY_ECDSA384:
480     case KEY_ECDSA521:
481 maya 4304 key_to_blob(k, &blob, &len);
482     break;
483    
484     case KEY_UNSPEC:
485     return retval;
486     break;
487    
488     default:
489     //fatal("key_fingerprint_raw: bad key type %d", k->type);
490     break;
491     }
492    
493     if (blob != NULL) {
494     retval = malloc(EVP_MAX_MD_SIZE);
495     if (retval == NULL) {
496     // TODO:
497     }
498     EVP_DigestInit(&ctx, md);
499     EVP_DigestUpdate(&ctx, blob, len);
500     EVP_DigestFinal(&ctx, retval, dgst_raw_length);
501     memset(blob, 0, len);
502     free(blob);
503     } else {
504     //fatal("key_fingerprint_raw: blob is null");
505     }
506     return retval;
507     }
508    
509    
510     const char *
511     key_type(const Key *k)
512     {
513     switch (k->type) {
514     case KEY_RSA1:
515     return "RSA1";
516     case KEY_RSA:
517     return "RSA";
518     case KEY_DSA:
519     return "DSA";
520 maya 4321 case KEY_ECDSA256:
521     case KEY_ECDSA384:
522     case KEY_ECDSA521:
523     return "ECDSA";
524 maya 4304 }
525     return "unknown";
526     }
527    
528     unsigned int
529     key_size(const Key *k)
530     {
531     switch (k->type) {
532     case KEY_RSA1:
533     // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
534     return k->bits;
535     case KEY_RSA:
536     return BN_num_bits(k->rsa->n);
537     case KEY_DSA:
538     return BN_num_bits(k->dsa->p);
539 maya 4321 case KEY_ECDSA256:
540     return 256;
541     case KEY_ECDSA384:
542     return 384;
543     case KEY_ECDSA521:
544     return 521;
545 maya 4304 }
546     return 0;
547     }
548    
549     // based on OpenSSH 5.1
550     #define FLDBASE 8
551     #define FLDSIZE_Y (FLDBASE + 1)
552     #define FLDSIZE_X (FLDBASE * 2 + 1)
553     static char *
554     key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
555     {
556     /*
557     * Chars to be used after each other every time the worm
558     * intersects with itself. Matter of taste.
559     */
560     char *augmentation_string = " .o+=*BOX@%&#/^SE";
561     char *retval, *p;
562     unsigned char field[FLDSIZE_X][FLDSIZE_Y];
563     unsigned int i, b;
564     int x, y;
565     size_t len = strlen(augmentation_string) - 1;
566    
567     retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
568    
569     /* initialize field */
570     memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
571     x = FLDSIZE_X / 2;
572     y = FLDSIZE_Y / 2;
573    
574     /* process raw key */
575     for (i = 0; i < dgst_raw_len; i++) {
576     int input;
577     /* each byte conveys four 2-bit move commands */
578     input = dgst_raw[i];
579     for (b = 0; b < 4; b++) {
580     /* evaluate 2 bit, rest is shifted later */
581     x += (input & 0x1) ? 1 : -1;
582     y += (input & 0x2) ? 1 : -1;
583    
584     /* assure we are still in bounds */
585     x = max(x, 0);
586     y = max(y, 0);
587     x = min(x, FLDSIZE_X - 1);
588     y = min(y, FLDSIZE_Y - 1);
589    
590     /* augment the field */
591     field[x][y]++;
592     input = input >> 2;
593     }
594     }
595    
596     /* mark starting point and end point*/
597     field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
598     field[x][y] = len;
599    
600     /* fill in retval */
601     _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k));
602     p = strchr(retval, '\0');
603    
604     /* output upper border */
605     for (i = p - retval - 1; i < FLDSIZE_X; i++)
606     *p++ = '-';
607     *p++ = '+';
608     *p++ = '\r';
609     *p++ = '\n';
610    
611     /* output content */
612     for (y = 0; y < FLDSIZE_Y; y++) {
613     *p++ = '|';
614     for (x = 0; x < FLDSIZE_X; x++)
615     *p++ = augmentation_string[min(field[x][y], len)];
616     *p++ = '|';
617     *p++ = '\r';
618     *p++ = '\n';
619     }
620    
621     /* output lower border */
622     *p++ = '+';
623     for (i = 0; i < FLDSIZE_X; i++)
624     *p++ = '-';
625     *p++ = '+';
626    
627     return retval;
628     }
629     #undef FLDBASE
630     #undef FLDSIZE_Y
631     #undef FLDSIZE_X
632    
633     //
634     // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
635     //
636     char *key_fingerprint(Key *key, enum fp_rep dgst_rep)
637     {
638     char *retval = NULL;
639     unsigned char *dgst_raw;
640     int dgst_raw_len;
641     int i, retval_len;
642    
643     // fingerprint���n�b�V���l�i�o�C�i���j��������
644 doda 4531 dgst_raw = key_fingerprint_raw(key, SSH_FP_MD5, &dgst_raw_len);
645 maya 4304
646     if (dgst_rep == SSH_FP_HEX) {
647     // 16�i�\�L����������
648     retval_len = dgst_raw_len * 3 + 1;
649     retval = malloc(retval_len);
650     retval[0] = '\0';
651     for (i = 0; i < dgst_raw_len; i++) {
652     char hex[4];
653     _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
654     strncat_s(retval, retval_len, hex, _TRUNCATE);
655     }
656    
657     /* Remove the trailing ':' character */
658     retval[(dgst_raw_len * 3) - 1] = '\0';
659    
660     } else if (dgst_rep == SSH_FP_RANDOMART) {
661     retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
662    
663     } else {
664    
665     }
666    
667     memset(dgst_raw, 0, dgst_raw_len);
668     free(dgst_raw);
669    
670     return (retval);
671     }
672    
673    
674     //
675     // �L�[����������������
676     //
677     void key_free(Key *key)
678     {
679 maya 4321 if (key == NULL) {
680     return;
681     }
682    
683 maya 4304 switch (key->type) {
684     case KEY_RSA1:
685     case KEY_RSA:
686     if (key->rsa != NULL)
687     RSA_free(key->rsa);
688     key->rsa = NULL;
689     break;
690    
691     case KEY_DSA:
692     if (key->dsa != NULL)
693     DSA_free(key->dsa);
694     key->dsa = NULL;
695     break;
696 maya 4321
697     case KEY_ECDSA256:
698     case KEY_ECDSA384:
699     case KEY_ECDSA521:
700     if (key->ecdsa != NULL)
701     EC_KEY_free(key->ecdsa);
702     key->ecdsa = NULL;
703     break;
704 maya 4304 }
705     free(key);
706     }
707    
708     //
709     // �L�[���������������p����
710     //
711 maya 4321 char *get_sshname_from_key(Key *key)
712     {
713 maya 4378 return get_ssh_keytype_name(key->type);
714 maya 4321 }
715 maya 4304
716     //
717     // �L�[������������������������
718     //
719 maya 4378 ssh_keytype get_keytype_from_name(char *name)
720 maya 4304 {
721     if (strcmp(name, "rsa1") == 0) {
722     return KEY_RSA1;
723     } else if (strcmp(name, "rsa") == 0) {
724     return KEY_RSA;
725     } else if (strcmp(name, "dsa") == 0) {
726     return KEY_DSA;
727     } else if (strcmp(name, "ssh-rsa") == 0) {
728     return KEY_RSA;
729     } else if (strcmp(name, "ssh-dss") == 0) {
730     return KEY_DSA;
731 maya 4321 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
732     return KEY_ECDSA256;
733     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
734     return KEY_ECDSA384;
735     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
736     return KEY_ECDSA521;
737 maya 4304 }
738     return KEY_UNSPEC;
739     }
740    
741    
742 maya 4378 ssh_keytype key_curve_name_to_keytype(char *name)
743 maya 4321 {
744     if (strcmp(name, "nistp256") == 0) {
745     return KEY_ECDSA256;
746     } else if (strcmp(name, "nistp384") == 0) {
747     return KEY_ECDSA384;
748     } else if (strcmp(name, "nistp521") == 0) {
749     return KEY_ECDSA521;
750     }
751     return KEY_UNSPEC;
752     }
753    
754 maya 4378 char *curve_keytype_to_name(ssh_keytype type)
755 maya 4321 {
756     switch (type) {
757     case KEY_ECDSA256:
758     return "nistp256";
759     break;
760     case KEY_ECDSA384:
761     return "nistp384";
762     break;
763     case KEY_ECDSA521:
764     return "nistp521";
765     break;
766     }
767     return NULL;
768     }
769    
770 maya 4304 //
771     // �L�[���������o�b�t�@���������� (for SSH2)
772     // NOTE:
773     //
774     int key_to_blob(Key *key, char **blobp, int *lenp)
775     {
776     buffer_t *b;
777 maya 4321 char *sshname, *tmp;
778 maya 4304 int len;
779     int ret = 1; // success
780    
781     b = buffer_init();
782     sshname = get_sshname_from_key(key);
783    
784 maya 4321 switch (key->type) {
785     case KEY_RSA:
786 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
787     buffer_put_bignum2(b, key->rsa->e);
788     buffer_put_bignum2(b, key->rsa->n);
789 maya 4321 break;
790     case KEY_DSA:
791 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
792     buffer_put_bignum2(b, key->dsa->p);
793     buffer_put_bignum2(b, key->dsa->q);
794     buffer_put_bignum2(b, key->dsa->g);
795     buffer_put_bignum2(b, key->dsa->pub_key);
796 maya 4321 break;
797     case KEY_ECDSA256:
798     case KEY_ECDSA384:
799     case KEY_ECDSA521:
800     buffer_put_string(b, sshname, strlen(sshname));
801     tmp = curve_keytype_to_name(key->type);
802     buffer_put_string(b, tmp, strlen(tmp));
803     buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
804     EC_KEY_get0_public_key(key->ecdsa));
805     break;
806 maya 4304
807 maya 4321 default:
808 maya 4304 ret = 0;
809     goto error;
810     }
811    
812     len = buffer_len(b);
813     if (lenp != NULL)
814     *lenp = len;
815     if (blobp != NULL) {
816     *blobp = malloc(len);
817     if (*blobp == NULL) {
818     ret = 0;
819     goto error;
820     }
821     memcpy(*blobp, buffer_ptr(b), len);
822     }
823    
824     error:
825     buffer_free(b);
826    
827     return (ret);
828     }
829    
830    
831     //
832     // �o�b�t�@�����L�[�����������o��(for SSH2)
833     // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
834     //
835     Key *key_from_blob(char *data, int blen)
836     {
837     int keynamelen;
838     char key[128];
839     RSA *rsa = NULL;
840     DSA *dsa = NULL;
841 maya 4321 EC_KEY *ecdsa = NULL;
842     EC_POINT *q = NULL;
843     char *curve = NULL;
844 maya 4304 Key *hostkey; // hostkey
845 maya 4378 ssh_keytype type;
846 maya 4304
847     hostkey = malloc(sizeof(Key));
848     if (hostkey == NULL)
849     goto error;
850    
851     memset(hostkey, 0, sizeof(Key));
852    
853     keynamelen = get_uint32_MSBfirst(data);
854     if (keynamelen >= sizeof(key)) {
855     goto error;
856     }
857     data += 4;
858     memcpy(key, data, keynamelen);
859     key[keynamelen] = 0;
860     data += keynamelen;
861    
862     type = get_keytype_from_name(key);
863    
864 maya 4321 switch (type) {
865     case KEY_RSA: // RSA key
866 maya 4304 rsa = RSA_new();
867     if (rsa == NULL) {
868     goto error;
869     }
870     rsa->n = BN_new();
871     rsa->e = BN_new();
872     if (rsa->n == NULL || rsa->e == NULL) {
873     goto error;
874     }
875    
876     buffer_get_bignum2(&data, rsa->e);
877     buffer_get_bignum2(&data, rsa->n);
878    
879     hostkey->type = type;
880     hostkey->rsa = rsa;
881 maya 4321 break;
882 maya 4304
883 maya 4321 case KEY_DSA: // DSA key
884 maya 4304 dsa = DSA_new();
885     if (dsa == NULL) {
886     goto error;
887     }
888     dsa->p = BN_new();
889     dsa->q = BN_new();
890     dsa->g = BN_new();
891     dsa->pub_key = BN_new();
892     if (dsa->p == NULL ||
893     dsa->q == NULL ||
894     dsa->g == NULL ||
895     dsa->pub_key == NULL) {
896     goto error;
897     }
898    
899     buffer_get_bignum2(&data, dsa->p);
900     buffer_get_bignum2(&data, dsa->q);
901     buffer_get_bignum2(&data, dsa->g);
902     buffer_get_bignum2(&data, dsa->pub_key);
903    
904     hostkey->type = type;
905     hostkey->dsa = dsa;
906 maya 4321 break;
907 maya 4304
908 maya 4321 case KEY_ECDSA256: // ECDSA
909     case KEY_ECDSA384:
910     case KEY_ECDSA521:
911     curve = buffer_get_string(&data, NULL);
912     if (type != key_curve_name_to_keytype(curve)) {
913     goto error;
914     }
915    
916 maya 4327 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
917 maya 4321 if (ecdsa == NULL) {
918     goto error;
919     }
920    
921     q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
922     if (q == NULL) {
923     goto error;
924     }
925    
926     buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
927     if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
928     goto error;
929     }
930    
931     if (EC_KEY_set_public_key(ecdsa, q) != 1) {
932     goto error;
933     }
934    
935     hostkey->type = type;
936     hostkey->ecdsa = ecdsa;
937     break;
938    
939     default: // unknown key
940 maya 4304 goto error;
941     }
942    
943     return (hostkey);
944    
945     error:
946     if (rsa != NULL)
947     RSA_free(rsa);
948     if (dsa != NULL)
949     DSA_free(dsa);
950 maya 4321 if (ecdsa != NULL)
951     EC_KEY_free(ecdsa);
952 maya 4304
953     return NULL;
954     }
955    
956    
957 maya 4307 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
958 maya 4304 {
959     buffer_t *msg = NULL;
960     char *s;
961    
962     msg = buffer_init();
963     if (msg == NULL) {
964     // TODO: error check
965     return FALSE;
966     }
967    
968 maya 4324 switch (keypair->type) {
969     case KEY_RSA: // RSA
970     {
971 maya 4307 const EVP_MD *evp_md = EVP_sha1();
972 maya 4304 EVP_MD_CTX md;
973     u_char digest[EVP_MAX_MD_SIZE], *sig;
974     u_int slen, dlen, len;
975 maya 4307 int ok, nid = NID_sha1;
976 maya 4304
977     // �_�C�W�F�X�g�l���v�Z
978     EVP_DigestInit(&md, evp_md);
979     EVP_DigestUpdate(&md, data, datalen);
980     EVP_DigestFinal(&md, digest, &dlen);
981    
982 maya 4307 slen = RSA_size(keypair->rsa);
983 maya 4304 sig = malloc(slen);
984     if (sig == NULL)
985     goto error;
986    
987     // �d�q�������v�Z
988 maya 4307 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
989 maya 4304 memset(digest, 'd', sizeof(digest));
990     if (ok != 1) { // error
991     free(sig);
992     goto error;
993     }
994     // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
995     if (len < slen) {
996     u_int diff = slen - len;
997     memmove(sig + diff, sig, len);
998     memset(sig, 0, diff);
999    
1000     } else if (len > slen) {
1001     free(sig);
1002     goto error;
1003    
1004     } else {
1005     // do nothing
1006    
1007     }
1008    
1009 maya 4307 s = get_sshname_from_key(keypair);
1010 maya 4304 buffer_put_string(msg, s, strlen(s));
1011     buffer_append_length(msg, sig, slen);
1012     len = buffer_len(msg);
1013    
1014     // setting
1015     *siglen = len;
1016     *sigptr = malloc(len);
1017     if (*sigptr == NULL) {
1018     free(sig);
1019     goto error;
1020     }
1021     memcpy(*sigptr, buffer_ptr(msg), len);
1022     free(sig);
1023 maya 4324
1024     break;
1025 maya 4307 }
1026 maya 4324 case KEY_DSA: // DSA
1027     {
1028 maya 4304 DSA_SIG *sig;
1029     const EVP_MD *evp_md = EVP_sha1();
1030     EVP_MD_CTX md;
1031     u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1032     u_int rlen, slen, len, dlen;
1033    
1034     // �_�C�W�F�X�g���v�Z
1035     EVP_DigestInit(&md, evp_md);
1036     EVP_DigestUpdate(&md, data, datalen);
1037     EVP_DigestFinal(&md, digest, &dlen);
1038    
1039     // DSA�d�q�������v�Z
1040 maya 4307 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1041 maya 4304 memset(digest, 'd', sizeof(digest));
1042     if (sig == NULL) {
1043     goto error;
1044     }
1045    
1046     // BIGNUM�����o�C�i���l��������
1047     rlen = BN_num_bytes(sig->r);
1048     slen = BN_num_bytes(sig->s);
1049     if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1050     DSA_SIG_free(sig);
1051     goto error;
1052     }
1053     memset(sigblob, 0, SIGBLOB_LEN);
1054     BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1055     BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1056     DSA_SIG_free(sig);
1057    
1058     // setting
1059 maya 4307 s = get_sshname_from_key(keypair);
1060 maya 4304 buffer_put_string(msg, s, strlen(s));
1061     buffer_append_length(msg, sigblob, sizeof(sigblob));
1062     len = buffer_len(msg);
1063    
1064     // setting
1065     *siglen = len;
1066     *sigptr = malloc(len);
1067     if (*sigptr == NULL) {
1068     goto error;
1069     }
1070     memcpy(*sigptr, buffer_ptr(msg), len);
1071    
1072 maya 4324 break;
1073 maya 4304 }
1074 maya 4324 case KEY_ECDSA256: // ECDSA
1075     case KEY_ECDSA384:
1076     case KEY_ECDSA521:
1077     {
1078     ECDSA_SIG *sig;
1079     const EVP_MD *evp_md;
1080     EVP_MD_CTX md;
1081     u_char digest[EVP_MAX_MD_SIZE];
1082     u_int len, dlen, nid;
1083     buffer_t *buf2 = NULL;
1084    
1085 maya 4327 nid = keytype_to_hash_nid(keypair->type);
1086 maya 4324 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1087     goto error;
1088     }
1089     EVP_DigestInit(&md, evp_md);
1090     EVP_DigestUpdate(&md, data, datalen);
1091     EVP_DigestFinal(&md, digest, &dlen);
1092    
1093     sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1094     memset(digest, 'd', sizeof(digest));
1095    
1096     if (sig == NULL) {
1097     goto error;
1098     }
1099    
1100     buf2 = buffer_init();
1101     if (buf2 == NULL) {
1102     // TODO: error check
1103     goto error;
1104     }
1105     buffer_put_bignum2(buf2, sig->r);
1106     buffer_put_bignum2(buf2, sig->s);
1107     ECDSA_SIG_free(sig);
1108    
1109     s = get_sshname_from_key(keypair);
1110     buffer_put_string(msg, s, strlen(s));
1111     buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1112     buffer_free(buf2);
1113     len = buffer_len(msg);
1114    
1115     *siglen = len;
1116     *sigptr = malloc(len);
1117     if (*sigptr == NULL) {
1118     goto error;
1119     }
1120     memcpy(*sigptr, buffer_ptr(msg), len);
1121    
1122     break;
1123     }
1124     default:
1125 maya 4307 buffer_free(msg);
1126     return FALSE;
1127 maya 4324 break;
1128 maya 4307 }
1129 maya 4304
1130     buffer_free(msg);
1131     return TRUE;
1132    
1133     error:
1134     buffer_free(msg);
1135    
1136     return FALSE;
1137     }
1138    
1139    
1140     BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1141     {
1142     buffer_t *msg = NULL;
1143 maya 4307 Key *keypair;
1144 maya 4324 char *s, *tmp;
1145 maya 4304
1146     msg = buffer_init();
1147     if (msg == NULL) {
1148     // TODO: error check
1149     return FALSE;
1150     }
1151    
1152     keypair = pvar->auth_state.cur_cred.key_pair;
1153    
1154 maya 4324 switch (keypair->type) {
1155     case KEY_RSA: // RSA
1156 maya 4307 s = get_sshname_from_key(keypair);
1157 maya 4304 buffer_put_string(msg, s, strlen(s));
1158 maya 4307 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1159     buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1160 maya 4324 break;
1161     case KEY_DSA: // DSA
1162 maya 4307 s = get_sshname_from_key(keypair);
1163 maya 4304 buffer_put_string(msg, s, strlen(s));
1164 maya 4307 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1165     buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1166     buffer_put_bignum2(msg, keypair->dsa->g); // ����
1167     buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1168 maya 4324 break;
1169     case KEY_ECDSA256: // ECDSA
1170     case KEY_ECDSA384:
1171     case KEY_ECDSA521:
1172     s = get_sshname_from_key(keypair);
1173     buffer_put_string(msg, s, strlen(s));
1174     tmp = curve_keytype_to_name(keypair->type);
1175     buffer_put_string(msg, tmp, strlen(tmp));
1176     buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1177     EC_KEY_get0_public_key(keypair->ecdsa));
1178     break;
1179     default:
1180 maya 4307 return FALSE;
1181     }
1182    
1183 maya 4304 *blobptr = msg;
1184     *bloblen = buffer_len(msg);
1185    
1186     return TRUE;
1187     }
1188 maya 4327
1189 maya 4378 int kextype_to_cipher_nid(kex_algorithm type)
1190 maya 4327 {
1191     switch (type) {
1192     case KEX_ECDH_SHA2_256:
1193     return NID_X9_62_prime256v1;
1194     case KEX_ECDH_SHA2_384:
1195     return NID_secp384r1;
1196     case KEX_ECDH_SHA2_521:
1197     return NID_secp521r1;
1198     }
1199     return NID_undef;
1200     }
1201    
1202 maya 4378 int keytype_to_hash_nid(ssh_keytype type)
1203 maya 4327 {
1204     switch (type) {
1205     case KEY_ECDSA256:
1206     return NID_sha256;
1207     case KEY_ECDSA384:
1208     return NID_sha384;
1209     case KEY_ECDSA521:
1210     return NID_sha512;
1211     }
1212     return NID_undef;
1213     }
1214    
1215 maya 4378 int keytype_to_cipher_nid(ssh_keytype type)
1216 maya 4327 {
1217     switch (type) {
1218     case KEY_ECDSA256:
1219     return NID_X9_62_prime256v1;
1220     case KEY_ECDSA384:
1221     return NID_secp384r1;
1222     case KEY_ECDSA521:
1223     return NID_secp521r1;
1224     }
1225     return NID_undef;
1226     }
1227    
1228 maya 4378 ssh_keytype nid_to_keytype(int nid)
1229 maya 4327 {
1230     switch (nid) {
1231     case NID_X9_62_prime256v1:
1232     return KEY_ECDSA256;
1233     case NID_secp384r1:
1234     return KEY_ECDSA384;
1235     case NID_secp521r1:
1236     return KEY_ECDSA521;
1237     }
1238     return KEY_UNSPEC;
1239     }

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