Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/hostkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10068 - (show annotations) (download) (as text)
Sun Jul 17 15:39:53 2022 UTC (20 months, 3 weeks ago) by doda
File MIME type: text/x-csrc
File size: 7678 byte(s)
公開鍵認証で rsa-sha2-256/512 に対応した

Ticket: #36109

・優先度は rsa-sha2-512, rsa-sha2-256, ssh-rsa 固定
1 /*
2 * (C) 2021- TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "ttxssh.h"
30 #include "hostkey.h"
31 #include "kex.h"
32
33
34 struct ssh2_host_key_t {
35 ssh_keyalgo algo;
36 ssh_keytype type;
37 int digest_type;
38 char *name;
39 };
40
41 static const struct ssh2_host_key_t ssh2_host_key[] = {
42 {KEY_ALGO_RSA1, KEY_RSA1, NID_sha1, "ssh-rsa1"}, // for SSH1 only
43 {KEY_ALGO_RSA, KEY_RSA, NID_sha1, "ssh-rsa"}, // RFC4253
44 {KEY_ALGO_DSA, KEY_DSA, NID_sha1, "ssh-dss"}, // RFC4253
45 {KEY_ALGO_ECDSA256, KEY_ECDSA256, NID_sha256, "ecdsa-sha2-nistp256"}, // RFC5656
46 {KEY_ALGO_ECDSA384, KEY_ECDSA384, NID_sha384, "ecdsa-sha2-nistp384"}, // RFC5656
47 {KEY_ALGO_ECDSA521, KEY_ECDSA521, NID_sha512, "ecdsa-sha2-nistp521"}, // RFC5656
48 {KEY_ALGO_ED25519, KEY_ED25519, NID_sha512, "ssh-ed25519"}, // RDC8709
49 {KEY_ALGO_RSASHA256,KEY_RSA, NID_sha256, "rsa-sha2-256"}, // RFC8332
50 {KEY_ALGO_RSASHA512,KEY_RSA, NID_sha512, "rsa-sha2-512"}, // RFC8332
51 {KEY_ALGO_UNSPEC, KEY_UNSPEC, NID_undef, "ssh-unknown"},
52 {KEY_ALGO_NONE, KEY_NONE, NID_undef, NULL},
53 };
54
55 struct ssh_digest_t {
56 digest_algorithm id;
57 char *name;
58 };
59
60 /* NB. Indexed directly by algorithm number */
61 static const struct ssh_digest_t ssh_digests[] = {
62 { SSH_DIGEST_MD5, "MD5" },
63 { SSH_DIGEST_RIPEMD160, "RIPEMD160" },
64 { SSH_DIGEST_SHA1, "SHA1" },
65 { SSH_DIGEST_SHA256, "SHA256" },
66 { SSH_DIGEST_SHA384, "SHA384" },
67 { SSH_DIGEST_SHA512, "SHA512" },
68 { SSH_DIGEST_MAX, NULL },
69 };
70
71
72 ssh_keytype get_hostkey_type_from_name(char *name)
73 {
74 if (strcmp(name, "rsa1") == 0) {
75 return KEY_RSA1;
76 } else if (strcmp(name, "rsa") == 0) {
77 return KEY_RSA;
78 } else if (strcmp(name, "dsa") == 0) {
79 return KEY_DSA;
80 } else if (strcmp(name, "ssh-rsa") == 0) {
81 return KEY_RSA;
82 } else if (strcmp(name, "ssh-dss") == 0) {
83 return KEY_DSA;
84 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
85 return KEY_ECDSA256;
86 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
87 return KEY_ECDSA384;
88 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
89 return KEY_ECDSA521;
90 } else if (strcmp(name, "ssh-ed25519") == 0) {
91 return KEY_ED25519;
92 }
93 return KEY_UNSPEC;
94 }
95
96 char* get_ssh2_hostkey_type_name(ssh_keytype type)
97 {
98 const struct ssh2_host_key_t *ptr = ssh2_host_key;
99
100 while (ptr->name != NULL) {
101 if (type == ptr->type) {
102 return ptr->name;
103 }
104 ptr++;
105 }
106
107 // not found.
108 return "ssh-unknown";
109 }
110
111 char *get_ssh2_hostkey_type_name_from_key(Key *key)
112 {
113 return get_ssh2_hostkey_type_name(key->type);
114 }
115
116 char* get_ssh2_keyalgo_name(ssh_keyalgo algo)
117 {
118 const struct ssh2_host_key_t *ptr = ssh2_host_key;
119
120 while (ptr->name != NULL) {
121 if (algo == ptr->algo) {
122 return ptr->name;
123 }
124 ptr++;
125 }
126
127 // not found.
128 return "ssh-unknown";
129 }
130
131 ssh_keyalgo get_ssh2_keyalgo_from_name(const char *name)
132 {
133 const struct ssh2_host_key_t *ptr = ssh2_host_key;
134
135 while (ptr->name != NULL) {
136 if (strcmp(name, ptr->name) == 0) {
137 return ptr->algo;
138 }
139 ptr++;
140 }
141
142 // not found.
143 return KEY_ALGO_UNSPEC;
144 }
145
146 int get_ssh2_key_hashtype(ssh_keyalgo algo)
147 {
148 const struct ssh2_host_key_t *ptr = ssh2_host_key;
149
150 while (ptr->name != NULL) {
151 if (algo == ptr->algo) {
152 return ptr->digest_type;
153 }
154 ptr++;
155 }
156
157 // not found.
158 return NID_sha1;
159 }
160
161 ssh_keytype get_ssh2_keytype_from_keyalgo(ssh_keyalgo algo)
162 {
163 const struct ssh2_host_key_t *ptr = ssh2_host_key;
164
165 while (ptr->name != NULL) {
166 if (algo == ptr->algo) {
167 return ptr->type;
168 }
169 ptr++;
170 }
171
172 // not found.
173 return KEY_UNSPEC;
174 }
175
176 const char* get_ssh2_keytype_name_from_keyalgo(ssh_keyalgo algo)
177 {
178 return get_ssh2_hostkey_type_name(get_ssh2_keytype_from_keyalgo(algo));
179 }
180
181 char* get_digest_algorithm_name(digest_algorithm id)
182 {
183 const struct ssh_digest_t *ptr = ssh_digests;
184
185 while (ptr->name != NULL) {
186 if (id == ptr->id) {
187 return ptr->name;
188 }
189 ptr++;
190 }
191
192 // not found.
193 return "unknown";
194 }
195
196 void normalize_host_key_order(char *buf)
197 {
198 static char default_strings[] = {
199 KEY_ALGO_ECDSA256,
200 KEY_ALGO_ECDSA384,
201 KEY_ALGO_ECDSA521,
202 KEY_ALGO_ED25519,
203 KEY_ALGO_RSASHA256,
204 KEY_ALGO_RSASHA512,
205 KEY_ALGO_RSA,
206 KEY_ALGO_DSA,
207 KEY_ALGO_NONE,
208 };
209
210 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
211 }
212
213 ssh_keyalgo choose_SSH2_host_key_algorithm(char *server_proposal, char *my_proposal)
214 {
215 ssh_keytype type = KEY_UNSPEC;
216 char str_keytype[20];
217 const struct ssh2_host_key_t *ptr = ssh2_host_key;
218
219 choose_SSH2_proposal(server_proposal, my_proposal, str_keytype, sizeof(str_keytype));
220
221 return get_ssh2_keyalgo_from_name(str_keytype);
222 }
223
224 // Host Key�A���S���Y���D���������������Amyproposal[]�������������B
225 // (2011.2.28 yutaka)
226 void SSH2_update_host_key_myproposal(PTInstVar pvar)
227 {
228 static char buf[256]; // TODO: malloc()��������
229 int index;
230 int len, i;
231
232 // ���M�������������������������A�O�������B(2006.6.26 maya)
233 if (pvar->socket != INVALID_SOCKET) {
234 return;
235 }
236
237 buf[0] = '\0';
238 for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) {
239 index = pvar->settings.HostKeyOrder[i] - '0';
240 if (index == KEY_NONE) // disabled line
241 break;
242 strncat_s(buf, sizeof(buf), get_ssh2_keyalgo_name(index), _TRUNCATE);
243 strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
244 }
245 len = strlen(buf);
246 if (len > 0)
247 buf[len - 1] = '\0'; // get rid of comma
248 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf;
249 }
250
251 ssh_keyalgo choose_SSH2_keysign_algorithm(char *server_proposal, ssh_keytype keytype)
252 {
253 char buff[128];
254 const struct ssh2_host_key_t *ptr = ssh2_host_key;
255
256 if (keytype == KEY_RSA) {
257 if (server_proposal == NULL) {
258 logprintf(LOG_LEVEL_VERBOSE, "%s: no server_sig_algs, ssh-rsa is selected.", __FUNCTION__);
259 return KEY_ALGO_RSA;
260 }
261 else {
262 choose_SSH2_proposal(server_proposal, "rsa-sha2-512,rsa-sha2-256,ssh-rsa", buff, sizeof(buff));
263 if (strlen(buff) == 0) {
264 // not found.
265 logprintf(LOG_LEVEL_WARNING, "%s: no match sign algorithm.", __FUNCTION__);
266 return KEY_ALGO_UNSPEC;
267 }
268 else {
269 logprintf(LOG_LEVEL_VERBOSE, "%s: %s is selected.", __FUNCTION__, buff);
270 return get_ssh2_keyalgo_from_name(buff);
271 }
272 }
273 }
274 else {
275 while (ptr->type != KEY_UNSPEC && ptr->type != keytype) {
276 ptr++;
277 }
278
279 return ptr->algo;
280 }
281
282 // not reached
283 return KEY_ALGO_UNSPEC;
284 }

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