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 4321 - (hide annotations) (download) (as text)
Sat Feb 19 07:41:41 2011 UTC (13 years, 1 month ago) by maya
Original Path: trunk/ttssh2/ttxssh/key.c
File MIME type: text/x-csrc
File size: 25588 byte(s)
SSH2 の ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521 ホスト鍵方式をサポートした
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     switch (keytype) {
339     case KEY_ECDSA256:
340     nid = NID_sha256;
341     break;
342     case KEY_ECDSA384:
343     nid = NID_sha384;
344     break;
345     case KEY_ECDSA521:
346     nid = NID_sha512;
347     break;
348     }
349     if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
350     return -8;
351     }
352     EVP_DigestInit(&md, evp_md);
353     EVP_DigestUpdate(&md, data, datalen);
354     EVP_DigestFinal(&md, digest, &dlen);
355    
356     ret = ECDSA_do_verify(digest, dlen, sig, key);
357     memset(digest, 'd', sizeof(digest));
358    
359     ECDSA_SIG_free(sig);
360    
361     return ret;
362     }
363    
364 maya 4307 int key_verify(Key *key,
365 maya 4304 unsigned char *signature, unsigned int signaturelen,
366     unsigned char *data, unsigned int datalen)
367     {
368     int ret = 0;
369    
370 maya 4321 switch (key->type) {
371     case KEY_RSA:
372 maya 4307 ret = ssh_rsa_verify(key->rsa, signature, signaturelen, data, datalen);
373 maya 4321 break;
374     case KEY_DSA:
375 maya 4307 ret = ssh_dss_verify(key->dsa, signature, signaturelen, data, datalen);
376 maya 4321 break;
377     case KEY_ECDSA256:
378     case KEY_ECDSA384:
379     case KEY_ECDSA521:
380     ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen);
381     break;
382     default:
383 maya 4304 return -1;
384     }
385    
386     return (ret); // success
387     }
388    
389     //
390     // RSA�\����������
391     //
392     RSA *duplicate_RSA(RSA *src)
393     {
394     RSA *rsa = NULL;
395    
396     rsa = RSA_new();
397     if (rsa == NULL)
398     goto error;
399     rsa->n = BN_new();
400     rsa->e = BN_new();
401     if (rsa->n == NULL || rsa->e == NULL) {
402     RSA_free(rsa);
403     goto error;
404     }
405    
406     // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
407     BN_copy(rsa->n, src->n);
408     BN_copy(rsa->e, src->e);
409    
410     error:
411     return (rsa);
412     }
413    
414    
415     //
416     // DSA�\����������
417     //
418     DSA *duplicate_DSA(DSA *src)
419     {
420     DSA *dsa = NULL;
421    
422     dsa = DSA_new();
423     if (dsa == NULL)
424     goto error;
425     dsa->p = BN_new();
426     dsa->q = BN_new();
427     dsa->g = BN_new();
428     dsa->pub_key = BN_new();
429     if (dsa->p == NULL ||
430     dsa->q == NULL ||
431     dsa->g == NULL ||
432     dsa->pub_key == NULL) {
433     DSA_free(dsa);
434     goto error;
435     }
436    
437     // �[���R�s�[(deep copy)���s���B�����R�s�[(shallow copy)��NG�B
438     BN_copy(dsa->p, src->p);
439     BN_copy(dsa->q, src->q);
440     BN_copy(dsa->g, src->g);
441     BN_copy(dsa->pub_key, src->pub_key);
442    
443     error:
444     return (dsa);
445     }
446    
447    
448     char* key_fingerprint_raw(Key *k, int *dgst_raw_length)
449     {
450     const EVP_MD *md = NULL;
451     EVP_MD_CTX ctx;
452     char *blob = NULL;
453     char *retval = NULL;
454     int len = 0;
455     int nlen, elen;
456     RSA *rsa;
457    
458     *dgst_raw_length = 0;
459    
460     // MD5�A���S���Y�����g�p����
461     md = EVP_md5();
462    
463     switch (k->type) {
464     case KEY_RSA1:
465     rsa = make_key(NULL, k->bits, k->exp, k->mod);
466     nlen = BN_num_bytes(rsa->n);
467     elen = BN_num_bytes(rsa->e);
468     len = nlen + elen;
469     blob = malloc(len);
470     if (blob == NULL) {
471     // TODO:
472     }
473     BN_bn2bin(rsa->n, blob);
474     BN_bn2bin(rsa->e, blob + nlen);
475     RSA_free(rsa);
476     break;
477    
478     case KEY_DSA:
479     case KEY_RSA:
480 maya 4321 case KEY_ECDSA256:
481     case KEY_ECDSA384:
482     case KEY_ECDSA521:
483 maya 4304 key_to_blob(k, &blob, &len);
484     break;
485    
486     case KEY_UNSPEC:
487     return retval;
488     break;
489    
490     default:
491     //fatal("key_fingerprint_raw: bad key type %d", k->type);
492     break;
493     }
494    
495     if (blob != NULL) {
496     retval = malloc(EVP_MAX_MD_SIZE);
497     if (retval == NULL) {
498     // TODO:
499     }
500     EVP_DigestInit(&ctx, md);
501     EVP_DigestUpdate(&ctx, blob, len);
502     EVP_DigestFinal(&ctx, retval, dgst_raw_length);
503     memset(blob, 0, len);
504     free(blob);
505     } else {
506     //fatal("key_fingerprint_raw: blob is null");
507     }
508     return retval;
509     }
510    
511    
512     const char *
513     key_type(const Key *k)
514     {
515     switch (k->type) {
516     case KEY_RSA1:
517     return "RSA1";
518     case KEY_RSA:
519     return "RSA";
520     case KEY_DSA:
521     return "DSA";
522 maya 4321 case KEY_ECDSA256:
523     case KEY_ECDSA384:
524     case KEY_ECDSA521:
525     return "ECDSA";
526 maya 4304 }
527     return "unknown";
528     }
529    
530     unsigned int
531     key_size(const Key *k)
532     {
533     switch (k->type) {
534     case KEY_RSA1:
535     // SSH1�������� key->rsa �� key->dsa �� NULL �����������A�g�������B
536     return k->bits;
537     case KEY_RSA:
538     return BN_num_bits(k->rsa->n);
539     case KEY_DSA:
540     return BN_num_bits(k->dsa->p);
541 maya 4321 case KEY_ECDSA256:
542     return 256;
543     case KEY_ECDSA384:
544     return 384;
545     case KEY_ECDSA521:
546     return 521;
547 maya 4304 }
548     return 0;
549     }
550    
551     // based on OpenSSH 5.1
552     #define FLDBASE 8
553     #define FLDSIZE_Y (FLDBASE + 1)
554     #define FLDSIZE_X (FLDBASE * 2 + 1)
555     static char *
556     key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
557     {
558     /*
559     * Chars to be used after each other every time the worm
560     * intersects with itself. Matter of taste.
561     */
562     char *augmentation_string = " .o+=*BOX@%&#/^SE";
563     char *retval, *p;
564     unsigned char field[FLDSIZE_X][FLDSIZE_Y];
565     unsigned int i, b;
566     int x, y;
567     size_t len = strlen(augmentation_string) - 1;
568    
569     retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2));
570    
571     /* initialize field */
572     memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
573     x = FLDSIZE_X / 2;
574     y = FLDSIZE_Y / 2;
575    
576     /* process raw key */
577     for (i = 0; i < dgst_raw_len; i++) {
578     int input;
579     /* each byte conveys four 2-bit move commands */
580     input = dgst_raw[i];
581     for (b = 0; b < 4; b++) {
582     /* evaluate 2 bit, rest is shifted later */
583     x += (input & 0x1) ? 1 : -1;
584     y += (input & 0x2) ? 1 : -1;
585    
586     /* assure we are still in bounds */
587     x = max(x, 0);
588     y = max(y, 0);
589     x = min(x, FLDSIZE_X - 1);
590     y = min(y, FLDSIZE_Y - 1);
591    
592     /* augment the field */
593     field[x][y]++;
594     input = input >> 2;
595     }
596     }
597    
598     /* mark starting point and end point*/
599     field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
600     field[x][y] = len;
601    
602     /* fill in retval */
603     _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k));
604     p = strchr(retval, '\0');
605    
606     /* output upper border */
607     for (i = p - retval - 1; i < FLDSIZE_X; i++)
608     *p++ = '-';
609     *p++ = '+';
610     *p++ = '\r';
611     *p++ = '\n';
612    
613     /* output content */
614     for (y = 0; y < FLDSIZE_Y; y++) {
615     *p++ = '|';
616     for (x = 0; x < FLDSIZE_X; x++)
617     *p++ = augmentation_string[min(field[x][y], len)];
618     *p++ = '|';
619     *p++ = '\r';
620     *p++ = '\n';
621     }
622    
623     /* output lower border */
624     *p++ = '+';
625     for (i = 0; i < FLDSIZE_X; i++)
626     *p++ = '-';
627     *p++ = '+';
628    
629     return retval;
630     }
631     #undef FLDBASE
632     #undef FLDSIZE_Y
633     #undef FLDSIZE_X
634    
635     //
636     // fingerprint�i�w���F�z�X�g���J�����n�b�V���j����������
637     //
638     char *key_fingerprint(Key *key, enum fp_rep dgst_rep)
639     {
640     char *retval = NULL;
641     unsigned char *dgst_raw;
642     int dgst_raw_len;
643     int i, retval_len;
644    
645     // fingerprint���n�b�V���l�i�o�C�i���j��������
646     dgst_raw = key_fingerprint_raw(key, &dgst_raw_len);
647    
648     if (dgst_rep == SSH_FP_HEX) {
649     // 16�i�\�L����������
650     retval_len = dgst_raw_len * 3 + 1;
651     retval = malloc(retval_len);
652     retval[0] = '\0';
653     for (i = 0; i < dgst_raw_len; i++) {
654     char hex[4];
655     _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]);
656     strncat_s(retval, retval_len, hex, _TRUNCATE);
657     }
658    
659     /* Remove the trailing ':' character */
660     retval[(dgst_raw_len * 3) - 1] = '\0';
661    
662     } else if (dgst_rep == SSH_FP_RANDOMART) {
663     retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key);
664    
665     } else {
666    
667     }
668    
669     memset(dgst_raw, 0, dgst_raw_len);
670     free(dgst_raw);
671    
672     return (retval);
673     }
674    
675    
676     //
677     // �L�[����������������
678     //
679     void key_free(Key *key)
680     {
681 maya 4321 if (key == NULL) {
682     return;
683     }
684    
685 maya 4304 switch (key->type) {
686     case KEY_RSA1:
687     case KEY_RSA:
688     if (key->rsa != NULL)
689     RSA_free(key->rsa);
690     key->rsa = NULL;
691     break;
692    
693     case KEY_DSA:
694     if (key->dsa != NULL)
695     DSA_free(key->dsa);
696     key->dsa = NULL;
697     break;
698 maya 4321
699     case KEY_ECDSA256:
700     case KEY_ECDSA384:
701     case KEY_ECDSA521:
702     if (key->ecdsa != NULL)
703     EC_KEY_free(key->ecdsa);
704     key->ecdsa = NULL;
705     break;
706 maya 4304 }
707     free(key);
708     }
709    
710     //
711     // �L�[���������������p����
712     //
713 maya 4321 char *get_sshname_from_keytype(enum ssh_keytype type)
714 maya 4304 {
715 maya 4321 if (type == KEY_RSA) {
716 maya 4304 return "ssh-rsa";
717 maya 4321 } else if (type == KEY_DSA) {
718 maya 4304 return "ssh-dss";
719 maya 4321 } else if (type == KEY_ECDSA256) {
720     return "ecdsa-sha2-nistp256";
721     } else if (type == KEY_ECDSA384) {
722     return "ecdsa-sha2-nistp384";
723     } else if (type == KEY_ECDSA521) {
724     return "ecdsa-sha2-nistp521";
725 maya 4304 } else {
726     return "ssh-unknown";
727     }
728     }
729 maya 4321 char *get_sshname_from_key(Key *key)
730     {
731     return get_sshname_from_keytype(key->type);
732     }
733 maya 4304
734     //
735     // �L�[������������������������
736     //
737 maya 4307 enum ssh_keytype get_keytype_from_name(char *name)
738 maya 4304 {
739     if (strcmp(name, "rsa1") == 0) {
740     return KEY_RSA1;
741     } else if (strcmp(name, "rsa") == 0) {
742     return KEY_RSA;
743     } else if (strcmp(name, "dsa") == 0) {
744     return KEY_DSA;
745     } else if (strcmp(name, "ssh-rsa") == 0) {
746     return KEY_RSA;
747     } else if (strcmp(name, "ssh-dss") == 0) {
748     return KEY_DSA;
749 maya 4321 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
750     return KEY_ECDSA256;
751     } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
752     return KEY_ECDSA384;
753     } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
754     return KEY_ECDSA521;
755 maya 4304 }
756     return KEY_UNSPEC;
757     }
758    
759    
760 maya 4321 enum ssh_keytype key_curve_name_to_keytype(char *name)
761     {
762     if (strcmp(name, "nistp256") == 0) {
763     return KEY_ECDSA256;
764     } else if (strcmp(name, "nistp384") == 0) {
765     return KEY_ECDSA384;
766     } else if (strcmp(name, "nistp521") == 0) {
767     return KEY_ECDSA521;
768     }
769     return KEY_UNSPEC;
770     }
771    
772     char *curve_keytype_to_name(enum ssh_keytype type)
773     {
774     switch (type) {
775     case KEY_ECDSA256:
776     return "nistp256";
777     break;
778     case KEY_ECDSA384:
779     return "nistp384";
780     break;
781     case KEY_ECDSA521:
782     return "nistp521";
783     break;
784     }
785     return NULL;
786     }
787    
788 maya 4304 //
789     // �L�[���������o�b�t�@���������� (for SSH2)
790     // NOTE:
791     //
792     int key_to_blob(Key *key, char **blobp, int *lenp)
793     {
794     buffer_t *b;
795 maya 4321 char *sshname, *tmp;
796 maya 4304 int len;
797     int ret = 1; // success
798    
799     b = buffer_init();
800     sshname = get_sshname_from_key(key);
801    
802 maya 4321 switch (key->type) {
803     case KEY_RSA:
804 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
805     buffer_put_bignum2(b, key->rsa->e);
806     buffer_put_bignum2(b, key->rsa->n);
807 maya 4321 break;
808     case KEY_DSA:
809 maya 4304 buffer_put_string(b, sshname, strlen(sshname));
810     buffer_put_bignum2(b, key->dsa->p);
811     buffer_put_bignum2(b, key->dsa->q);
812     buffer_put_bignum2(b, key->dsa->g);
813     buffer_put_bignum2(b, key->dsa->pub_key);
814 maya 4321 break;
815     case KEY_ECDSA256:
816     case KEY_ECDSA384:
817     case KEY_ECDSA521:
818     buffer_put_string(b, sshname, strlen(sshname));
819     tmp = curve_keytype_to_name(key->type);
820     buffer_put_string(b, tmp, strlen(tmp));
821     buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
822     EC_KEY_get0_public_key(key->ecdsa));
823     break;
824 maya 4304
825 maya 4321 default:
826 maya 4304 ret = 0;
827     goto error;
828     }
829    
830     len = buffer_len(b);
831     if (lenp != NULL)
832     *lenp = len;
833     if (blobp != NULL) {
834     *blobp = malloc(len);
835     if (*blobp == NULL) {
836     ret = 0;
837     goto error;
838     }
839     memcpy(*blobp, buffer_ptr(b), len);
840     }
841    
842     error:
843     buffer_free(b);
844    
845     return (ret);
846     }
847    
848    
849     //
850     // �o�b�t�@�����L�[�����������o��(for SSH2)
851     // NOTE: ���l���A���P�[�g���������������A�����o�������������������B
852     //
853     Key *key_from_blob(char *data, int blen)
854     {
855     int keynamelen;
856     char key[128];
857     RSA *rsa = NULL;
858     DSA *dsa = NULL;
859 maya 4321 EC_KEY *ecdsa = NULL;
860     EC_POINT *q = NULL;
861     char *curve = NULL;
862 maya 4304 Key *hostkey; // hostkey
863 maya 4307 enum ssh_keytype type;
864 maya 4304
865     hostkey = malloc(sizeof(Key));
866     if (hostkey == NULL)
867     goto error;
868    
869     memset(hostkey, 0, sizeof(Key));
870    
871     keynamelen = get_uint32_MSBfirst(data);
872     if (keynamelen >= sizeof(key)) {
873     goto error;
874     }
875     data += 4;
876     memcpy(key, data, keynamelen);
877     key[keynamelen] = 0;
878     data += keynamelen;
879    
880     type = get_keytype_from_name(key);
881    
882 maya 4321 switch (type) {
883     case KEY_RSA: // RSA key
884 maya 4304 rsa = RSA_new();
885     if (rsa == NULL) {
886     goto error;
887     }
888     rsa->n = BN_new();
889     rsa->e = BN_new();
890     if (rsa->n == NULL || rsa->e == NULL) {
891     goto error;
892     }
893    
894     buffer_get_bignum2(&data, rsa->e);
895     buffer_get_bignum2(&data, rsa->n);
896    
897     hostkey->type = type;
898     hostkey->rsa = rsa;
899 maya 4321 break;
900 maya 4304
901 maya 4321 case KEY_DSA: // DSA key
902 maya 4304 dsa = DSA_new();
903     if (dsa == NULL) {
904     goto error;
905     }
906     dsa->p = BN_new();
907     dsa->q = BN_new();
908     dsa->g = BN_new();
909     dsa->pub_key = BN_new();
910     if (dsa->p == NULL ||
911     dsa->q == NULL ||
912     dsa->g == NULL ||
913     dsa->pub_key == NULL) {
914     goto error;
915     }
916    
917     buffer_get_bignum2(&data, dsa->p);
918     buffer_get_bignum2(&data, dsa->q);
919     buffer_get_bignum2(&data, dsa->g);
920     buffer_get_bignum2(&data, dsa->pub_key);
921    
922     hostkey->type = type;
923     hostkey->dsa = dsa;
924 maya 4321 break;
925 maya 4304
926 maya 4321 case KEY_ECDSA256: // ECDSA
927     case KEY_ECDSA384:
928     case KEY_ECDSA521:
929     curve = buffer_get_string(&data, NULL);
930     if (type != key_curve_name_to_keytype(curve)) {
931     goto error;
932     }
933    
934     switch (type) {
935     case KEY_ECDSA256:
936     ecdsa = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
937     break;
938     case KEY_ECDSA384:
939     ecdsa = EC_KEY_new_by_curve_name(NID_secp384r1);
940     break;
941     case KEY_ECDSA521:
942     ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1);
943     break;
944     default:
945     goto error;
946     }
947     if (ecdsa == NULL) {
948     goto error;
949     }
950    
951     q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
952     if (q == NULL) {
953     goto error;
954     }
955    
956     buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
957     if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
958     goto error;
959     }
960    
961     if (EC_KEY_set_public_key(ecdsa, q) != 1) {
962     goto error;
963     }
964    
965     hostkey->type = type;
966     hostkey->ecdsa = ecdsa;
967     break;
968    
969     default: // unknown key
970 maya 4304 goto error;
971     }
972    
973     return (hostkey);
974    
975     error:
976     if (rsa != NULL)
977     RSA_free(rsa);
978     if (dsa != NULL)
979     DSA_free(dsa);
980 maya 4321 if (ecdsa != NULL)
981     EC_KEY_free(ecdsa);
982 maya 4304
983     return NULL;
984     }
985    
986    
987 maya 4307 BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
988 maya 4304 {
989     buffer_t *msg = NULL;
990     char *s;
991    
992     msg = buffer_init();
993     if (msg == NULL) {
994     // TODO: error check
995     return FALSE;
996     }
997    
998 maya 4307 if (keypair->type == KEY_RSA) { // RSA
999     const EVP_MD *evp_md = EVP_sha1();
1000 maya 4304 EVP_MD_CTX md;
1001     u_char digest[EVP_MAX_MD_SIZE], *sig;
1002     u_int slen, dlen, len;
1003 maya 4307 int ok, nid = NID_sha1;
1004 maya 4304
1005     // �_�C�W�F�X�g�l���v�Z
1006     EVP_DigestInit(&md, evp_md);
1007     EVP_DigestUpdate(&md, data, datalen);
1008     EVP_DigestFinal(&md, digest, &dlen);
1009    
1010 maya 4307 slen = RSA_size(keypair->rsa);
1011 maya 4304 sig = malloc(slen);
1012     if (sig == NULL)
1013     goto error;
1014    
1015     // �d�q�������v�Z
1016 maya 4307 ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
1017 maya 4304 memset(digest, 'd', sizeof(digest));
1018     if (ok != 1) { // error
1019     free(sig);
1020     goto error;
1021     }
1022     // �������T�C�Y���o�b�t�@���������������A�������������B�������[�����������B
1023     if (len < slen) {
1024     u_int diff = slen - len;
1025     memmove(sig + diff, sig, len);
1026     memset(sig, 0, diff);
1027    
1028     } else if (len > slen) {
1029     free(sig);
1030     goto error;
1031    
1032     } else {
1033     // do nothing
1034    
1035     }
1036    
1037 maya 4307 s = get_sshname_from_key(keypair);
1038 maya 4304 buffer_put_string(msg, s, strlen(s));
1039     buffer_append_length(msg, sig, slen);
1040     len = buffer_len(msg);
1041    
1042     // setting
1043     *siglen = len;
1044     *sigptr = malloc(len);
1045     if (*sigptr == NULL) {
1046     free(sig);
1047     goto error;
1048     }
1049     memcpy(*sigptr, buffer_ptr(msg), len);
1050     free(sig);
1051    
1052 maya 4307 }
1053     else if (keypair->type == KEY_DSA) { // DSA
1054 maya 4304 DSA_SIG *sig;
1055     const EVP_MD *evp_md = EVP_sha1();
1056     EVP_MD_CTX md;
1057     u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
1058     u_int rlen, slen, len, dlen;
1059    
1060     // �_�C�W�F�X�g���v�Z
1061     EVP_DigestInit(&md, evp_md);
1062     EVP_DigestUpdate(&md, data, datalen);
1063     EVP_DigestFinal(&md, digest, &dlen);
1064    
1065     // DSA�d�q�������v�Z
1066 maya 4307 sig = DSA_do_sign(digest, dlen, keypair->dsa);
1067 maya 4304 memset(digest, 'd', sizeof(digest));
1068     if (sig == NULL) {
1069     goto error;
1070     }
1071    
1072     // BIGNUM�����o�C�i���l��������
1073     rlen = BN_num_bytes(sig->r);
1074     slen = BN_num_bytes(sig->s);
1075     if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1076     DSA_SIG_free(sig);
1077     goto error;
1078     }
1079     memset(sigblob, 0, SIGBLOB_LEN);
1080     BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1081     BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1082     DSA_SIG_free(sig);
1083    
1084     // setting
1085 maya 4307 s = get_sshname_from_key(keypair);
1086 maya 4304 buffer_put_string(msg, s, strlen(s));
1087     buffer_append_length(msg, sigblob, sizeof(sigblob));
1088     len = buffer_len(msg);
1089    
1090     // setting
1091     *siglen = len;
1092     *sigptr = malloc(len);
1093     if (*sigptr == NULL) {
1094     goto error;
1095     }
1096     memcpy(*sigptr, buffer_ptr(msg), len);
1097    
1098     }
1099 maya 4307 else {
1100     buffer_free(msg);
1101     return FALSE;
1102     }
1103 maya 4304
1104     buffer_free(msg);
1105     return TRUE;
1106    
1107     error:
1108     buffer_free(msg);
1109    
1110     return FALSE;
1111     }
1112    
1113    
1114     BOOL get_SSH2_publickey_blob(PTInstVar pvar, buffer_t **blobptr, int *bloblen)
1115     {
1116     buffer_t *msg = NULL;
1117 maya 4307 Key *keypair;
1118 maya 4304 char *s;
1119    
1120     msg = buffer_init();
1121     if (msg == NULL) {
1122     // TODO: error check
1123     return FALSE;
1124     }
1125    
1126     keypair = pvar->auth_state.cur_cred.key_pair;
1127    
1128 maya 4307 if (keypair->type == KEY_RSA) { // RSA
1129     s = get_sshname_from_key(keypair);
1130 maya 4304 buffer_put_string(msg, s, strlen(s));
1131 maya 4307 buffer_put_bignum2(msg, keypair->rsa->e); // ���J�w��
1132     buffer_put_bignum2(msg, keypair->rsa->n); // p�~q
1133 maya 4304
1134 maya 4307 }
1135     else if (keypair->type == KEY_RSA) { // DSA
1136     s = get_sshname_from_key(keypair);
1137 maya 4304 buffer_put_string(msg, s, strlen(s));
1138 maya 4307 buffer_put_bignum2(msg, keypair->dsa->p); // �f��
1139     buffer_put_bignum2(msg, keypair->dsa->q); // (p-1)���f����
1140     buffer_put_bignum2(msg, keypair->dsa->g); // ����
1141     buffer_put_bignum2(msg, keypair->dsa->pub_key); // ���J��
1142 maya 4304
1143     }
1144 maya 4307 else {
1145     return FALSE;
1146 maya 4304
1147 maya 4307 }
1148    
1149 maya 4304 *blobptr = msg;
1150     *bloblen = buffer_len(msg);
1151    
1152     return TRUE;
1153     }

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