View | Details | Raw Unified | Return to bug 2699
Collapse All | Expand All

(-)a/sshkey.c (-40 / +60 lines)
Lines 3365-3370 sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, Link Here
3365
3365
3366
3366
3367
#ifdef WITH_OPENSSL
3367
#ifdef WITH_OPENSSL
3368
static int
3369
translate_libcrypto_error(unsigned long pem_err)
3370
{
3371
	int pem_reason = ERR_GET_REASON(pem_err);
3372
3373
	switch (ERR_GET_LIB(pem_err)) {
3374
	case ERR_LIB_PEM:
3375
		switch (pem_reason) {
3376
		case PEM_R_BAD_PASSWORD_READ:
3377
		case PEM_R_PROBLEMS_GETTING_PASSWORD:
3378
		case PEM_R_BAD_DECRYPT:
3379
			return SSH_ERR_KEY_WRONG_PASSPHRASE;
3380
		default:
3381
			return SSH_ERR_INVALID_FORMAT;
3382
		}
3383
	case ERR_LIB_EVP:
3384
		switch (pem_reason) {
3385
		case EVP_R_BAD_DECRYPT:
3386
			return SSH_ERR_KEY_WRONG_PASSPHRASE;
3387
		case EVP_R_BN_DECODE_ERROR:
3388
		case EVP_R_DECODE_ERROR:
3389
#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3390
		case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3391
#endif
3392
			return SSH_ERR_INVALID_FORMAT;
3393
		default:
3394
			return SSH_ERR_LIBCRYPTO_ERROR;
3395
		}
3396
	case ERR_LIB_ASN1:
3397
		return SSH_ERR_INVALID_FORMAT;
3398
	}
3399
	return SSH_ERR_LIBCRYPTO_ERROR;
3400
}
3401
3402
static void
3403
clear_libcrypto_errors(void)
3404
{
3405
	while (ERR_get_error() != 0)
3406
		;
3407
}
3408
3409
/*
3410
 * Translate OpenSSL error codes to determine whether
3411
 * passphrase is required/incorrect.
3412
 */
3413
static int
3414
convert_libcrypto_error(void)
3415
{
3416
	/*
3417
	 * Some password errors are reported at the beginning
3418
	 * of the error queue.
3419
	 */
3420
	if (translate_libcrypto_error(ERR_peek_error()) ==
3421
	    SSH_ERR_KEY_WRONG_PASSPHRASE)
3422
		return SSH_ERR_KEY_WRONG_PASSPHRASE;
3423
	return translate_libcrypto_error(ERR_peek_last_error());
3424
}
3425
3368
static int
3426
static int
3369
sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3427
sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3370
    const char *passphrase, struct sshkey **keyp)
3428
    const char *passphrase, struct sshkey **keyp)
Lines 3385-3432 sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, Link Here
3385
		goto out;
3443
		goto out;
3386
	}
3444
	}
3387
3445
3446
	clear_libcrypto_errors();
3388
	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3447
	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3389
	    (char *)passphrase)) == NULL) {
3448
	    (char *)passphrase)) == NULL) {
3390
		unsigned long pem_err = ERR_peek_last_error();
3449
		r = convert_libcrypto_error();
3391
		int pem_reason = ERR_GET_REASON(pem_err);
3392
3393
		/*
3394
		 * Translate OpenSSL error codes to determine whether
3395
		 * passphrase is required/incorrect.
3396
		 */
3397
		switch (ERR_GET_LIB(pem_err)) {
3398
		case ERR_LIB_PEM:
3399
			switch (pem_reason) {
3400
			case PEM_R_BAD_PASSWORD_READ:
3401
			case PEM_R_PROBLEMS_GETTING_PASSWORD:
3402
			case PEM_R_BAD_DECRYPT:
3403
				r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3404
				goto out;
3405
			default:
3406
				r = SSH_ERR_INVALID_FORMAT;
3407
				goto out;
3408
			}
3409
		case ERR_LIB_EVP:
3410
			switch (pem_reason) {
3411
			case EVP_R_BAD_DECRYPT:
3412
				r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3413
				goto out;
3414
			case EVP_R_BN_DECODE_ERROR:
3415
			case EVP_R_DECODE_ERROR:
3416
#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3417
			case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3418
#endif
3419
				r = SSH_ERR_INVALID_FORMAT;
3420
				goto out;
3421
			default:
3422
				r = SSH_ERR_LIBCRYPTO_ERROR;
3423
				goto out;
3424
			}
3425
		case ERR_LIB_ASN1:
3426
			r = SSH_ERR_INVALID_FORMAT;
3427
			goto out;
3428
		}
3429
		r = SSH_ERR_LIBCRYPTO_ERROR;
3430
		goto out;
3450
		goto out;
3431
	}
3451
	}
3432
	if (pk->type == EVP_PKEY_RSA &&
3452
	if (pk->type == EVP_PKEY_RSA &&

Return to bug 2699