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 10949 - (show annotations) (download) (as text)
Fri Sep 29 08:35:23 2023 UTC (6 months, 1 week ago) by nmaya
File MIME type: text/x-csrc
File size: 9934 byte(s)
最初の KEX のときには "ext-info-c" を送信するが、Rekey のときには送信しないようにした

ticket: #36111
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 ssh_agentflag signflag;
39 char *name;
40 };
41
42 static const struct ssh2_host_key_t ssh2_host_key[] = {
43 {KEY_ALGO_RSA1, KEY_RSA1, NID_sha1, SSH_AGENT_SIGN_DEFAULT, "ssh-rsa1"}, // for SSH1 only
44 {KEY_ALGO_RSA, KEY_RSA, NID_sha1, SSH_AGENT_SIGN_DEFAULT, "ssh-rsa"}, // RFC4253
45 {KEY_ALGO_DSA, KEY_DSA, NID_sha1, SSH_AGENT_SIGN_DEFAULT, "ssh-dss"}, // RFC4253
46 {KEY_ALGO_ECDSA256, KEY_ECDSA256, NID_sha256, SSH_AGENT_SIGN_DEFAULT, "ecdsa-sha2-nistp256"}, // RFC5656
47 {KEY_ALGO_ECDSA384, KEY_ECDSA384, NID_sha384, SSH_AGENT_SIGN_DEFAULT, "ecdsa-sha2-nistp384"}, // RFC5656
48 {KEY_ALGO_ECDSA521, KEY_ECDSA521, NID_sha512, SSH_AGENT_SIGN_DEFAULT, "ecdsa-sha2-nistp521"}, // RFC5656
49 {KEY_ALGO_ED25519, KEY_ED25519, NID_sha512, SSH_AGENT_SIGN_DEFAULT, "ssh-ed25519"}, // RDC8709
50 {KEY_ALGO_RSASHA256,KEY_RSA, NID_sha256, SSH_AGENT_RSA_SHA2_256, "rsa-sha2-256"}, // RFC8332
51 {KEY_ALGO_RSASHA512,KEY_RSA, NID_sha512, SSH_AGENT_RSA_SHA2_512, "rsa-sha2-512"}, // RFC8332
52 {KEY_ALGO_UNSPEC, KEY_UNSPEC, NID_undef, SSH_AGENT_SIGN_DEFAULT, "ssh-unknown"},
53 {KEY_ALGO_NONE, KEY_NONE, NID_undef, SSH_AGENT_SIGN_DEFAULT, NULL},
54 };
55
56 struct ssh_digest_t {
57 digest_algorithm id;
58 char *name;
59 };
60
61 /* NB. Indexed directly by algorithm number */
62 static const struct ssh_digest_t ssh_digests[] = {
63 { SSH_DIGEST_MD5, "MD5" },
64 { SSH_DIGEST_RIPEMD160, "RIPEMD160" },
65 { SSH_DIGEST_SHA1, "SHA1" },
66 { SSH_DIGEST_SHA256, "SHA256" },
67 { SSH_DIGEST_SHA384, "SHA384" },
68 { SSH_DIGEST_SHA512, "SHA512" },
69 { SSH_DIGEST_MAX, NULL },
70 };
71
72
73 ssh_keytype get_hostkey_type_from_name(char *name)
74 {
75 if (strcmp(name, "rsa1") == 0) {
76 return KEY_RSA1;
77 } else if (strcmp(name, "rsa") == 0) {
78 return KEY_RSA;
79 } else if (strcmp(name, "dsa") == 0) {
80 return KEY_DSA;
81 } else if (strcmp(name, "ssh-rsa") == 0) {
82 return KEY_RSA;
83 } else if (strcmp(name, "ssh-dss") == 0) {
84 return KEY_DSA;
85 } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
86 return KEY_ECDSA256;
87 } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
88 return KEY_ECDSA384;
89 } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
90 return KEY_ECDSA521;
91 } else if (strcmp(name, "ssh-ed25519") == 0) {
92 return KEY_ED25519;
93 }
94 return KEY_UNSPEC;
95 }
96
97 char* get_ssh2_hostkey_type_name(ssh_keytype type)
98 {
99 const struct ssh2_host_key_t *ptr = ssh2_host_key;
100
101 while (ptr->name != NULL) {
102 if (type == ptr->type) {
103 return ptr->name;
104 }
105 ptr++;
106 }
107
108 // not found.
109 return "ssh-unknown";
110 }
111
112 char *get_ssh2_hostkey_type_name_from_key(Key *key)
113 {
114 return get_ssh2_hostkey_type_name(key->type);
115 }
116
117 char* get_ssh2_hostkey_algorithm_name(ssh_keyalgo algo)
118 {
119 const struct ssh2_host_key_t *ptr = ssh2_host_key;
120
121 while (ptr->name != NULL) {
122 if (algo == ptr->algo) {
123 return ptr->name;
124 }
125 ptr++;
126 }
127
128 // not found.
129 return "ssh-unknown";
130 }
131
132 ssh_keyalgo get_ssh2_hostkey_algorithm_from_name(const char *name)
133 {
134 const struct ssh2_host_key_t *ptr = ssh2_host_key;
135
136 while (ptr->name != NULL) {
137 if (strcmp(name, ptr->name) == 0) {
138 return ptr->algo;
139 }
140 ptr++;
141 }
142
143 // not found.
144 return KEY_ALGO_UNSPEC;
145 }
146
147 int get_ssh2_key_hashtype(ssh_keyalgo algo)
148 {
149 const struct ssh2_host_key_t *ptr = ssh2_host_key;
150
151 while (ptr->name != NULL) {
152 if (algo == ptr->algo) {
153 return ptr->digest_type;
154 }
155 ptr++;
156 }
157
158 // not found.
159 return NID_sha1;
160 }
161
162 int get_ssh2_agent_flag(ssh_keyalgo algo)
163 {
164 const struct ssh2_host_key_t *ptr = ssh2_host_key;
165
166 while (ptr->name != NULL) {
167 if (algo == ptr->algo) {
168 return ptr->signflag;
169 }
170 ptr++;
171 }
172
173 // not found.
174 return SSH_AGENT_SIGN_DEFAULT;
175 }
176
177 ssh_keytype get_ssh2_hostkey_type_from_algorithm(ssh_keyalgo algo)
178 {
179 const struct ssh2_host_key_t *ptr = ssh2_host_key;
180
181 while (ptr->name != NULL) {
182 if (algo == ptr->algo) {
183 return ptr->type;
184 }
185 ptr++;
186 }
187
188 // not found.
189 return KEY_UNSPEC;
190 }
191
192 const char* get_ssh2_hostkey_type_name_from_algorithm(ssh_keyalgo algo)
193 {
194 return get_ssh2_hostkey_type_name(get_ssh2_hostkey_type_from_algorithm(algo));
195 }
196
197 char* get_digest_algorithm_name(digest_algorithm id)
198 {
199 const struct ssh_digest_t *ptr = ssh_digests;
200
201 while (ptr->name != NULL) {
202 if (id == ptr->id) {
203 return ptr->name;
204 }
205 ptr++;
206 }
207
208 // not found.
209 return "unknown";
210 }
211
212 void normalize_host_key_order(char *buf)
213 {
214 static char default_strings[] = {
215 KEY_ALGO_ECDSA256,
216 KEY_ALGO_ECDSA384,
217 KEY_ALGO_ECDSA521,
218 KEY_ALGO_ED25519,
219 KEY_ALGO_RSASHA256,
220 KEY_ALGO_RSASHA512,
221 KEY_ALGO_RSA,
222 KEY_ALGO_DSA,
223 KEY_ALGO_NONE,
224 };
225
226 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
227 }
228
229 ssh_keyalgo choose_SSH2_host_key_algorithm(char *server_proposal, char *my_proposal)
230 {
231 ssh_keytype type = KEY_UNSPEC;
232 char str_keytype[20];
233 const struct ssh2_host_key_t *ptr = ssh2_host_key;
234
235 choose_SSH2_proposal(server_proposal, my_proposal, str_keytype, sizeof(str_keytype));
236
237 return get_ssh2_hostkey_algorithm_from_name(str_keytype);
238 }
239
240 // Host Key�A���S���Y���D���������������Amyproposal[]�������������B
241 // (2011.2.28 yutaka)
242 void SSH2_update_host_key_myproposal(PTInstVar pvar)
243 {
244 static char buf[256]; // TODO: malloc()��������
245 int index;
246 int len, i;
247
248 // ���M�������������������������L�[������
249 // �L�[������������������������
250 if (pvar->socket != INVALID_SOCKET) {
251 return;
252 }
253
254 buf[0] = '\0';
255 for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) {
256 index = pvar->settings.HostKeyOrder[i] - '0';
257 if (index == KEY_NONE) // disabled line
258 break;
259 strncat_s(buf, sizeof(buf), get_ssh2_hostkey_algorithm_name(index), _TRUNCATE);
260 strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
261 }
262 len = strlen(buf);
263 if (len > 0)
264 buf[len - 1] = '\0'; // get rid of comma
265 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf;
266 }
267
268 static void SSH2_rsa_pubkey_sign_algo_myproposal(PTInstVar pvar, char *buf, int buf_len)
269 {
270 int algo;
271 int len, i;
272 char *c_str;
273
274 // �����������D�������������� buf ��������
275 buf[0] = '\0';
276 for (i = 0 ; pvar->settings.RSAPubkeySignAlgorithmOrder[i] != 0 ; i++) {
277 algo = pvar->settings.RSAPubkeySignAlgorithmOrder[i] - '0';
278 if (algo == 0) // disabled line
279 break;
280 switch (algo) {
281 case RSA_PUBKEY_SIGN_ALGO_RSA:
282 c_str = "ssh-rsa,";
283 break;
284 case RSA_PUBKEY_SIGN_ALGO_RSASHA256:
285 c_str = "rsa-sha2-256,";
286 break;
287 case RSA_PUBKEY_SIGN_ALGO_RSASHA512:
288 c_str = "rsa-sha2-512,";
289 break;
290 default:
291 continue;
292 }
293 strncat_s(buf, buf_len, c_str, _TRUNCATE);
294 }
295 len = strlen(buf);
296 if (len > 0)
297 buf[len - 1] = '\0'; // get rid of comma
298 }
299
300 ssh_keyalgo choose_SSH2_keysign_algorithm(PTInstVar pvar, ssh_keytype keytype)
301 {
302 char buff[128];
303 const struct ssh2_host_key_t *ptr = ssh2_host_key;
304 char *server_proposal = pvar->server_sig_algs;
305
306 if (keytype == KEY_RSA) {
307 if (server_proposal == NULL) {
308 logprintf(LOG_LEVEL_VERBOSE, "%s: no server_sig_algs, ssh-rsa is selected.", __FUNCTION__);
309 return KEY_ALGO_RSA;
310 }
311 else {
312 char rsa_myproposal[128];
313 SSH2_rsa_pubkey_sign_algo_myproposal(pvar, rsa_myproposal, sizeof(rsa_myproposal));
314 choose_SSH2_proposal(server_proposal, rsa_myproposal, buff, sizeof(buff));
315 if (strlen(buff) == 0) {
316 // not found.
317 logprintf(LOG_LEVEL_WARNING, "%s: no match sign algorithm.", __FUNCTION__);
318 return KEY_ALGO_UNSPEC;
319 }
320 else {
321 logprintf(LOG_LEVEL_VERBOSE, "%s: %s is selected.", __FUNCTION__, buff);
322 return get_ssh2_hostkey_algorithm_from_name(buff);
323 }
324 }
325 }
326 else {
327 while (ptr->type != KEY_UNSPEC && ptr->type != keytype) {
328 ptr++;
329 }
330
331 return ptr->algo;
332 }
333
334 // not reached
335 return KEY_ALGO_UNSPEC;
336 }
337
338 void normalize_rsa_pubkey_sign_algo_order(char *buf)
339 {
340 static char default_strings[] = {
341 RSA_PUBKEY_SIGN_ALGO_RSASHA512,
342 RSA_PUBKEY_SIGN_ALGO_RSASHA256,
343 RSA_PUBKEY_SIGN_ALGO_RSA,
344 RSA_PUBKEY_SIGN_ALGO_NONE,
345 };
346
347 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
348 }
349
350 /*
351 * ssh_keyalgo �����A�����������W�����������_�C�W�F�X�g������������
352 * ���������� rsa-sha2-256, rsa-sha2-512 ���������� "SHA-256", "SHA-512" ������
353 * About �_�C�A���O���A���W�����_�C�W�F�X�g���������������\����������
354 */
355 char* get_ssh2_hostkey_algorithm_digest_name(ssh_keyalgo algo)
356 {
357 switch (algo) {
358 case KEY_ALGO_RSASHA256:
359 return "SHA-256";
360 case KEY_ALGO_RSASHA512:
361 return "SHA-512";
362 }
363 return "";
364 }

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