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 10509 - (show annotations) (download) (as text)
Tue Jan 17 23:13:14 2023 UTC (14 months, 3 weeks ago) by nmaya
File MIME type: text/x-csrc
File size: 9918 byte(s)
rsa-sha2-256/512 対応

ticket: #36109
merge from 4-stable:
  RSA 鍵を用いた公開鍵認証の署名アルゴリズムの優先度の設定: r10384, r10386, r10416, r10465
  About ダイアログ: r10387
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�������������������������A�O�������B(2006.6.26 maya)
249 if (pvar->socket != INVALID_SOCKET) {
250 return;
251 }
252
253 buf[0] = '\0';
254 for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) {
255 index = pvar->settings.HostKeyOrder[i] - '0';
256 if (index == KEY_NONE) // disabled line
257 break;
258 strncat_s(buf, sizeof(buf), get_ssh2_hostkey_algorithm_name(index), _TRUNCATE);
259 strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
260 }
261 len = strlen(buf);
262 if (len > 0)
263 buf[len - 1] = '\0'; // get rid of comma
264 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf;
265 }
266
267 static void SSH2_rsa_pubkey_sign_algo_myproposal(PTInstVar pvar, char *buf, int buf_len)
268 {
269 int algo;
270 int len, i;
271 char *c_str;
272
273 // �����������D�������������� buf ��������
274 buf[0] = '\0';
275 for (i = 0 ; pvar->settings.RSAPubkeySignAlgorithmOrder[i] != 0 ; i++) {
276 algo = pvar->settings.RSAPubkeySignAlgorithmOrder[i] - '0';
277 if (algo == 0) // disabled line
278 break;
279 switch (algo) {
280 case RSA_PUBKEY_SIGN_ALGO_RSA:
281 c_str = "ssh-rsa,";
282 break;
283 case RSA_PUBKEY_SIGN_ALGO_RSASHA256:
284 c_str = "rsa-sha2-256,";
285 break;
286 case RSA_PUBKEY_SIGN_ALGO_RSASHA512:
287 c_str = "rsa-sha2-512,";
288 break;
289 default:
290 continue;
291 }
292 strncat_s(buf, buf_len, c_str, _TRUNCATE);
293 }
294 len = strlen(buf);
295 if (len > 0)
296 buf[len - 1] = '\0'; // get rid of comma
297 }
298
299 ssh_keyalgo choose_SSH2_keysign_algorithm(PTInstVar pvar, ssh_keytype keytype)
300 {
301 char buff[128];
302 const struct ssh2_host_key_t *ptr = ssh2_host_key;
303 char *server_proposal = pvar->server_sig_algs;
304
305 if (keytype == KEY_RSA) {
306 if (server_proposal == NULL) {
307 logprintf(LOG_LEVEL_VERBOSE, "%s: no server_sig_algs, ssh-rsa is selected.", __FUNCTION__);
308 return KEY_ALGO_RSA;
309 }
310 else {
311 char rsa_myproposal[128];
312 SSH2_rsa_pubkey_sign_algo_myproposal(pvar, rsa_myproposal, sizeof(rsa_myproposal));
313 choose_SSH2_proposal(server_proposal, rsa_myproposal, buff, sizeof(buff));
314 if (strlen(buff) == 0) {
315 // not found.
316 logprintf(LOG_LEVEL_WARNING, "%s: no match sign algorithm.", __FUNCTION__);
317 return KEY_ALGO_UNSPEC;
318 }
319 else {
320 logprintf(LOG_LEVEL_VERBOSE, "%s: %s is selected.", __FUNCTION__, buff);
321 return get_ssh2_hostkey_algorithm_from_name(buff);
322 }
323 }
324 }
325 else {
326 while (ptr->type != KEY_UNSPEC && ptr->type != keytype) {
327 ptr++;
328 }
329
330 return ptr->algo;
331 }
332
333 // not reached
334 return KEY_ALGO_UNSPEC;
335 }
336
337 void normalize_rsa_pubkey_sign_algo_order(char *buf)
338 {
339 static char default_strings[] = {
340 RSA_PUBKEY_SIGN_ALGO_RSASHA512,
341 RSA_PUBKEY_SIGN_ALGO_RSASHA256,
342 RSA_PUBKEY_SIGN_ALGO_RSA,
343 RSA_PUBKEY_SIGN_ALGO_NONE,
344 };
345
346 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
347 }
348
349 /*
350 * ssh_keyalgo �����A�����������W�����������_�C�W�F�X�g������������
351 * ���������� rsa-sha2-256, rsa-sha2-512 ���������� "SHA-256", "SHA-512" ������
352 * About �_�C�A���O���A���W�����_�C�W�F�X�g���������������\����������
353 */
354 char* get_ssh2_hostkey_algorithm_digest_name(ssh_keyalgo algo)
355 {
356 switch (algo) {
357 case KEY_ALGO_RSASHA256:
358 return "SHA-256";
359 case KEY_ALGO_RSASHA512:
360 return "SHA-512";
361 }
362 return "";
363 }

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