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 4378 - (hide annotations) (download) (as text)
Tue Mar 8 14:19:03 2011 UTC (13 years, 1 month ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 27254 byte(s)
SSH2 の 圧縮で none を利用できるように修正した。
ソース整理
  鍵形式・KEXプロトコル・MAC・圧縮の名前や関数を取得する関数を作成。
    これにより定義で順序を入れ替えてもよくなった。
  enum に型名を付けた。
  共通の関数を使えるところで使うようにした。
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     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_key(Key *key)
704     {
705 maya 4378 return get_ssh_keytype_name(key->type);
706 maya 4321 }
707 maya 4304
708     //
709     // �L�[������������������������
710     //
711 maya 4378 ssh_keytype get_keytype_from_name(char *name)
712 maya 4304 {
713     if (strcmp(name, "rsa1") == 0) {
714     return KEY_RSA1;
715     } else if (strcmp(name, "rsa") == 0) {
716     return KEY_RSA;
717     } else if (strcmp(name, "dsa") == 0) {
718     return KEY_DSA;
719     } else if (strcmp(name, "ssh-rsa") == 0) {
720     return KEY_RSA;
721     } else if (strcmp(name, "ssh-dss") == 0) {
722     return KEY_DSA;
723 maya 4321 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
724     return KEY_ECDSA256;
725     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
726     return KEY_ECDSA384;
727     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
728     return KEY_ECDSA521;
729 maya 4304 }
730     return KEY_UNSPEC;
731     }
732    
733    
734 maya 4378 ssh_keytype key_curve_name_to_keytype(char *name)
735 maya 4321 {
736     if (strcmp(name, "nistp256") == 0) {
737     return KEY_ECDSA256;
738     } else if (strcmp(name, "nistp384") == 0) {
739     return KEY_ECDSA384;
740     } else if (strcmp(name, "nistp521") == 0) {
741     return KEY_ECDSA521;
742     }
743     return KEY_UNSPEC;
744     }
745    
746 maya 4378 char *curve_keytype_to_name(ssh_keytype type)
747 maya 4321 {
748     switch (type) {
749     case KEY_ECDSA256:
750     return "nistp256";
751     break;
752     case KEY_ECDSA384:
753     return "nistp384";
754     break;
755     case KEY_ECDSA521:
756     return "nistp521";
757     break;
758     }
759     return NULL;
760     }
761    
762 maya 4304 //
763     // �L�[���������o�b�t�@���������� (for SSH2)
764     // NOTE:
765     //
766     int key_to_blob(Key *key, char **blobp, int *lenp)
767     {
768     buffer_t *b;
769 maya 4321 char *sshname, *tmp;
770 maya 4304 int len;
771     int ret = 1; // success
772    
773     b = buffer_init();
774     sshname = get_sshname_from_key(key);
775    
776 maya 4321 switch (key->type) {
777     case KEY_RSA:
778 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
779     buffer_put_bignum2(b, key->rsa->e);
780     buffer_put_bignum2(b, key->rsa->n);
781 maya 4321 break;
782     case KEY_DSA:
783 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
784     buffer_put_bignum2(b, key->dsa->p);
785     buffer_put_bignum2(b, key->dsa->q);
786     buffer_put_bignum2(b, key->dsa->g);
787     buffer_put_bignum2(b, key->dsa->pub_key);
788 maya 4321 break;
789     case KEY_ECDSA256:
790     case KEY_ECDSA384:
791     case KEY_ECDSA521:
792     buffer_put_string(b, sshname, strlen(sshname));
793     tmp = curve_keytype_to_name(key->type);
794     buffer_put_string(b, tmp, strlen(tmp));
795     buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
796     EC_KEY_get0_public_key(key->ecdsa));
797     break;
798 maya 4304
799 maya 4321 default:
800 maya 4304 ret = 0;
801     goto error;
802     }
803    
804     len = buffer_len(b);
805     if (lenp != NULL)
806     *lenp = len;
807     if (blobp != NULL) {
808     *blobp = malloc(len);
809     if (*blobp == NULL) {
810     ret = 0;
811     goto error;
812     }
813     memcpy(*blobp, buffer_ptr(b), len);
814     }
815    
816     error:
817     buffer_free(b);
818    
819     return (ret);
820     }
821    
822    
823     //
824     // �o�b�t�@�����L�[�����������o��(for SSH2)
825     // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
826     //
827     Key *key_from_blob(char *data, int blen)
828     {
829     int keynamelen;
830     char key[128];
831     RSA *rsa = NULL;
832     DSA *dsa = NULL;
833 maya 4321 EC_KEY *ecdsa = NULL;
834     EC_POINT *q = NULL;
835     char *curve = NULL;
836 maya 4304 Key *hostkey; // hostkey
837 maya 4378 ssh_keytype type;
838 maya 4304
839     hostkey = malloc(sizeof(Key));
840     if (hostkey == NULL)
841     goto error;
842    
843     memset(hostkey, 0, sizeof(Key));
844    
845     keynamelen = get_uint32_MSBfirst(data);
846     if (keynamelen >= sizeof(key)) {
847     goto error;
848     }
849     data += 4;
850     memcpy(key, data, keynamelen);
851     key[keynamelen] = 0;
852     data += keynamelen;
853    
854     type = get_keytype_from_name(key);
855    
856 maya 4321 switch (type) {
857     case KEY_RSA: // RSA key
858 maya 4304 rsa = RSA_new();
859     if (rsa == NULL) {
860     goto error;
861     }
862     rsa->n = BN_new();
863     rsa->e = BN_new();
864     if (rsa->n == NULL || rsa->e == NULL) {
865     goto error;
866     }
867    
868     buffer_get_bignum2(&data, rsa->e);
869     buffer_get_bignum2(&data, rsa->n);
870    
871     hostkey->type = type;
872     hostkey->rsa = rsa;
873 maya 4321 break;
874 maya 4304
875 maya 4321 case KEY_DSA: // DSA key
876 maya 4304 dsa = DSA_new();
877     if (dsa == NULL) {
878     goto error;
879     }
880     dsa->p = BN_new();
881     dsa->q = BN_new();
882     dsa->g = BN_new();
883     dsa->pub_key = BN_new();
884     if (dsa->p == NULL ||
885     dsa->q == NULL ||
886     dsa->g == NULL ||
887     dsa->pub_key == NULL) {
888     goto error;
889     }
890    
891     buffer_get_bignum2(&data, dsa->p);
892     buffer_get_bignum2(&data, dsa->q);
893     buffer_get_bignum2(&data, dsa->g);
894     buffer_get_bignum2(&data, dsa->pub_key);
895    
896     hostkey->type = type;
897     hostkey->dsa = dsa;
898 maya 4321 break;
899 maya 4304
900 maya 4321 case KEY_ECDSA256: // ECDSA
901     case KEY_ECDSA384:
902     case KEY_ECDSA521:
903     curve = buffer_get_string(&data, NULL);
904     if (type != key_curve_name_to_keytype(curve)) {
905     goto error;
906     }
907    
908 maya 4327 ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
909 maya 4321 if (ecdsa == NULL) {
910     goto error;
911     }
912    
913     q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
914     if (q == NULL) {
915     goto error;
916     }
917    
918     buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
919     if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
920     goto error;
921     }
922    
923     if (EC_KEY_set_public_key(ecdsa, q) != 1) {
924     goto error;
925     }
926    
927     hostkey->type = type;
928     hostkey->ecdsa = ecdsa;
929     break;
930    
931     default: // unknown key
932 maya 4304 goto error;
933     }
934    
935     return (hostkey);
936    
937     error:
938     if (rsa != NULL)
939     RSA_free(rsa);
940     if (dsa != NULL)
941     DSA_free(dsa);
942 maya 4321 if (ecdsa != NULL)
943     EC_KEY_free(ecdsa);
944 maya 4304
945     return NULL;
946     }
947    
948    
949 maya 4307 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
950 maya 4304 {
951     buffer_t *msg = NULL;
952     char *s;
953    
954     msg = buffer_init();
955     if (msg == NULL) {
956     // TODO: error check
957     return FALSE;
958     }
959    
960 maya 4324 switch (keypair->type) {
961     case KEY_RSA: // RSA
962     {
963 maya 4307 const EVP_MD *evp_md = EVP_sha1();
964 maya 4304 EVP_MD_CTX md;
965     u_char digest[EVP_MAX_MD_SIZE], *sig;
966     u_int slen, dlen, len;
967 maya 4307 int ok, nid = NID_sha1;
968 maya 4304
969     // �_�C�W�F�X�g�l���v�Z
970     EVP_DigestInit(&md, evp_md);
971     EVP_DigestUpdate(&md, data, datalen);
972     EVP_DigestFinal(&md, digest, &dlen);
973    
974 maya 4307 slen = RSA_size(keypair->rsa);
975 maya 4304 sig = malloc(slen);
976     if (sig == NULL)
977     goto error;
978    
979     // �d�q�������v�Z
980 maya 4307 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
981 maya 4304 memset(digest, 'd', sizeof(digest));
982     if (ok != 1) { // error
983     free(sig);
984     goto error;
985     }
986     // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
987     if (len < slen) {
988     u_int diff = slen - len;
989     memmove(sig + diff, sig, len);
990     memset(sig, 0, diff);
991    
992     } else if (len > slen) {
993     free(sig);
994     goto error;
995    
996     } else {
997     // do nothing
998    
999     }
1000    
1001 maya 4307 s = get_sshname_from_key(keypair);
1002 maya 4304 buffer_put_string(msg, s, strlen(s));
1003     buffer_append_length(msg, sig, slen);
1004     len = buffer_len(msg);
1005    
1006     // setting
1007     *siglen = len;
1008     *sigptr = malloc(len);
1009     if (*sigptr == NULL) {
1010     free(sig);
1011     goto error;
1012     }
1013     memcpy(*sigptr, buffer_ptr(msg), len);
1014     free(sig);
1015 maya 4324
1016     break;
1017 maya 4307 }
1018 maya 4324 case KEY_DSA: // DSA
1019     {
1020 maya 4304 DSA_SIG *sig;
1021     const EVP_MD *evp_md = EVP_sha1();
1022     EVP_MD_CTX md;
1023     u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1024     u_int rlen, slen, len, dlen;
1025    
1026     // �_�C�W�F�X�g���v�Z
1027     EVP_DigestInit(&md, evp_md);
1028     EVP_DigestUpdate(&md, data, datalen);
1029     EVP_DigestFinal(&md, digest, &dlen);
1030    
1031     // DSA�d�q�������v�Z
1032 maya 4307 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1033 maya 4304 memset(digest, 'd', sizeof(digest));
1034     if (sig == NULL) {
1035     goto error;
1036     }
1037    
1038     // BIGNUM�����o�C�i���l��������
1039     rlen = BN_num_bytes(sig->r);
1040     slen = BN_num_bytes(sig->s);
1041     if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1042     DSA_SIG_free(sig);
1043     goto error;
1044     }
1045     memset(sigblob, 0, SIGBLOB_LEN);
1046     BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1047     BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1048     DSA_SIG_free(sig);
1049    
1050     // setting
1051 maya 4307 s = get_sshname_from_key(keypair);
1052 maya 4304 buffer_put_string(msg, s, strlen(s));
1053     buffer_append_length(msg, sigblob, sizeof(sigblob));
1054     len = buffer_len(msg);
1055    
1056     // setting
1057     *siglen = len;
1058     *sigptr = malloc(len);
1059     if (*sigptr == NULL) {
1060     goto error;
1061     }
1062     memcpy(*sigptr, buffer_ptr(msg), len);
1063    
1064 maya 4324 break;
1065 maya 4304 }
1066 maya 4324 case KEY_ECDSA256: // ECDSA
1067     case KEY_ECDSA384:
1068     case KEY_ECDSA521:
1069     {
1070     ECDSA_SIG *sig;
1071     const EVP_MD *evp_md;
1072     EVP_MD_CTX md;
1073     u_char digest[EVP_MAX_MD_SIZE];
1074     u_int len, dlen, nid;
1075     buffer_t *buf2 = NULL;
1076    
1077 maya 4327 nid = keytype_to_hash_nid(keypair->type);
1078 maya 4324 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1079     goto error;
1080     }
1081     EVP_DigestInit(&md, evp_md);
1082     EVP_DigestUpdate(&md, data, datalen);
1083     EVP_DigestFinal(&md, digest, &dlen);
1084    
1085     sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
1086     memset(digest, 'd', sizeof(digest));
1087    
1088     if (sig == NULL) {
1089     goto error;
1090     }
1091    
1092     buf2 = buffer_init();
1093     if (buf2 == NULL) {
1094     // TODO: error check
1095     goto error;
1096     }
1097     buffer_put_bignum2(buf2, sig->r);
1098     buffer_put_bignum2(buf2, sig->s);
1099     ECDSA_SIG_free(sig);
1100    
1101     s = get_sshname_from_key(keypair);
1102     buffer_put_string(msg, s, strlen(s));
1103     buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
1104     buffer_free(buf2);
1105     len = buffer_len(msg);
1106    
1107     *siglen = len;
1108     *sigptr = malloc(len);
1109     if (*sigptr == NULL) {
1110     goto error;
1111     }
1112     memcpy(*sigptr, buffer_ptr(msg), len);
1113    
1114     break;
1115     }
1116     default:
1117 maya 4307 buffer_free(msg);
1118     return FALSE;
1119 maya 4324 break;
1120 maya 4307 }
1121 maya 4304
1122     buffer_free(msg);
1123     return TRUE;
1124    
1125     error:
1126     buffer_free(msg);
1127    
1128     return FALSE;
1129     }
1130    
1131    
1132     BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1133     {
1134     buffer_t *msg = NULL;
1135 maya 4307 Key *keypair;
1136 maya 4324 char *s, *tmp;
1137 maya 4304
1138     msg = buffer_init();
1139     if (msg == NULL) {
1140     // TODO: error check
1141     return FALSE;
1142     }
1143    
1144     keypair = pvar->auth_state.cur_cred.key_pair;
1145    
1146 maya 4324 switch (keypair->type) {
1147     case KEY_RSA: // RSA
1148 maya 4307 s = get_sshname_from_key(keypair);
1149 maya 4304 buffer_put_string(msg, s, strlen(s));
1150 maya 4307 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1151     buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1152 maya 4324 break;
1153     case KEY_DSA: // DSA
1154 maya 4307 s = get_sshname_from_key(keypair);
1155 maya 4304 buffer_put_string(msg, s, strlen(s));
1156 maya 4307 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1157     buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1158     buffer_put_bignum2(msg, keypair->dsa->g); // ����
1159     buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1160 maya 4324 break;
1161     case KEY_ECDSA256: // ECDSA
1162     case KEY_ECDSA384:
1163     case KEY_ECDSA521:
1164     s = get_sshname_from_key(keypair);
1165     buffer_put_string(msg, s, strlen(s));
1166     tmp = curve_keytype_to_name(keypair->type);
1167     buffer_put_string(msg, tmp, strlen(tmp));
1168     buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa),
1169     EC_KEY_get0_public_key(keypair->ecdsa));
1170     break;
1171     default:
1172 maya 4307 return FALSE;
1173     }
1174    
1175 maya 4304 *blobptr = msg;
1176     *bloblen = buffer_len(msg);
1177    
1178     return TRUE;
1179     }
1180 maya 4327
1181 maya 4378 int kextype_to_cipher_nid(kex_algorithm type)
1182 maya 4327 {
1183     switch (type) {
1184     case KEX_ECDH_SHA2_256:
1185     return NID_X9_62_prime256v1;
1186     case KEX_ECDH_SHA2_384:
1187     return NID_secp384r1;
1188     case KEX_ECDH_SHA2_521:
1189     return NID_secp521r1;
1190     }
1191     return NID_undef;
1192     }
1193    
1194 maya 4378 int keytype_to_hash_nid(ssh_keytype type)
1195 maya 4327 {
1196     switch (type) {
1197     case KEY_ECDSA256:
1198     return NID_sha256;
1199     case KEY_ECDSA384:
1200     return NID_sha384;
1201     case KEY_ECDSA521:
1202     return NID_sha512;
1203     }
1204     return NID_undef;
1205     }
1206    
1207 maya 4378 int keytype_to_cipher_nid(ssh_keytype type)
1208 maya 4327 {
1209     switch (type) {
1210     case KEY_ECDSA256:
1211     return NID_X9_62_prime256v1;
1212     case KEY_ECDSA384:
1213     return NID_secp384r1;
1214     case KEY_ECDSA521:
1215     return NID_secp521r1;
1216     }
1217     return NID_undef;
1218     }
1219    
1220 maya 4378 ssh_keytype nid_to_keytype(int nid)
1221 maya 4327 {
1222     switch (nid) {
1223     case NID_X9_62_prime256v1:
1224     return KEY_ECDSA256;
1225     case NID_secp384r1:
1226     return KEY_ECDSA384;
1227     case NID_secp521r1:
1228     return KEY_ECDSA521;
1229     }
1230     return KEY_UNSPEC;
1231     }

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