| 5276 |
} |
} |
| 5277 |
|
|
| 5278 |
|
|
| 5279 |
|
const char * |
| 5280 |
|
key_type(const Key *k) |
| 5281 |
|
{ |
| 5282 |
|
switch (k->type) { |
| 5283 |
|
case KEY_RSA1: |
| 5284 |
|
return "RSA1"; |
| 5285 |
|
case KEY_RSA: |
| 5286 |
|
return "RSA"; |
| 5287 |
|
case KEY_DSA: |
| 5288 |
|
return "DSA"; |
| 5289 |
|
} |
| 5290 |
|
return "unknown"; |
| 5291 |
|
} |
| 5292 |
|
|
| 5293 |
|
unsigned int |
| 5294 |
|
key_size(const Key *k) |
| 5295 |
|
{ |
| 5296 |
|
switch (k->type) { |
| 5297 |
|
case KEY_RSA1: |
| 5298 |
|
case KEY_RSA: |
| 5299 |
|
return BN_num_bits(k->rsa->n); |
| 5300 |
|
case KEY_DSA: |
| 5301 |
|
return BN_num_bits(k->dsa->p); |
| 5302 |
|
} |
| 5303 |
|
return 0; |
| 5304 |
|
} |
| 5305 |
|
|
| 5306 |
|
// based on OpenSSH 5.1 |
| 5307 |
|
#define FLDBASE 8 |
| 5308 |
|
#define FLDSIZE_Y (FLDBASE + 1) |
| 5309 |
|
#define FLDSIZE_X (FLDBASE * 2 + 1) |
| 5310 |
|
static char * |
| 5311 |
|
key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) |
| 5312 |
|
{ |
| 5313 |
|
/* |
| 5314 |
|
* Chars to be used after each other every time the worm |
| 5315 |
|
* intersects with itself. Matter of taste. |
| 5316 |
|
*/ |
| 5317 |
|
char *augmentation_string = " .o+=*BOX@%&#/^SE"; |
| 5318 |
|
char *retval, *p; |
| 5319 |
|
unsigned char field[FLDSIZE_X][FLDSIZE_Y]; |
| 5320 |
|
unsigned int i, b; |
| 5321 |
|
int x, y; |
| 5322 |
|
size_t len = strlen(augmentation_string) - 1; |
| 5323 |
|
|
| 5324 |
|
retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2)); |
| 5325 |
|
|
| 5326 |
|
/* initialize field */ |
| 5327 |
|
memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); |
| 5328 |
|
x = FLDSIZE_X / 2; |
| 5329 |
|
y = FLDSIZE_Y / 2; |
| 5330 |
|
|
| 5331 |
|
/* process raw key */ |
| 5332 |
|
for (i = 0; i < dgst_raw_len; i++) { |
| 5333 |
|
int input; |
| 5334 |
|
/* each byte conveys four 2-bit move commands */ |
| 5335 |
|
input = dgst_raw[i]; |
| 5336 |
|
for (b = 0; b < 4; b++) { |
| 5337 |
|
/* evaluate 2 bit, rest is shifted later */ |
| 5338 |
|
x += (input & 0x1) ? 1 : -1; |
| 5339 |
|
y += (input & 0x2) ? 1 : -1; |
| 5340 |
|
|
| 5341 |
|
/* assure we are still in bounds */ |
| 5342 |
|
x = max(x, 0); |
| 5343 |
|
y = max(y, 0); |
| 5344 |
|
x = min(x, FLDSIZE_X - 1); |
| 5345 |
|
y = min(y, FLDSIZE_Y - 1); |
| 5346 |
|
|
| 5347 |
|
/* augment the field */ |
| 5348 |
|
field[x][y]++; |
| 5349 |
|
input = input >> 2; |
| 5350 |
|
} |
| 5351 |
|
} |
| 5352 |
|
|
| 5353 |
|
/* mark starting point and end point*/ |
| 5354 |
|
field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; |
| 5355 |
|
field[x][y] = len; |
| 5356 |
|
|
| 5357 |
|
/* fill in retval */ |
| 5358 |
|
_snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", key_type(k), key_size(k)); |
| 5359 |
|
p = strchr(retval, '\0'); |
| 5360 |
|
|
| 5361 |
|
/* output upper border */ |
| 5362 |
|
for (i = p - retval - 1; i < FLDSIZE_X; i++) |
| 5363 |
|
*p++ = '-'; |
| 5364 |
|
*p++ = '+'; |
| 5365 |
|
*p++ = '\r'; |
| 5366 |
|
*p++ = '\n'; |
| 5367 |
|
|
| 5368 |
|
/* output content */ |
| 5369 |
|
for (y = 0; y < FLDSIZE_Y; y++) { |
| 5370 |
|
*p++ = '|'; |
| 5371 |
|
for (x = 0; x < FLDSIZE_X; x++) |
| 5372 |
|
*p++ = augmentation_string[min(field[x][y], len)]; |
| 5373 |
|
*p++ = '|'; |
| 5374 |
|
*p++ = '\r'; |
| 5375 |
|
*p++ = '\n'; |
| 5376 |
|
} |
| 5377 |
|
|
| 5378 |
|
/* output lower border */ |
| 5379 |
|
*p++ = '+'; |
| 5380 |
|
for (i = 0; i < FLDSIZE_X; i++) |
| 5381 |
|
*p++ = '-'; |
| 5382 |
|
*p++ = '+'; |
| 5383 |
|
|
| 5384 |
|
return retval; |
| 5385 |
|
} |
| 5386 |
|
#undef FLDBASE |
| 5387 |
|
#undef FLDSIZE_Y |
| 5388 |
|
#undef FLDSIZE_X |
| 5389 |
|
|
| 5390 |
// |
// |
| 5391 |
// fingerprint(指紋:ホスト公開鍵のハッシュ)を生成する |
// fingerprint(指紋:ホスト公開鍵のハッシュ)を生成する |
| 5392 |
// |
// |
| 5393 |
char *key_fingerprint(Key *key) |
char *key_fingerprint(Key *key, enum fp_rep dgst_rep) |
| 5394 |
{ |
{ |
| 5395 |
char *retval = NULL; |
char *retval = NULL; |
| 5396 |
unsigned char *dgst_raw; |
unsigned char *dgst_raw; |
| 5400 |
// fingerprintのハッシュ値(バイナリ)を求める |
// fingerprintのハッシュ値(バイナリ)を求める |
| 5401 |
dgst_raw = key_fingerprint_raw(key, &dgst_raw_len); |
dgst_raw = key_fingerprint_raw(key, &dgst_raw_len); |
| 5402 |
|
|
| 5403 |
// 16進表記へ変換する |
if (dgst_rep == SSH_FP_HEX) { |
| 5404 |
retval_len = dgst_raw_len * 3 + 1; |
// 16進表記へ変換する |
| 5405 |
retval = malloc(retval_len); |
retval_len = dgst_raw_len * 3 + 1; |
| 5406 |
retval[0] = '\0'; |
retval = malloc(retval_len); |
| 5407 |
for (i = 0; i < dgst_raw_len; i++) { |
retval[0] = '\0'; |
| 5408 |
char hex[4]; |
for (i = 0; i < dgst_raw_len; i++) { |
| 5409 |
_snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]); |
char hex[4]; |
| 5410 |
strncat_s(retval, retval_len, hex, _TRUNCATE); |
_snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]); |
| 5411 |
} |
strncat_s(retval, retval_len, hex, _TRUNCATE); |
| 5412 |
|
} |
| 5413 |
|
|
| 5414 |
|
/* Remove the trailing ':' character */ |
| 5415 |
|
retval[(dgst_raw_len * 3) - 1] = '\0'; |
| 5416 |
|
|
| 5417 |
/* Remove the trailing ':' character */ |
} else if (dgst_rep == SSH_FP_RANDOMART) { |
| 5418 |
retval[(dgst_raw_len * 3) - 1] = '\0'; |
retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key); |
| 5419 |
|
|
| 5420 |
|
} else { |
| 5421 |
|
|
| 5422 |
|
} |
| 5423 |
|
|
| 5424 |
memset(dgst_raw, 0, dgst_raw_len); |
memset(dgst_raw, 0, dgst_raw_len); |
| 5425 |
free(dgst_raw); |
free(dgst_raw); |