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

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