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 4367 - (hide annotations) (download) (as text)
Sat Mar 5 14:52:45 2011 UTC (13 years, 1 month ago) by yutakapon
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 27527 byte(s)
TTSSHの各種暗号設定に関して、teraterm.iniのエントリでカスタマイズできるようにした。
正式なUIに関しては、これから検討する。

KexOrder=56743210
HostKeyOrder=456230
MacOrder=120
CompOrder=012

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 4321 int ssh_ecdsa_verify(EC_KEY *key, enum ssh_keytype keytype,
292     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     if (strncmp(get_sshname_from_keytype(keytype), ptr, len) != 0) {
314     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     char* key_fingerprint_raw(Key *k, int *dgst_raw_length)
439     {
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     // MD5�A���S���Y�����g�p����
451     md = EVP_md5();
452    
453     switch (k->type) {
454     case KEY_RSA1:
455     rsa = make_key(NULL, k->bits, k->exp, k->mod);
456     nlen = BN_num_bytes(rsa->n);
457     elen = BN_num_bytes(rsa->e);
458     len = nlen + elen;
459     blob = malloc(len);
460     if (blob == NULL) {
461     // TODO:
462     }
463     BN_bn2bin(rsa->n, blob);
464     BN_bn2bin(rsa->e, blob + nlen);
465     RSA_free(rsa);
466     break;
467    
468     case KEY_DSA:
469     case KEY_RSA:
470 maya 4321 case KEY_ECDSA256:
471     case KEY_ECDSA384:
472     case KEY_ECDSA521:
473 maya 4304 key_to_blob(k, &blob, &len);
474     break;
475    
476     case KEY_UNSPEC:
477     return retval;
478     break;
479    
480     default:
481     //fatal("key_fingerprint_raw: bad key type %d", k->type);
482     break;
483     }
484    
485     if (blob != NULL) {
486     retval = malloc(EVP_MAX_MD_SIZE);
487     if (retval == NULL) {
488     // TODO:
489     }
490     EVP_DigestInit(&ctx, md);
491     EVP_DigestUpdate(&ctx, blob, len);
492     EVP_DigestFinal(&ctx, retval, dgst_raw_length);
493     memset(blob, 0, len);
494     free(blob);
495     } else {
496     //fatal("key_fingerprint_raw: blob is null");
497     }
498     return retval;
499     }
500    
501    
502     const char *
503     key_type(const Key *k)
504     {
505     switch (k->type) {
506     case KEY_RSA1:
507     return "RSA1";
508     case KEY_RSA:
509     return "RSA";
510     case KEY_DSA:
511     return "DSA";
512 maya 4321 case KEY_ECDSA256:
513     case KEY_ECDSA384:
514     case KEY_ECDSA521:
515     return "ECDSA";
516 maya 4304 }
517     return "unknown";
518     }
519    
520     unsigned int
521     key_size(const Key *k)
522     {
523     switch (k->type) {
524     case KEY_RSA1:
525     // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
526     return k->bits;
527     case KEY_RSA:
528     return BN_num_bits(k->rsa->n);
529     case KEY_DSA:
530     return BN_num_bits(k->dsa->p);
531 maya 4321 case KEY_ECDSA256:
532     return 256;
533     case KEY_ECDSA384:
534     return 384;
535     case KEY_ECDSA521:
536     return 521;
537 maya 4304 }
538     return 0;
539     }
540    
541     // based on OpenSSH 5.1
542     #define FLDBASE 8
543     #define FLDSIZE_Y (FLDBASE + 1)
544     #define FLDSIZE_X (FLDBASE * 2 + 1)
545     static char *
546     key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
547     {
548     /*
549     * Chars to be used after each other every time the worm
550     * intersects with itself. Matter of taste.
551     */
552     char *augmentation_string = " .o+=*BOX@%&#/^SE";
553     char *retval, *p;
554     unsigned char field[FLDSIZE_X][FLDSIZE_Y];
555     unsigned int i, b;
556     int x, y;
557     size_t len = strlen(augmentation_string) - 1;
558    
559     retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
560    
561     /* initialize field */
562     memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
563     x = FLDSIZE_X / 2;
564     y = FLDSIZE_Y / 2;
565    
566     /* process raw key */
567     for (i = 0; i < dgst_raw_len; i++) {
568     int input;
569     /* each byte conveys four 2-bit move commands */
570     input = dgst_raw[i];
571     for (b = 0; b < 4; b++) {
572     /* evaluate 2 bit, rest is shifted later */
573     x += (input & 0x1) ? 1 : -1;
574     y += (input & 0x2) ? 1 : -1;
575    
576     /* assure we are still in bounds */
577     x = max(x, 0);
578     y = max(y, 0);
579     x = min(x, FLDSIZE_X - 1);
580     y = min(y, FLDSIZE_Y - 1);
581    
582     /* augment the field */
583     field[x][y]++;
584     input = input >> 2;
585     }
586     }
587    
588     /* mark starting point and end point*/
589     field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
590     field[x][y] = len;
591    
592     /* fill in retval */
593     _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k));
594     p = strchr(retval, '\0');
595    
596     /* output upper border */
597     for (i = p - retval - 1; i < FLDSIZE_X; i++)
598     *p++ = '-';
599     *p++ = '+';
600     *p++ = '\r';
601     *p++ = '\n';
602    
603     /* output content */
604     for (y = 0; y < FLDSIZE_Y; y++) {
605     *p++ = '|';
606     for (x = 0; x < FLDSIZE_X; x++)
607     *p++ = augmentation_string[min(field[x][y], len)];
608     *p++ = '|';
609     *p++ = '\r';
610     *p++ = '\n';
611     }
612    
613     /* output lower border */
614     *p++ = '+';
615     for (i = 0; i < FLDSIZE_X; i++)
616     *p++ = '-';
617     *p++ = '+';
618    
619     return retval;
620     }
621     #undef FLDBASE
622     #undef FLDSIZE_Y
623     #undef FLDSIZE_X
624    
625     //
626     // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
627     //
628     char *key_fingerprint(Key *key, enum fp_rep dgst_rep)
629     {
630     char *retval = NULL;
631     unsigned char *dgst_raw;
632     int dgst_raw_len;
633     int i, retval_len;
634    
635     // fingerprint���n�b�V���l�i�o�C�i���j��������
636     dgst_raw = key_fingerprint_raw(key, &dgst_raw_len);
637    
638     if (dgst_rep == SSH_FP_HEX) {
639     // 16�i�\�L����������
640     retval_len = dgst_raw_len * 3 + 1;
641     retval = malloc(retval_len);
642     retval[0] = '\0';
643     for (i = 0; i < dgst_raw_len; i++) {
644     char hex[4];
645     _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
646     strncat_s(retval, retval_len, hex, _TRUNCATE);
647     }
648    
649     /* Remove the trailing ':' character */
650     retval[(dgst_raw_len * 3) - 1] = '\0';
651    
652     } else if (dgst_rep == SSH_FP_RANDOMART) {
653     retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
654    
655     } else {
656    
657     }
658    
659     memset(dgst_raw, 0, dgst_raw_len);
660     free(dgst_raw);
661    
662     return (retval);
663     }
664    
665    
666     //
667     // �L�[����������������
668     //
669     void key_free(Key *key)
670     {
671 maya 4321 if (key == NULL) {
672     return;
673     }
674    
675 maya 4304 switch (key->type) {
676     case KEY_RSA1:
677     case KEY_RSA:
678     if (key->rsa != NULL)
679     RSA_free(key->rsa);
680     key->rsa = NULL;
681     break;
682    
683     case KEY_DSA:
684     if (key->dsa != NULL)
685     DSA_free(key->dsa);
686     key->dsa = NULL;
687     break;
688 maya 4321
689     case KEY_ECDSA256:
690     case KEY_ECDSA384:
691     case KEY_ECDSA521:
692     if (key->ecdsa != NULL)
693     EC_KEY_free(key->ecdsa);
694     key->ecdsa = NULL;
695     break;
696 maya 4304 }
697     free(key);
698     }
699    
700     //
701     // �L�[���������������p����
702     //
703 maya 4321 char *get_sshname_from_keytype(enum ssh_keytype type)
704 maya 4304 {
705 yutakapon 4367 int i;
706    
707     for (i = 0 ; ssh2_host_key[i].name ; i++) {
708     if (type == ssh2_host_key[i].type)
709     return ssh2_host_key[i].name;
710 maya 4304 }
711 yutakapon 4367 return "ssh-unknown";
712 maya 4304 }
713 yutakapon 4367
714 maya 4321 char *get_sshname_from_key(Key *key)
715     {
716     return get_sshname_from_keytype(key->type);
717     }
718 maya 4304
719     //
720     // �L�[������������������������
721     //
722 maya 4307 enum ssh_keytype get_keytype_from_name(char *name)
723 maya 4304 {
724     if (strcmp(name, "rsa1") == 0) {
725     return KEY_RSA1;
726     } else if (strcmp(name, "rsa") == 0) {
727     return KEY_RSA;
728     } else if (strcmp(name, "dsa") == 0) {
729     return KEY_DSA;
730     } else if (strcmp(name, "ssh-rsa") == 0) {
731     return KEY_RSA;
732     } else if (strcmp(name, "ssh-dss") == 0) {
733     return KEY_DSA;
734 maya 4321 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
735     return KEY_ECDSA256;
736     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
737     return KEY_ECDSA384;
738     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
739     return KEY_ECDSA521;
740 maya 4304 }
741     return KEY_UNSPEC;
742     }
743    
744    
745 maya 4321 enum ssh_keytype key_curve_name_to_keytype(char *name)
746     {
747     if (strcmp(name, "nistp256") == 0) {
748     return KEY_ECDSA256;
749     } else if (strcmp(name, "nistp384") == 0) {
750     return KEY_ECDSA384;
751     } else if (strcmp(name, "nistp521") == 0) {
752     return KEY_ECDSA521;
753     }
754     return KEY_UNSPEC;
755     }
756    
757     char *curve_keytype_to_name(enum ssh_keytype type)
758     {
759     switch (type) {
760     case KEY_ECDSA256:
761     return "nistp256";
762     break;
763     case KEY_ECDSA384:
764     return "nistp384";
765     break;
766     case KEY_ECDSA521:
767     return "nistp521";
768     break;
769     }
770     return NULL;
771     }
772    
773 maya 4304 //
774     // �L�[���������o�b�t�@���������� (for SSH2)
775     // NOTE:
776     //
777     int key_to_blob(Key *key, char **blobp, int *lenp)
778     {
779     buffer_t *b;
780 maya 4321 char *sshname, *tmp;
781 maya 4304 int len;
782     int ret = 1; // success
783    
784     b = buffer_init();
785     sshname = get_sshname_from_key(key);
786    
787 maya 4321 switch (key->type) {
788     case KEY_RSA:
789 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
790     buffer_put_bignum2(b, key->rsa->e);
791     buffer_put_bignum2(b, key->rsa->n);
792 maya 4321 break;
793     case KEY_DSA:
794 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
795     buffer_put_bignum2(b, key->dsa->p);
796     buffer_put_bignum2(b, key->dsa->q);
797     buffer_put_bignum2(b, key->dsa->g);
798     buffer_put_bignum2(b, key->dsa->pub_key);
799 maya 4321 break;
800     case KEY_ECDSA256:
801     case KEY_ECDSA384:
802     case KEY_ECDSA521:
803     buffer_put_string(b, sshname, strlen(sshname));
804     tmp = curve_keytype_to_name(key->type);
805     buffer_put_string(b, tmp, strlen(tmp));
806     buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
807     EC_KEY_get0_public_key(key->ecdsa));
808     break;
809 maya 4304
810 maya 4321 default:
811 maya 4304 ret = 0;
812     goto error;
813     }
814    
815     len = buffer_len(b);
816     if (lenp != NULL)
817     *lenp = len;
818     if (blobp != NULL) {
819     *blobp = malloc(len);
820     if (*blobp == NULL) {
821     ret = 0;
822     goto error;
823     }
824     memcpy(*blobp, buffer_ptr(b), len);
825     }
826    
827     error:
828     buffer_free(b);
829    
830     return (ret);
831     }
832    
833    
834     //
835     // �o�b�t�@�����L�[�����������o��(for SSH2)
836     // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
837     //
838     Key *key_from_blob(char *data, int blen)
839     {
840     int keynamelen;
841     char key[128];
842     RSA *rsa = NULL;
843     DSA *dsa = NULL;
844 maya 4321 EC_KEY *ecdsa = NULL;
845     EC_POINT *q = NULL;
846     char *curve = NULL;
847 maya 4304 Key *hostkey; // hostkey
848 maya 4307 enum ssh_keytype type;
849 maya 4304
850     hostkey = malloc(sizeof(Key));
851     if (hostkey == NULL)
852     goto error;
853    
854     memset(hostkey, 0, sizeof(Key));
855    
856     keynamelen = get_uint32_MSBfirst(data);
857     if (keynamelen >= sizeof(key)) {
858     goto error;
859     }
860     data += 4;
861     memcpy(key, data, keynamelen);
862     key[keynamelen] = 0;
863     data += keynamelen;
864    
865     type = get_keytype_from_name(key);
866    
867 maya 4321 switch (type) {
868     case KEY_RSA: // RSA key
869 maya 4304 rsa = RSA_new();
870     if (rsa == NULL) {
871     goto error;
872     }
873     rsa->n = BN_new();
874     rsa->e = BN_new();
875     if (rsa->n == NULL || rsa->e == NULL) {
876     goto error;
877     }
878    
879     buffer_get_bignum2(&data, rsa->e);
880     buffer_get_bignum2(&data, rsa->n);
881    
882     hostkey->type = type;
883     hostkey->rsa = rsa;
884 maya 4321 break;
885 maya 4304
886 maya 4321 case KEY_DSA: // DSA key
887 maya 4304 dsa = DSA_new();
888     if (dsa == NULL) {
889     goto error;
890     }
891     dsa->p = BN_new();
892     dsa->q = BN_new();
893     dsa->g = BN_new();
894     dsa->pub_key = BN_new();
895     if (dsa->p == NULL ||
896     dsa->q == NULL ||
897     dsa->g == NULL ||
898     dsa->pub_key == NULL) {
899     goto error;
900     }
901    
902     buffer_get_bignum2(&data, dsa->p);
903     buffer_get_bignum2(&data, dsa->q);
904     buffer_get_bignum2(&data, dsa->g);
905     buffer_get_bignum2(&data, dsa->pub_key);
906    
907     hostkey->type = type;
908     hostkey->dsa = dsa;
909 maya 4321 break;
910 maya 4304
911 maya 4321 case KEY_ECDSA256: // ECDSA
912     case KEY_ECDSA384:
913     case KEY_ECDSA521:
914     curve = buffer_get_string(&data, NULL);
915     if (type != key_curve_name_to_keytype(curve)) {
916     goto error;
917     }
918    
919 maya 4327 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
920 maya 4321 if (ecdsa == NULL) {
921     goto error;
922     }
923    
924     q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
925     if (q == NULL) {
926     goto error;
927     }
928    
929     buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
930     if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
931     goto error;
932     }
933    
934     if (EC_KEY_set_public_key(ecdsa, q) != 1) {
935     goto error;
936     }
937    
938     hostkey->type = type;
939     hostkey->ecdsa = ecdsa;
940     break;
941    
942     default: // unknown key
943 maya 4304 goto error;
944     }
945    
946     return (hostkey);
947    
948     error:
949     if (rsa != NULL)
950     RSA_free(rsa);
951     if (dsa != NULL)
952     DSA_free(dsa);
953 maya 4321 if (ecdsa != NULL)
954     EC_KEY_free(ecdsa);
955 maya 4304
956     return NULL;
957     }
958    
959    
960 maya 4307 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
961 maya 4304 {
962     buffer_t *msg = NULL;
963     char *s;
964    
965     msg = buffer_init();
966     if (msg == NULL) {
967     // TODO: error check
968     return FALSE;
969     }
970    
971 maya 4324 switch (keypair->type) {
972     case KEY_RSA: // RSA
973     {
974 maya 4307 const EVP_MD *evp_md = EVP_sha1();
975 maya 4304 EVP_MD_CTX md;
976     u_char digest[EVP_MAX_MD_SIZE], *sig;
977     u_int slen, dlen, len;
978 maya 4307 int ok, nid = NID_sha1;
979 maya 4304
980     // �_�C�W�F�X�g�l���v�Z
981     EVP_DigestInit(&md, evp_md);
982     EVP_DigestUpdate(&md, data, datalen);
983     EVP_DigestFinal(&md, digest, &dlen);
984    
985 maya 4307 slen = RSA_size(keypair->rsa);
986 maya 4304 sig = malloc(slen);
987     if (sig == NULL)
988     goto error;
989    
990     // �d�q�������v�Z
991 maya 4307 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
992 maya 4304 memset(digest, 'd', sizeof(digest));
993     if (ok != 1) { // error
994     free(sig);
995     goto error;
996     }
997     // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
998     if (len < slen) {
999     u_int diff = slen - len;
1000     memmove(sig + diff, sig, len);
1001     memset(sig, 0, diff);
1002    
1003     } else if (len > slen) {
1004     free(sig);
1005     goto error;
1006    
1007     } else {
1008     // do nothing
1009    
1010     }
1011    
1012 maya 4307 s = get_sshname_from_key(keypair);
1013 maya 4304 buffer_put_string(msg, s, strlen(s));
1014     buffer_append_length(msg, sig, slen);
1015     len = buffer_len(msg);
1016    
1017     // setting
1018     *siglen = len;
1019     *sigptr = malloc(len);
1020     if (*sigptr == NULL) {
1021     free(sig);
1022     goto error;
1023     }
1024     memcpy(*sigptr, buffer_ptr(msg), len);
1025     free(sig);
1026 maya 4324
1027     break;
1028 maya 4307 }
1029 maya 4324 case KEY_DSA: // DSA
1030     {
1031 maya 4304 DSA_SIG *sig;
1032     const EVP_MD *evp_md = EVP_sha1();
1033     EVP_MD_CTX md;
1034     u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1035     u_int rlen, slen, len, dlen;
1036    
1037     // �_�C�W�F�X�g���v�Z
1038     EVP_DigestInit(&md, evp_md);
1039     EVP_DigestUpdate(&md, data, datalen);
1040     EVP_DigestFinal(&md, digest, &dlen);
1041    
1042     // DSA�d�q�������v�Z
1043 maya 4307 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1044 maya 4304 memset(digest, 'd', sizeof(digest));
1045     if (sig == NULL) {
1046     goto error;
1047     }
1048    
1049     // BIGNUM�����o�C�i���l��������
1050     rlen = BN_num_bytes(sig->r);
1051     slen = BN_num_bytes(sig->s);
1052     if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1053     DSA_SIG_free(sig);
1054     goto error;
1055     }
1056     memset(sigblob, 0, SIGBLOB_LEN);
1057     BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1058     BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1059     DSA_SIG_free(sig);
1060    
1061     // setting
1062 maya 4307 s = get_sshname_from_key(keypair);
1063 maya 4304 buffer_put_string(msg, s, strlen(s));
1064     buffer_append_length(msg, sigblob, sizeof(sigblob));
1065     len = buffer_len(msg);
1066    
1067     // setting
1068     *siglen = len;
1069     *sigptr = malloc(len);
1070     if (*sigptr == NULL) {
1071     goto error;
1072     }
1073     memcpy(*sigptr, buffer_ptr(msg), len);
1074    
1075 maya 4324 break;
1076 maya 4304 }
1077 maya 4324 case KEY_ECDSA256: // ECDSA
1078     case KEY_ECDSA384:
1079     case KEY_ECDSA521:
1080     {
1081     ECDSA_SIG *sig;
1082     const EVP_MD *evp_md;
1083     EVP_MD_CTX md;
1084     u_char digest[EVP_MAX_MD_SIZE];
1085     u_int len, dlen, nid;
1086     buffer_t *buf2 = NULL;
1087    
1088 maya 4327 nid = keytype_to_hash_nid(keypair->type);
1089 maya 4324 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1090     goto error;
1091     }
1092     EVP_DigestInit(&md, evp_md);
1093     EVP_DigestUpdate(&md, data, datalen);
1094     EVP_DigestFinal(&md, digest, &dlen);
1095    
1096     sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1097     memset(digest, 'd', sizeof(digest));
1098    
1099     if (sig == NULL) {
1100     goto error;
1101     }
1102    
1103     buf2 = buffer_init();
1104     if (buf2 == NULL) {
1105     // TODO: error check
1106     goto error;
1107     }
1108     buffer_put_bignum2(buf2, sig->r);
1109     buffer_put_bignum2(buf2, sig->s);
1110     ECDSA_SIG_free(sig);
1111    
1112     s = get_sshname_from_key(keypair);
1113     buffer_put_string(msg, s, strlen(s));
1114     buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1115     buffer_free(buf2);
1116     len = buffer_len(msg);
1117    
1118     *siglen = len;
1119     *sigptr = malloc(len);
1120     if (*sigptr == NULL) {
1121     goto error;
1122     }
1123     memcpy(*sigptr, buffer_ptr(msg), len);
1124    
1125     break;
1126     }
1127     default:
1128 maya 4307 buffer_free(msg);
1129     return FALSE;
1130 maya 4324 break;
1131 maya 4307 }
1132 maya 4304
1133     buffer_free(msg);
1134     return TRUE;
1135    
1136     error:
1137     buffer_free(msg);
1138    
1139     return FALSE;
1140     }
1141    
1142    
1143     BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1144     {
1145     buffer_t *msg = NULL;
1146 maya 4307 Key *keypair;
1147 maya 4324 char *s, *tmp;
1148 maya 4304
1149     msg = buffer_init();
1150     if (msg == NULL) {
1151     // TODO: error check
1152     return FALSE;
1153     }
1154    
1155     keypair = pvar->auth_state.cur_cred.key_pair;
1156    
1157 maya 4324 switch (keypair->type) {
1158     case KEY_RSA: // RSA
1159 maya 4307 s = get_sshname_from_key(keypair);
1160 maya 4304 buffer_put_string(msg, s, strlen(s));
1161 maya 4307 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1162     buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1163 maya 4324 break;
1164     case KEY_DSA: // DSA
1165 maya 4307 s = get_sshname_from_key(keypair);
1166 maya 4304 buffer_put_string(msg, s, strlen(s));
1167 maya 4307 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1168     buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1169     buffer_put_bignum2(msg, keypair->dsa->g); // ����
1170     buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1171 maya 4324 break;
1172     case KEY_ECDSA256: // ECDSA
1173     case KEY_ECDSA384:
1174     case KEY_ECDSA521:
1175     s = get_sshname_from_key(keypair);
1176     buffer_put_string(msg, s, strlen(s));
1177     tmp = curve_keytype_to_name(keypair->type);
1178     buffer_put_string(msg, tmp, strlen(tmp));
1179     buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1180     EC_KEY_get0_public_key(keypair->ecdsa));
1181     break;
1182     default:
1183 maya 4307 return FALSE;
1184     }
1185    
1186 maya 4304 *blobptr = msg;
1187     *bloblen = buffer_len(msg);
1188    
1189     return TRUE;
1190     }
1191 maya 4327
1192     int kextype_to_cipher_nid(enum kex_algorithm type)
1193     {
1194     switch (type) {
1195     case KEX_ECDH_SHA2_256:
1196     return NID_X9_62_prime256v1;
1197     case KEX_ECDH_SHA2_384:
1198     return NID_secp384r1;
1199     case KEX_ECDH_SHA2_521:
1200     return NID_secp521r1;
1201     }
1202     return NID_undef;
1203     }
1204    
1205     int keytype_to_hash_nid(enum ssh_keytype type)
1206     {
1207     switch (type) {
1208     case KEY_ECDSA256:
1209     return NID_sha256;
1210     case KEY_ECDSA384:
1211     return NID_sha384;
1212     case KEY_ECDSA521:
1213     return NID_sha512;
1214     }
1215     return NID_undef;
1216     }
1217    
1218     int keytype_to_cipher_nid(enum ssh_keytype type)
1219     {
1220     switch (type) {
1221     case KEY_ECDSA256:
1222     return NID_X9_62_prime256v1;
1223     case KEY_ECDSA384:
1224     return NID_secp384r1;
1225     case KEY_ECDSA521:
1226     return NID_secp521r1;
1227     }
1228     return NID_undef;
1229     }
1230    
1231     enum ssh_keytype nid_to_keytype(int nid)
1232     {
1233     switch (nid) {
1234     case NID_X9_62_prime256v1:
1235     return KEY_ECDSA256;
1236     case NID_secp384r1:
1237     return KEY_ECDSA384;
1238     case NID_secp521r1:
1239     return KEY_ECDSA521;
1240     }
1241     return KEY_UNSPEC;
1242     }

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