| 351 |
return ret; |
return ret; |
| 352 |
} |
} |
| 353 |
|
|
| 354 |
|
static int ssh_ed25519_verify(Key *key, unsigned char *signature, unsigned int signaturelen, |
| 355 |
|
unsigned char *data, unsigned int datalen) |
| 356 |
|
{ |
| 357 |
|
buffer_t *b; |
| 358 |
|
char *ktype = NULL; |
| 359 |
|
unsigned char *sigblob = NULL, *sm = NULL, *m = NULL; |
| 360 |
|
unsigned int len; |
| 361 |
|
unsigned long long smlen, mlen; |
| 362 |
|
int rlen, ret; |
| 363 |
|
char *bptr; |
| 364 |
|
|
| 365 |
|
ret = -1; |
| 366 |
|
b = buffer_init(); |
| 367 |
|
if (b == NULL) |
| 368 |
|
goto error; |
| 369 |
|
|
| 370 |
|
buffer_append(b, signature, signaturelen); |
| 371 |
|
bptr = buffer_ptr(b); |
| 372 |
|
ktype = buffer_get_string(&bptr, NULL); |
| 373 |
|
if (strcmp("ssh-ed25519", ktype) != 0) { |
| 374 |
|
goto error; |
| 375 |
|
} |
| 376 |
|
sigblob = buffer_get_string(&bptr, &len); |
| 377 |
|
rlen = buffer_remain_len(b); |
| 378 |
|
if (rlen != 0) { |
| 379 |
|
goto error; |
| 380 |
|
} |
| 381 |
|
if (len > crypto_sign_ed25519_BYTES) { |
| 382 |
|
goto error; |
| 383 |
|
} |
| 384 |
|
|
| 385 |
|
smlen = len + datalen; |
| 386 |
|
sm = malloc((size_t)smlen); |
| 387 |
|
memcpy(sm, sigblob, len); |
| 388 |
|
memcpy(sm+len, data, datalen); |
| 389 |
|
mlen = smlen; |
| 390 |
|
m = malloc((size_t)mlen); |
| 391 |
|
|
| 392 |
|
if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen, |
| 393 |
|
key->ed25519_pk)) != 0) { |
| 394 |
|
//debug2("%s: crypto_sign_ed25519_open failed: %d", |
| 395 |
|
// __func__, ret); |
| 396 |
|
} |
| 397 |
|
if (ret == 0 && mlen != datalen) { |
| 398 |
|
//debug2("%s: crypto_sign_ed25519_open " |
| 399 |
|
// "mlen != datalen (%llu != %u)", __func__, mlen, datalen); |
| 400 |
|
ret = -1; |
| 401 |
|
} |
| 402 |
|
/* XXX compare 'm' and 'data' ? */ |
| 403 |
|
|
| 404 |
|
error: |
| 405 |
|
buffer_free(b); |
| 406 |
|
free(ktype); |
| 407 |
|
|
| 408 |
|
if (sigblob) { |
| 409 |
|
memset(sigblob, 's', len); |
| 410 |
|
free(sigblob); |
| 411 |
|
} |
| 412 |
|
if (sm) { |
| 413 |
|
memset(sm, 'S', (size_t)smlen); |
| 414 |
|
free(sm); |
| 415 |
|
} |
| 416 |
|
if (m) { |
| 417 |
|
memset(m, 'm', (size_t)smlen); /* NB. mlen may be invalid if ret != 0 */ |
| 418 |
|
free(m); |
| 419 |
|
} |
| 420 |
|
|
| 421 |
|
/* translate return code carefully */ |
| 422 |
|
return (ret == 0) ? 1 : -1; |
| 423 |
|
} |
| 424 |
|
|
| 425 |
int key_verify(Key *key, |
int key_verify(Key *key, |
| 426 |
unsigned char *signature, unsigned int signaturelen, |
unsigned char *signature, unsigned int signaturelen, |
| 427 |
unsigned char *data, unsigned int datalen) |
unsigned char *data, unsigned int datalen) |
| 440 |
case KEY_ECDSA521: |
case KEY_ECDSA521: |
| 441 |
ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen); |
ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen); |
| 442 |
break; |
break; |
| 443 |
|
case KEY_ED25519: |
| 444 |
|
ret = ssh_ed25519_verify(key, signature, signaturelen, data, datalen); |
| 445 |
|
break; |
| 446 |
default: |
default: |
| 447 |
return -1; |
return -1; |
| 448 |
} |
} |
| 508 |
return (dsa); |
return (dsa); |
| 509 |
} |
} |
| 510 |
|
|
| 511 |
|
unsigned char *duplicate_ED25519_PK(unsigned char *src) |
| 512 |
|
{ |
| 513 |
|
unsigned char *ptr = NULL; |
| 514 |
|
|
| 515 |
|
ptr = malloc(ED25519_PK_SZ); |
| 516 |
|
if (ptr) { |
| 517 |
|
memcpy(ptr, src, ED25519_PK_SZ); |
| 518 |
|
} |
| 519 |
|
return (ptr); |
| 520 |
|
} |
| 521 |
|
|
| 522 |
|
|
| 523 |
char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length) |
char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length) |
| 524 |
{ |
{ |
| 566 |
case KEY_ECDSA256: |
case KEY_ECDSA256: |
| 567 |
case KEY_ECDSA384: |
case KEY_ECDSA384: |
| 568 |
case KEY_ECDSA521: |
case KEY_ECDSA521: |
| 569 |
|
case KEY_ED25519: |
| 570 |
key_to_blob(k, &blob, &len); |
key_to_blob(k, &blob, &len); |
| 571 |
break; |
break; |
| 572 |
|
|
| 610 |
case KEY_ECDSA384: |
case KEY_ECDSA384: |
| 611 |
case KEY_ECDSA521: |
case KEY_ECDSA521: |
| 612 |
return "ECDSA"; |
return "ECDSA"; |
| 613 |
|
case KEY_ED25519: |
| 614 |
|
return "ED25519"; |
| 615 |
} |
} |
| 616 |
return "unknown"; |
return "unknown"; |
| 617 |
} |
} |
| 633 |
return 384; |
return 384; |
| 634 |
case KEY_ECDSA521: |
case KEY_ECDSA521: |
| 635 |
return 521; |
return 521; |
| 636 |
|
case KEY_ED25519: |
| 637 |
|
return 256; /* XXX */ |
| 638 |
} |
} |
| 639 |
return 0; |
return 0; |
| 640 |
} |
} |
| 763 |
return (retval); |
return (retval); |
| 764 |
} |
} |
| 765 |
|
|
| 766 |
|
// |
| 767 |
|
// キーのメモリ領域確保 |
| 768 |
|
// |
| 769 |
|
static void key_add_private(Key *k) |
| 770 |
|
{ |
| 771 |
|
switch (k->type) { |
| 772 |
|
case KEY_RSA1: |
| 773 |
|
case KEY_RSA: |
| 774 |
|
k->rsa->d = BN_new(); |
| 775 |
|
k->rsa->iqmp = BN_new(); |
| 776 |
|
k->rsa->q = BN_new(); |
| 777 |
|
k->rsa->p = BN_new(); |
| 778 |
|
k->rsa->dmq1 = BN_new(); |
| 779 |
|
k->rsa->dmp1 = BN_new(); |
| 780 |
|
if (k->rsa->d == NULL || k->rsa->iqmp == NULL || k->rsa->q == NULL || |
| 781 |
|
k->rsa->p == NULL || k->rsa->dmq1 == NULL || k->rsa->dmp1 == NULL) |
| 782 |
|
goto error; |
| 783 |
|
break; |
| 784 |
|
|
| 785 |
|
case KEY_DSA: |
| 786 |
|
k->dsa->priv_key = BN_new(); |
| 787 |
|
if (k->dsa->priv_key == NULL) |
| 788 |
|
goto error; |
| 789 |
|
break; |
| 790 |
|
|
| 791 |
|
case KEY_ECDSA256: |
| 792 |
|
case KEY_ECDSA384: |
| 793 |
|
case KEY_ECDSA521: |
| 794 |
|
/* Cannot do anything until we know the group */ |
| 795 |
|
break; |
| 796 |
|
|
| 797 |
|
case KEY_ED25519: |
| 798 |
|
/* no need to prealloc */ |
| 799 |
|
break; |
| 800 |
|
|
| 801 |
|
case KEY_UNSPEC: |
| 802 |
|
break; |
| 803 |
|
|
| 804 |
|
default: |
| 805 |
|
goto error; |
| 806 |
|
break; |
| 807 |
|
} |
| 808 |
|
return; |
| 809 |
|
|
| 810 |
|
error: |
| 811 |
|
if (k->rsa->d) { |
| 812 |
|
BN_free(k->rsa->d); |
| 813 |
|
k->rsa->d = NULL; |
| 814 |
|
} |
| 815 |
|
if (k->rsa->iqmp) { |
| 816 |
|
BN_free(k->rsa->iqmp); |
| 817 |
|
k->rsa->iqmp = NULL; |
| 818 |
|
} |
| 819 |
|
if (k->rsa->q) { |
| 820 |
|
BN_free(k->rsa->q); |
| 821 |
|
k->rsa->q = NULL; |
| 822 |
|
} |
| 823 |
|
if (k->rsa->p) { |
| 824 |
|
BN_free(k->rsa->p); |
| 825 |
|
k->rsa->p = NULL; |
| 826 |
|
} |
| 827 |
|
if (k->rsa->dmq1) { |
| 828 |
|
BN_free(k->rsa->dmq1); |
| 829 |
|
k->rsa->dmq1 = NULL; |
| 830 |
|
} |
| 831 |
|
if (k->rsa->dmp1) { |
| 832 |
|
BN_free(k->rsa->dmp1); |
| 833 |
|
k->rsa->dmp1 = NULL; |
| 834 |
|
} |
| 835 |
|
|
| 836 |
|
|
| 837 |
|
if (k->dsa->priv_key == NULL) { |
| 838 |
|
BN_free(k->dsa->priv_key); |
| 839 |
|
k->dsa->priv_key = NULL; |
| 840 |
|
} |
| 841 |
|
|
| 842 |
|
} |
| 843 |
|
|
| 844 |
|
Key *key_new_private(int type) |
| 845 |
|
{ |
| 846 |
|
Key *k = key_new(type); |
| 847 |
|
|
| 848 |
|
key_add_private(k); |
| 849 |
|
return (k); |
| 850 |
|
} |
| 851 |
|
|
| 852 |
|
|
| 853 |
|
Key *key_new(int type) |
| 854 |
|
{ |
| 855 |
|
int success = 0; |
| 856 |
|
Key *k = NULL; |
| 857 |
|
RSA *rsa; |
| 858 |
|
DSA *dsa; |
| 859 |
|
|
| 860 |
|
k = calloc(1, sizeof(Key)); |
| 861 |
|
if (k == NULL) |
| 862 |
|
goto error; |
| 863 |
|
k->type = type; |
| 864 |
|
k->ecdsa = NULL; |
| 865 |
|
k->dsa = NULL; |
| 866 |
|
k->rsa = NULL; |
| 867 |
|
k->ed25519_pk = NULL; |
| 868 |
|
k->ed25519_sk = NULL; |
| 869 |
|
|
| 870 |
|
switch (k->type) { |
| 871 |
|
case KEY_RSA1: |
| 872 |
|
case KEY_RSA: |
| 873 |
|
rsa = RSA_new(); |
| 874 |
|
if (rsa == NULL) |
| 875 |
|
goto error; |
| 876 |
|
rsa->n = BN_new(); |
| 877 |
|
rsa->e = BN_new(); |
| 878 |
|
if (rsa->n == NULL || rsa->e == NULL) |
| 879 |
|
goto error; |
| 880 |
|
k->rsa = rsa; |
| 881 |
|
break; |
| 882 |
|
|
| 883 |
|
case KEY_DSA: |
| 884 |
|
dsa = DSA_new(); |
| 885 |
|
if (dsa == NULL) |
| 886 |
|
goto error; |
| 887 |
|
dsa->p = BN_new(); |
| 888 |
|
dsa->q = BN_new(); |
| 889 |
|
dsa->g = BN_new(); |
| 890 |
|
dsa->pub_key = BN_new(); |
| 891 |
|
if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) |
| 892 |
|
goto error; |
| 893 |
|
k->dsa = dsa; |
| 894 |
|
break; |
| 895 |
|
|
| 896 |
|
case KEY_ECDSA256: |
| 897 |
|
case KEY_ECDSA384: |
| 898 |
|
case KEY_ECDSA521: |
| 899 |
|
/* Cannot do anything until we know the group */ |
| 900 |
|
break; |
| 901 |
|
|
| 902 |
|
case KEY_ED25519: |
| 903 |
|
/* no need to prealloc */ |
| 904 |
|
break; |
| 905 |
|
|
| 906 |
|
case KEY_UNSPEC: |
| 907 |
|
break; |
| 908 |
|
|
| 909 |
|
default: |
| 910 |
|
goto error; |
| 911 |
|
break; |
| 912 |
|
} |
| 913 |
|
success = 1; |
| 914 |
|
|
| 915 |
|
error: |
| 916 |
|
if (success == 0) { |
| 917 |
|
key_free(k); |
| 918 |
|
k = NULL; |
| 919 |
|
} |
| 920 |
|
return (k); |
| 921 |
|
} |
| 922 |
|
|
| 923 |
|
|
| 924 |
// |
// |
| 925 |
// キーのメモリ領域解放 |
// キーのメモリ領域解放 |
| 951 |
EC_KEY_free(key->ecdsa); |
EC_KEY_free(key->ecdsa); |
| 952 |
key->ecdsa = NULL; |
key->ecdsa = NULL; |
| 953 |
break; |
break; |
| 954 |
|
|
| 955 |
|
case KEY_ED25519: |
| 956 |
|
if (key->ed25519_pk) { |
| 957 |
|
memset(key->ed25519_pk, 0, ED25519_PK_SZ); |
| 958 |
|
free(key->ed25519_pk); |
| 959 |
|
key->ed25519_pk = NULL; |
| 960 |
|
} |
| 961 |
|
if (key->ed25519_sk) { |
| 962 |
|
memset(key->ed25519_sk, 0, ED25519_SK_SZ); |
| 963 |
|
free(key->ed25519_sk); |
| 964 |
|
key->ed25519_sk = NULL; |
| 965 |
|
} |
| 966 |
|
break; |
| 967 |
} |
} |
| 968 |
free(key); |
free(key); |
| 969 |
} |
} |
| 997 |
return KEY_ECDSA384; |
return KEY_ECDSA384; |
| 998 |
} else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) { |
} else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) { |
| 999 |
return KEY_ECDSA521; |
return KEY_ECDSA521; |
| 1000 |
|
} else if (strcmp(name, "ssh-ed25519") == 0) { |
| 1001 |
|
return KEY_ED25519; |
| 1002 |
} |
} |
| 1003 |
return KEY_UNSPEC; |
return KEY_UNSPEC; |
| 1004 |
} |
} |
| 1068 |
buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), |
buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), |
| 1069 |
EC_KEY_get0_public_key(key->ecdsa)); |
EC_KEY_get0_public_key(key->ecdsa)); |
| 1070 |
break; |
break; |
| 1071 |
|
case KEY_ED25519: |
| 1072 |
|
buffer_put_cstring(b, sshname); |
| 1073 |
|
buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); |
| 1074 |
|
break; |
| 1075 |
|
|
| 1076 |
default: |
default: |
| 1077 |
ret = 0; |
ret = 0; |
| 1103 |
// |
// |
| 1104 |
Key *key_from_blob(char *data, int blen) |
Key *key_from_blob(char *data, int blen) |
| 1105 |
{ |
{ |
| 1106 |
int keynamelen; |
int keynamelen, len; |
| 1107 |
char key[128]; |
char key[128]; |
| 1108 |
RSA *rsa = NULL; |
RSA *rsa = NULL; |
| 1109 |
DSA *dsa = NULL; |
DSA *dsa = NULL; |
| 1112 |
char *curve = NULL; |
char *curve = NULL; |
| 1113 |
Key *hostkey; // hostkey |
Key *hostkey; // hostkey |
| 1114 |
ssh_keytype type; |
ssh_keytype type; |
| 1115 |
|
unsigned char *pk = NULL; |
| 1116 |
|
|
| 1117 |
hostkey = malloc(sizeof(Key)); |
hostkey = malloc(sizeof(Key)); |
| 1118 |
if (hostkey == NULL) |
if (hostkey == NULL) |
| 1206 |
hostkey->ecdsa = ecdsa; |
hostkey->ecdsa = ecdsa; |
| 1207 |
break; |
break; |
| 1208 |
|
|
| 1209 |
|
case KEY_ED25519: |
| 1210 |
|
pk = buffer_get_string(&data, &len); |
| 1211 |
|
if (pk == NULL) |
| 1212 |
|
goto error; |
| 1213 |
|
if (len != ED25519_PK_SZ) |
| 1214 |
|
goto error; |
| 1215 |
|
|
| 1216 |
|
hostkey->type = type; |
| 1217 |
|
hostkey->ed25519_pk = pk; |
| 1218 |
|
pk = NULL; |
| 1219 |
|
break; |
| 1220 |
|
|
| 1221 |
default: // unknown key |
default: // unknown key |
| 1222 |
goto error; |
goto error; |
| 1223 |
} |
} |
| 1232 |
if (ecdsa != NULL) |
if (ecdsa != NULL) |
| 1233 |
EC_KEY_free(ecdsa); |
EC_KEY_free(ecdsa); |
| 1234 |
|
|
| 1235 |
|
free(hostkey); |
| 1236 |
|
|
| 1237 |
return NULL; |
return NULL; |
| 1238 |
} |
} |
| 1239 |
|
|
| 1240 |
|
|
| 1241 |
|
static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen) |
| 1242 |
|
{ |
| 1243 |
|
char *sig; |
| 1244 |
|
int slen, len; |
| 1245 |
|
unsigned long long smlen; |
| 1246 |
|
int ret; |
| 1247 |
|
buffer_t *b; |
| 1248 |
|
|
| 1249 |
|
smlen = slen = datalen + crypto_sign_ed25519_BYTES; |
| 1250 |
|
sig = malloc(slen); |
| 1251 |
|
|
| 1252 |
|
if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen, |
| 1253 |
|
key->ed25519_sk)) != 0 || smlen <= datalen) { |
| 1254 |
|
//error("%s: crypto_sign_ed25519 failed: %d", __func__, ret); |
| 1255 |
|
free(sig); |
| 1256 |
|
return -1; |
| 1257 |
|
} |
| 1258 |
|
/* encode signature */ |
| 1259 |
|
b = buffer_init(); |
| 1260 |
|
buffer_put_cstring(b, "ssh-ed25519"); |
| 1261 |
|
buffer_put_string(b, sig, (int)(smlen - datalen)); |
| 1262 |
|
len = buffer_len(b); |
| 1263 |
|
if (lenp != NULL) |
| 1264 |
|
*lenp = len; |
| 1265 |
|
if (sigp != NULL) { |
| 1266 |
|
*sigp = malloc(len); |
| 1267 |
|
memcpy(*sigp, buffer_ptr(b), len); |
| 1268 |
|
} |
| 1269 |
|
buffer_free(b); |
| 1270 |
|
memset(sig, 's', slen); |
| 1271 |
|
free(sig); |
| 1272 |
|
|
| 1273 |
|
return 0; |
| 1274 |
|
} |
| 1275 |
|
|
| 1276 |
|
|
| 1277 |
BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen) |
BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen) |
| 1278 |
{ |
{ |
| 1279 |
buffer_t *msg = NULL; |
buffer_t *msg = NULL; |
| 1280 |
char *s; |
char *s; |
| 1281 |
|
int ret; |
| 1282 |
|
|
| 1283 |
msg = buffer_init(); |
msg = buffer_init(); |
| 1284 |
if (msg == NULL) { |
if (msg == NULL) { |
| 1442 |
|
|
| 1443 |
break; |
break; |
| 1444 |
} |
} |
| 1445 |
|
|
| 1446 |
|
case KEY_ED25519: |
| 1447 |
|
ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen); |
| 1448 |
|
if (ret != 0) |
| 1449 |
|
goto error; |
| 1450 |
|
break; |
| 1451 |
|
|
| 1452 |
default: |
default: |
| 1453 |
buffer_free(msg); |
buffer_free(msg); |
| 1454 |
return FALSE; |
return FALSE; |
| 1504 |
buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa), |
buffer_put_ecpoint(msg, EC_KEY_get0_group(keypair->ecdsa), |
| 1505 |
EC_KEY_get0_public_key(keypair->ecdsa)); |
EC_KEY_get0_public_key(keypair->ecdsa)); |
| 1506 |
break; |
break; |
| 1507 |
|
case KEY_ED25519: |
| 1508 |
|
s = get_sshname_from_key(keypair); |
| 1509 |
|
buffer_put_cstring(msg, s); |
| 1510 |
|
buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ); |
| 1511 |
|
break; |
| 1512 |
default: |
default: |
| 1513 |
return FALSE; |
return FALSE; |
| 1514 |
} |
} |
| 1570 |
} |
} |
| 1571 |
return KEY_UNSPEC; |
return KEY_UNSPEC; |
| 1572 |
} |
} |
| 1573 |
|
|
| 1574 |
|
void key_private_serialize(Key *key, buffer_t *b) |
| 1575 |
|
{ |
| 1576 |
|
char *s; |
| 1577 |
|
|
| 1578 |
|
s = get_sshname_from_key(key); |
| 1579 |
|
buffer_put_cstring(b, s); |
| 1580 |
|
|
| 1581 |
|
switch (key->type) { |
| 1582 |
|
case KEY_RSA: |
| 1583 |
|
buffer_put_bignum2(b, key->rsa->n); |
| 1584 |
|
buffer_put_bignum2(b, key->rsa->e); |
| 1585 |
|
buffer_put_bignum2(b, key->rsa->d); |
| 1586 |
|
buffer_put_bignum2(b, key->rsa->iqmp); |
| 1587 |
|
buffer_put_bignum2(b, key->rsa->p); |
| 1588 |
|
buffer_put_bignum2(b, key->rsa->q); |
| 1589 |
|
break; |
| 1590 |
|
|
| 1591 |
|
case KEY_DSA: |
| 1592 |
|
buffer_put_bignum2(b, key->dsa->p); |
| 1593 |
|
buffer_put_bignum2(b, key->dsa->q); |
| 1594 |
|
buffer_put_bignum2(b, key->dsa->g); |
| 1595 |
|
buffer_put_bignum2(b, key->dsa->pub_key); |
| 1596 |
|
buffer_put_bignum2(b, key->dsa->priv_key); |
| 1597 |
|
break; |
| 1598 |
|
|
| 1599 |
|
case KEY_ECDSA256: |
| 1600 |
|
case KEY_ECDSA384: |
| 1601 |
|
case KEY_ECDSA521: |
| 1602 |
|
buffer_put_cstring(b, curve_keytype_to_name(key->type)); |
| 1603 |
|
buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), |
| 1604 |
|
EC_KEY_get0_public_key(key->ecdsa)); |
| 1605 |
|
buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa)); |
| 1606 |
|
break; |
| 1607 |
|
|
| 1608 |
|
case KEY_ED25519: |
| 1609 |
|
buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); |
| 1610 |
|
buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); |
| 1611 |
|
break; |
| 1612 |
|
|
| 1613 |
|
default: |
| 1614 |
|
break; |
| 1615 |
|
} |
| 1616 |
|
} |
| 1617 |
|
|
| 1618 |
|
/* calculate p-1 and q-1 */ |
| 1619 |
|
static void rsa_generate_additional_parameters(RSA *rsa) |
| 1620 |
|
{ |
| 1621 |
|
BIGNUM *aux = NULL; |
| 1622 |
|
BN_CTX *ctx = NULL; |
| 1623 |
|
|
| 1624 |
|
if ((aux = BN_new()) == NULL) |
| 1625 |
|
goto error; |
| 1626 |
|
if ((ctx = BN_CTX_new()) == NULL) |
| 1627 |
|
goto error; |
| 1628 |
|
|
| 1629 |
|
if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || |
| 1630 |
|
(BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || |
| 1631 |
|
(BN_sub(aux, rsa->p, BN_value_one()) == 0) || |
| 1632 |
|
(BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) |
| 1633 |
|
goto error; |
| 1634 |
|
|
| 1635 |
|
error: |
| 1636 |
|
if (aux) |
| 1637 |
|
BN_clear_free(aux); |
| 1638 |
|
if (ctx) |
| 1639 |
|
BN_CTX_free(ctx); |
| 1640 |
|
} |
| 1641 |
|
|
| 1642 |
|
static int key_ec_validate_private(EC_KEY *key) |
| 1643 |
|
{ |
| 1644 |
|
BN_CTX *bnctx = NULL; |
| 1645 |
|
BIGNUM *order, *tmp; |
| 1646 |
|
int ret = -1; |
| 1647 |
|
|
| 1648 |
|
if ((bnctx = BN_CTX_new()) == NULL) |
| 1649 |
|
goto out; |
| 1650 |
|
BN_CTX_start(bnctx); |
| 1651 |
|
|
| 1652 |
|
if ((order = BN_CTX_get(bnctx)) == NULL || |
| 1653 |
|
(tmp = BN_CTX_get(bnctx)) == NULL) |
| 1654 |
|
goto out; |
| 1655 |
|
|
| 1656 |
|
/* log2(private) > log2(order)/2 */ |
| 1657 |
|
if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) |
| 1658 |
|
goto out; |
| 1659 |
|
if (BN_num_bits(EC_KEY_get0_private_key(key)) <= |
| 1660 |
|
BN_num_bits(order) / 2) { |
| 1661 |
|
goto out; |
| 1662 |
|
} |
| 1663 |
|
|
| 1664 |
|
/* private < order - 1 */ |
| 1665 |
|
if (!BN_sub(tmp, order, BN_value_one())) |
| 1666 |
|
goto out; |
| 1667 |
|
if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { |
| 1668 |
|
goto out; |
| 1669 |
|
} |
| 1670 |
|
ret = 0; |
| 1671 |
|
|
| 1672 |
|
out: |
| 1673 |
|
if (bnctx) |
| 1674 |
|
BN_CTX_free(bnctx); |
| 1675 |
|
return ret; |
| 1676 |
|
} |
| 1677 |
|
|
| 1678 |
|
Key *key_private_deserialize(buffer_t *blob) |
| 1679 |
|
{ |
| 1680 |
|
int success = 0; |
| 1681 |
|
char *type_name = NULL; |
| 1682 |
|
Key *k = NULL; |
| 1683 |
|
unsigned int pklen, sklen; |
| 1684 |
|
int type; |
| 1685 |
|
|
| 1686 |
|
type_name = buffer_get_string_msg(blob, NULL); |
| 1687 |
|
if (type_name == NULL) |
| 1688 |
|
goto error; |
| 1689 |
|
type = get_keytype_from_name(type_name); |
| 1690 |
|
|
| 1691 |
|
k = key_new_private(type); |
| 1692 |
|
|
| 1693 |
|
switch (type) { |
| 1694 |
|
case KEY_RSA: |
| 1695 |
|
buffer_get_bignum2_msg(blob, k->rsa->n); |
| 1696 |
|
buffer_get_bignum2_msg(blob, k->rsa->e); |
| 1697 |
|
buffer_get_bignum2_msg(blob, k->rsa->d); |
| 1698 |
|
buffer_get_bignum2_msg(blob, k->rsa->iqmp); |
| 1699 |
|
buffer_get_bignum2_msg(blob, k->rsa->p); |
| 1700 |
|
buffer_get_bignum2_msg(blob, k->rsa->q); |
| 1701 |
|
|
| 1702 |
|
/* Generate additional parameters */ |
| 1703 |
|
rsa_generate_additional_parameters(k->rsa); |
| 1704 |
|
break; |
| 1705 |
|
|
| 1706 |
|
case KEY_DSA: |
| 1707 |
|
buffer_get_bignum2_msg(blob, k->dsa->p); |
| 1708 |
|
buffer_get_bignum2_msg(blob, k->dsa->q); |
| 1709 |
|
buffer_get_bignum2_msg(blob, k->dsa->g); |
| 1710 |
|
buffer_get_bignum2_msg(blob, k->dsa->pub_key); |
| 1711 |
|
buffer_get_bignum2_msg(blob, k->dsa->priv_key); |
| 1712 |
|
break; |
| 1713 |
|
|
| 1714 |
|
case KEY_ECDSA256: |
| 1715 |
|
case KEY_ECDSA384: |
| 1716 |
|
case KEY_ECDSA521: |
| 1717 |
|
{ |
| 1718 |
|
int success = 0; |
| 1719 |
|
unsigned int nid; |
| 1720 |
|
char *curve = NULL; |
| 1721 |
|
ssh_keytype skt; |
| 1722 |
|
BIGNUM *exponent = NULL; |
| 1723 |
|
EC_POINT *q = NULL; |
| 1724 |
|
|
| 1725 |
|
nid = keytype_to_cipher_nid(type); |
| 1726 |
|
curve = buffer_get_string_msg(blob, NULL); |
| 1727 |
|
skt = key_curve_name_to_keytype(curve); |
| 1728 |
|
if (nid != keytype_to_cipher_nid(skt)) |
| 1729 |
|
goto ecdsa_error; |
| 1730 |
|
|
| 1731 |
|
k->ecdsa = EC_KEY_new_by_curve_name(nid); |
| 1732 |
|
if (k->ecdsa == NULL) |
| 1733 |
|
goto ecdsa_error; |
| 1734 |
|
|
| 1735 |
|
q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); |
| 1736 |
|
if (q == NULL) |
| 1737 |
|
goto ecdsa_error; |
| 1738 |
|
|
| 1739 |
|
if ((exponent = BN_new()) == NULL) |
| 1740 |
|
goto ecdsa_error; |
| 1741 |
|
buffer_get_ecpoint_msg(blob, |
| 1742 |
|
EC_KEY_get0_group(k->ecdsa), q); |
| 1743 |
|
buffer_get_bignum2_msg(blob, exponent); |
| 1744 |
|
if (EC_KEY_set_public_key(k->ecdsa, q) != 1) |
| 1745 |
|
goto ecdsa_error; |
| 1746 |
|
if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) |
| 1747 |
|
goto ecdsa_error; |
| 1748 |
|
if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), |
| 1749 |
|
EC_KEY_get0_public_key(k->ecdsa)) != 0) |
| 1750 |
|
goto ecdsa_error; |
| 1751 |
|
if (key_ec_validate_private(k->ecdsa) != 0) |
| 1752 |
|
goto ecdsa_error; |
| 1753 |
|
|
| 1754 |
|
success = 1; |
| 1755 |
|
|
| 1756 |
|
ecdsa_error: |
| 1757 |
|
free(curve); |
| 1758 |
|
if (exponent) |
| 1759 |
|
BN_clear_free(exponent); |
| 1760 |
|
if (q) |
| 1761 |
|
EC_POINT_free(q); |
| 1762 |
|
if (success == 0) |
| 1763 |
|
goto error; |
| 1764 |
|
} |
| 1765 |
|
break; |
| 1766 |
|
|
| 1767 |
|
case KEY_ED25519: |
| 1768 |
|
k->ed25519_pk = buffer_get_string_msg(blob, &pklen); |
| 1769 |
|
k->ed25519_sk = buffer_get_string_msg(blob, &sklen); |
| 1770 |
|
if (pklen != ED25519_PK_SZ) |
| 1771 |
|
goto error; |
| 1772 |
|
if (sklen != ED25519_SK_SZ) |
| 1773 |
|
goto error; |
| 1774 |
|
break; |
| 1775 |
|
|
| 1776 |
|
default: |
| 1777 |
|
goto error; |
| 1778 |
|
break; |
| 1779 |
|
} |
| 1780 |
|
|
| 1781 |
|
/* enable blinding */ |
| 1782 |
|
switch (k->type) { |
| 1783 |
|
case KEY_RSA1: |
| 1784 |
|
case KEY_RSA: |
| 1785 |
|
if (RSA_blinding_on(k->rsa, NULL) != 1) |
| 1786 |
|
goto error; |
| 1787 |
|
break; |
| 1788 |
|
} |
| 1789 |
|
|
| 1790 |
|
success = 1; |
| 1791 |
|
|
| 1792 |
|
error: |
| 1793 |
|
free(type_name); |
| 1794 |
|
|
| 1795 |
|
if (success == 0) { |
| 1796 |
|
key_free(k); |
| 1797 |
|
k = NULL; |
| 1798 |
|
} |
| 1799 |
|
|
| 1800 |
|
return (k); |
| 1801 |
|
} |