diff options
Diffstat (limited to 'sshkey.c')
-rw-r--r-- | sshkey.c | 68 |
1 files changed, 34 insertions, 34 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.c,v 1.35 2016/06/19 07:48:02 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.c,v 1.41 2016/10/24 01:09:17 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | 4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. |
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include "includes.h" | 28 | #include "includes.h" |
29 | 29 | ||
30 | #include <sys/param.h> /* MIN MAX */ | ||
31 | #include <sys/types.h> | 30 | #include <sys/types.h> |
32 | #include <netinet/in.h> | 31 | #include <netinet/in.h> |
33 | 32 | ||
@@ -197,7 +196,7 @@ sshkey_ecdsa_nid_from_name(const char *name) | |||
197 | } | 196 | } |
198 | 197 | ||
199 | char * | 198 | char * |
200 | key_alg_list(int certs_only, int plain_only) | 199 | sshkey_alg_list(int certs_only, int plain_only, char sep) |
201 | { | 200 | { |
202 | char *tmp, *ret = NULL; | 201 | char *tmp, *ret = NULL; |
203 | size_t nlen, rlen = 0; | 202 | size_t nlen, rlen = 0; |
@@ -209,7 +208,7 @@ key_alg_list(int certs_only, int plain_only) | |||
209 | if ((certs_only && !kt->cert) || (plain_only && kt->cert)) | 208 | if ((certs_only && !kt->cert) || (plain_only && kt->cert)) |
210 | continue; | 209 | continue; |
211 | if (ret != NULL) | 210 | if (ret != NULL) |
212 | ret[rlen++] = '\n'; | 211 | ret[rlen++] = sep; |
213 | nlen = strlen(kt->name); | 212 | nlen = strlen(kt->name); |
214 | if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { | 213 | if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { |
215 | free(ret); | 214 | free(ret); |
@@ -514,7 +513,6 @@ sshkey_new(int type) | |||
514 | default: | 513 | default: |
515 | free(k); | 514 | free(k); |
516 | return NULL; | 515 | return NULL; |
517 | break; | ||
518 | } | 516 | } |
519 | 517 | ||
520 | if (sshkey_is_cert(k)) { | 518 | if (sshkey_is_cert(k)) { |
@@ -889,9 +887,12 @@ sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, | |||
889 | int nlen = BN_num_bytes(k->rsa->n); | 887 | int nlen = BN_num_bytes(k->rsa->n); |
890 | int elen = BN_num_bytes(k->rsa->e); | 888 | int elen = BN_num_bytes(k->rsa->e); |
891 | 889 | ||
890 | if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) { | ||
891 | r = SSH_ERR_INVALID_FORMAT; | ||
892 | goto out; | ||
893 | } | ||
892 | blob_len = nlen + elen; | 894 | blob_len = nlen + elen; |
893 | if (nlen >= INT_MAX - elen || | 895 | if ((blob = malloc(blob_len)) == NULL) { |
894 | (blob = malloc(blob_len)) == NULL) { | ||
895 | r = SSH_ERR_ALLOC_FAIL; | 896 | r = SSH_ERR_ALLOC_FAIL; |
896 | goto out; | 897 | goto out; |
897 | } | 898 | } |
@@ -1083,10 +1084,10 @@ fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, | |||
1083 | y += (input & 0x2) ? 1 : -1; | 1084 | y += (input & 0x2) ? 1 : -1; |
1084 | 1085 | ||
1085 | /* assure we are still in bounds */ | 1086 | /* assure we are still in bounds */ |
1086 | x = MAX(x, 0); | 1087 | x = MAXIMUM(x, 0); |
1087 | y = MAX(y, 0); | 1088 | y = MAXIMUM(y, 0); |
1088 | x = MIN(x, FLDSIZE_X - 1); | 1089 | x = MINIMUM(x, FLDSIZE_X - 1); |
1089 | y = MIN(y, FLDSIZE_Y - 1); | 1090 | y = MINIMUM(y, FLDSIZE_Y - 1); |
1090 | 1091 | ||
1091 | /* augment the field */ | 1092 | /* augment the field */ |
1092 | if (field[x][y] < len - 2) | 1093 | if (field[x][y] < len - 2) |
@@ -1127,7 +1128,7 @@ fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, | |||
1127 | for (y = 0; y < FLDSIZE_Y; y++) { | 1128 | for (y = 0; y < FLDSIZE_Y; y++) { |
1128 | *p++ = '|'; | 1129 | *p++ = '|'; |
1129 | for (x = 0; x < FLDSIZE_X; x++) | 1130 | for (x = 0; x < FLDSIZE_X; x++) |
1130 | *p++ = augmentation_string[MIN(field[x][y], len)]; | 1131 | *p++ = augmentation_string[MINIMUM(field[x][y], len)]; |
1131 | *p++ = '|'; | 1132 | *p++ = '|'; |
1132 | *p++ = '\n'; | 1133 | *p++ = '\n'; |
1133 | } | 1134 | } |
@@ -2863,6 +2864,14 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | |||
2863 | BIGNUM *order, *x, *y, *tmp; | 2864 | BIGNUM *order, *x, *y, *tmp; |
2864 | int ret = SSH_ERR_KEY_INVALID_EC_VALUE; | 2865 | int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
2865 | 2866 | ||
2867 | /* | ||
2868 | * NB. This assumes OpenSSL has already verified that the public | ||
2869 | * point lies on the curve. This is done by EC_POINT_oct2point() | ||
2870 | * implicitly calling EC_POINT_is_on_curve(). If this code is ever | ||
2871 | * reachable with public points not unmarshalled using | ||
2872 | * EC_POINT_oct2point then the caller will need to explicitly check. | ||
2873 | */ | ||
2874 | |||
2866 | if ((bnctx = BN_CTX_new()) == NULL) | 2875 | if ((bnctx = BN_CTX_new()) == NULL) |
2867 | return SSH_ERR_ALLOC_FAIL; | 2876 | return SSH_ERR_ALLOC_FAIL; |
2868 | BN_CTX_start(bnctx); | 2877 | BN_CTX_start(bnctx); |
@@ -3030,13 +3039,11 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | |||
3030 | size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; | 3039 | size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; |
3031 | u_int check; | 3040 | u_int check; |
3032 | int r = SSH_ERR_INTERNAL_ERROR; | 3041 | int r = SSH_ERR_INTERNAL_ERROR; |
3033 | struct sshcipher_ctx ciphercontext; | 3042 | struct sshcipher_ctx *ciphercontext = NULL; |
3034 | const struct sshcipher *cipher; | 3043 | const struct sshcipher *cipher; |
3035 | const char *kdfname = KDFNAME; | 3044 | const char *kdfname = KDFNAME; |
3036 | struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; | 3045 | struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; |
3037 | 3046 | ||
3038 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | ||
3039 | |||
3040 | if (rounds <= 0) | 3047 | if (rounds <= 0) |
3041 | rounds = DEFAULT_ROUNDS; | 3048 | rounds = DEFAULT_ROUNDS; |
3042 | if (passphrase == NULL || !strlen(passphrase)) { | 3049 | if (passphrase == NULL || !strlen(passphrase)) { |
@@ -3123,7 +3130,7 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | |||
3123 | if ((r = sshbuf_reserve(encoded, | 3130 | if ((r = sshbuf_reserve(encoded, |
3124 | sshbuf_len(encrypted) + authlen, &cp)) != 0) | 3131 | sshbuf_len(encrypted) + authlen, &cp)) != 0) |
3125 | goto out; | 3132 | goto out; |
3126 | if ((r = cipher_crypt(&ciphercontext, 0, cp, | 3133 | if ((r = cipher_crypt(ciphercontext, 0, cp, |
3127 | sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) | 3134 | sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) |
3128 | goto out; | 3135 | goto out; |
3129 | 3136 | ||
@@ -3155,7 +3162,7 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | |||
3155 | sshbuf_free(kdf); | 3162 | sshbuf_free(kdf); |
3156 | sshbuf_free(encoded); | 3163 | sshbuf_free(encoded); |
3157 | sshbuf_free(encrypted); | 3164 | sshbuf_free(encrypted); |
3158 | cipher_cleanup(&ciphercontext); | 3165 | cipher_free(ciphercontext); |
3159 | explicit_bzero(salt, sizeof(salt)); | 3166 | explicit_bzero(salt, sizeof(salt)); |
3160 | if (key != NULL) { | 3167 | if (key != NULL) { |
3161 | explicit_bzero(key, keylen + ivlen); | 3168 | explicit_bzero(key, keylen + ivlen); |
@@ -3184,12 +3191,11 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, | |||
3184 | size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; | 3191 | size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; |
3185 | struct sshbuf *encoded = NULL, *decoded = NULL; | 3192 | struct sshbuf *encoded = NULL, *decoded = NULL; |
3186 | struct sshbuf *kdf = NULL, *decrypted = NULL; | 3193 | struct sshbuf *kdf = NULL, *decrypted = NULL; |
3187 | struct sshcipher_ctx ciphercontext; | 3194 | struct sshcipher_ctx *ciphercontext = NULL; |
3188 | struct sshkey *k = NULL; | 3195 | struct sshkey *k = NULL; |
3189 | u_char *key = NULL, *salt = NULL, *dp, pad, last; | 3196 | u_char *key = NULL, *salt = NULL, *dp, pad, last; |
3190 | u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; | 3197 | u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; |
3191 | 3198 | ||
3192 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | ||
3193 | if (keyp != NULL) | 3199 | if (keyp != NULL) |
3194 | *keyp = NULL; | 3200 | *keyp = NULL; |
3195 | if (commentp != NULL) | 3201 | if (commentp != NULL) |
@@ -3318,7 +3324,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, | |||
3318 | (r = cipher_init(&ciphercontext, cipher, key, keylen, | 3324 | (r = cipher_init(&ciphercontext, cipher, key, keylen, |
3319 | key + keylen, ivlen, 0)) != 0) | 3325 | key + keylen, ivlen, 0)) != 0) |
3320 | goto out; | 3326 | goto out; |
3321 | if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded), | 3327 | if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), |
3322 | encrypted_len, 0, authlen)) != 0) { | 3328 | encrypted_len, 0, authlen)) != 0) { |
3323 | /* an integrity error here indicates an incorrect passphrase */ | 3329 | /* an integrity error here indicates an incorrect passphrase */ |
3324 | if (r == SSH_ERR_MAC_INVALID) | 3330 | if (r == SSH_ERR_MAC_INVALID) |
@@ -3372,7 +3378,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, | |||
3372 | } | 3378 | } |
3373 | out: | 3379 | out: |
3374 | pad = 0; | 3380 | pad = 0; |
3375 | cipher_cleanup(&ciphercontext); | 3381 | cipher_free(ciphercontext); |
3376 | free(ciphername); | 3382 | free(ciphername); |
3377 | free(kdfname); | 3383 | free(kdfname); |
3378 | free(comment); | 3384 | free(comment); |
@@ -3406,7 +3412,7 @@ sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, | |||
3406 | struct sshbuf *buffer = NULL, *encrypted = NULL; | 3412 | struct sshbuf *buffer = NULL, *encrypted = NULL; |
3407 | u_char buf[8]; | 3413 | u_char buf[8]; |
3408 | int r, cipher_num; | 3414 | int r, cipher_num; |
3409 | struct sshcipher_ctx ciphercontext; | 3415 | struct sshcipher_ctx *ciphercontext = NULL; |
3410 | const struct sshcipher *cipher; | 3416 | const struct sshcipher *cipher; |
3411 | u_char *cp; | 3417 | u_char *cp; |
3412 | 3418 | ||
@@ -3476,16 +3482,14 @@ sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, | |||
3476 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, | 3482 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, |
3477 | CIPHER_ENCRYPT)) != 0) | 3483 | CIPHER_ENCRYPT)) != 0) |
3478 | goto out; | 3484 | goto out; |
3479 | if ((r = cipher_crypt(&ciphercontext, 0, cp, | 3485 | if ((r = cipher_crypt(ciphercontext, 0, cp, |
3480 | sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) | 3486 | sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) |
3481 | goto out; | 3487 | goto out; |
3482 | if ((r = cipher_cleanup(&ciphercontext)) != 0) | ||
3483 | goto out; | ||
3484 | 3488 | ||
3485 | r = sshbuf_putb(blob, encrypted); | 3489 | r = sshbuf_putb(blob, encrypted); |
3486 | 3490 | ||
3487 | out: | 3491 | out: |
3488 | explicit_bzero(&ciphercontext, sizeof(ciphercontext)); | 3492 | cipher_free(ciphercontext); |
3489 | explicit_bzero(buf, sizeof(buf)); | 3493 | explicit_bzero(buf, sizeof(buf)); |
3490 | sshbuf_free(buffer); | 3494 | sshbuf_free(buffer); |
3491 | sshbuf_free(encrypted); | 3495 | sshbuf_free(encrypted); |
@@ -3655,7 +3659,7 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | |||
3655 | struct sshbuf *decrypted = NULL, *copy = NULL; | 3659 | struct sshbuf *decrypted = NULL, *copy = NULL; |
3656 | u_char *cp; | 3660 | u_char *cp; |
3657 | char *comment = NULL; | 3661 | char *comment = NULL; |
3658 | struct sshcipher_ctx ciphercontext; | 3662 | struct sshcipher_ctx *ciphercontext = NULL; |
3659 | const struct sshcipher *cipher; | 3663 | const struct sshcipher *cipher; |
3660 | struct sshkey *prv = NULL; | 3664 | struct sshkey *prv = NULL; |
3661 | 3665 | ||
@@ -3713,12 +3717,8 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | |||
3713 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, | 3717 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, |
3714 | CIPHER_DECRYPT)) != 0) | 3718 | CIPHER_DECRYPT)) != 0) |
3715 | goto out; | 3719 | goto out; |
3716 | if ((r = cipher_crypt(&ciphercontext, 0, cp, | 3720 | if ((r = cipher_crypt(ciphercontext, 0, cp, |
3717 | sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) { | 3721 | sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) |
3718 | cipher_cleanup(&ciphercontext); | ||
3719 | goto out; | ||
3720 | } | ||
3721 | if ((r = cipher_cleanup(&ciphercontext)) != 0) | ||
3722 | goto out; | 3722 | goto out; |
3723 | 3723 | ||
3724 | if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || | 3724 | if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || |
@@ -3755,7 +3755,7 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | |||
3755 | comment = NULL; | 3755 | comment = NULL; |
3756 | } | 3756 | } |
3757 | out: | 3757 | out: |
3758 | explicit_bzero(&ciphercontext, sizeof(ciphercontext)); | 3758 | cipher_free(ciphercontext); |
3759 | free(comment); | 3759 | free(comment); |
3760 | sshkey_free(prv); | 3760 | sshkey_free(prv); |
3761 | sshbuf_free(copy); | 3761 | sshbuf_free(copy); |