Blame lib/x509/privkey_pkcs8_pbes1.c

Packit aea12f
/*
Packit aea12f
 * Copyright (C) 2016 Red Hat
Packit aea12f
 *
Packit aea12f
 * Author: Nikos Mavrogiannopoulos
Packit aea12f
 *
Packit aea12f
 * This file is part of GnuTLS.
Packit aea12f
 *
Packit aea12f
 * The GnuTLS is free software; you can redistribute it and/or
Packit aea12f
 * modify it under the terms of the GNU Lesser General Public License
Packit aea12f
 * as published by the Free Software Foundation; either version 2.1 of
Packit aea12f
 * the License, or (at your option) any later version.
Packit aea12f
 *
Packit aea12f
 * This library is distributed in the hope that it will be useful, but
Packit aea12f
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit aea12f
 * Lesser General Public License for more details.
Packit aea12f
 *
Packit aea12f
 * You should have received a copy of the GNU Lesser General Public License
Packit aea12f
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
Packit aea12f
 *
Packit aea12f
 */
Packit aea12f
Packit aea12f
#include "gnutls_int.h"
Packit aea12f
Packit aea12f
#include <datum.h>
Packit aea12f
#include <global.h>
Packit aea12f
#include "errors.h"
Packit aea12f
#include <common.h>
Packit aea12f
#include <x509.h>
Packit aea12f
#include <x509_b64.h>
Packit aea12f
#include "x509_int.h"
Packit aea12f
#include "pkcs7_int.h"
Packit aea12f
#include <algorithms.h>
Packit aea12f
#include <nettle/md5.h>
Packit aea12f
Packit aea12f
/* This file includes support for PKCS#8 PBES1 with DES and MD5.
Packit aea12f
 * We only support decryption for compatibility with other software.
Packit aea12f
 */
Packit aea12f
Packit aea12f
int _gnutls_read_pbkdf1_params(const uint8_t * data, int data_size,
Packit aea12f
		       struct pbkdf2_params *kdf_params,
Packit aea12f
		       struct pbe_enc_params *enc_params)
Packit aea12f
{
Packit aea12f
	ASN1_TYPE pasn = ASN1_TYPE_EMPTY;
Packit aea12f
	int len;
Packit aea12f
	int ret, result;
Packit aea12f
Packit aea12f
	memset(kdf_params, 0, sizeof(*kdf_params));
Packit aea12f
	memset(enc_params, 0, sizeof(*enc_params));
Packit aea12f
Packit aea12f
	if ((result =
Packit aea12f
		     asn1_create_element(_gnutls_get_pkix(),
Packit aea12f
					 "PKIX1.pkcs-5-PBE-params",
Packit aea12f
					 &pasn)) != ASN1_SUCCESS) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return _gnutls_asn2err(result);
Packit aea12f
	}
Packit aea12f
Packit aea12f
	/* Decode the parameters.
Packit aea12f
	 */
Packit aea12f
	result =
Packit aea12f
	    _asn1_strict_der_decode(&pasn, data, data_size, NULL);
Packit aea12f
	if (result != ASN1_SUCCESS) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		ret = _gnutls_asn2err(result);
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	ret =
Packit aea12f
	    _gnutls_x509_read_uint(pasn, "iterationCount",
Packit aea12f
			   &kdf_params->iter_count);
Packit aea12f
	if (ret < 0) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	if (kdf_params->iter_count >= MAX_ITER_COUNT || kdf_params->iter_count == 0) {
Packit aea12f
		ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	len = sizeof(kdf_params->salt);
Packit aea12f
	result =
Packit aea12f
	    asn1_read_value(pasn, "salt",
Packit aea12f
		    kdf_params->salt, &len;;
Packit aea12f
	if (result != ASN1_SUCCESS) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		ret = _gnutls_asn2err(result);
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	if (len != 8) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		ret = GNUTLS_E_ILLEGAL_PARAMETER;
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	enc_params->cipher = GNUTLS_CIPHER_DES_CBC;
Packit aea12f
Packit aea12f
	ret = 0;
Packit aea12f
 error:
Packit aea12f
	asn1_delete_structure2(&pasn, ASN1_DELETE_FLAG_ZEROIZE);
Packit aea12f
	return ret;
Packit aea12f
Packit aea12f
}
Packit aea12f
Packit aea12f
static void pbkdf1_md5(const char *password, unsigned password_len,
Packit aea12f
	const uint8_t salt[8], unsigned iter_count, unsigned key_size, uint8_t *key)
Packit aea12f
{
Packit aea12f
	struct md5_ctx ctx;
Packit aea12f
	uint8_t tmp[16];
Packit aea12f
	unsigned i;
Packit aea12f
Packit aea12f
	if (key_size > sizeof(tmp))
Packit aea12f
		abort();
Packit aea12f
Packit aea12f
	for (i=0;i
Packit aea12f
		md5_init(&ctx;;
Packit aea12f
		if (i==0) {
Packit aea12f
			md5_update(&ctx, password_len, (uint8_t*)password);
Packit aea12f
			md5_update(&ctx, 8, salt);
Packit aea12f
			md5_digest(&ctx, 16, tmp);
Packit aea12f
		} else {
Packit aea12f
			md5_update(&ctx, 16, tmp);
Packit aea12f
			md5_digest(&ctx, 16, tmp);
Packit aea12f
		}
Packit aea12f
	}
Packit aea12f
Packit aea12f
	memcpy(key, tmp, key_size);
Packit aea12f
	return;
Packit aea12f
}
Packit aea12f
Packit aea12f
int
Packit aea12f
_gnutls_decrypt_pbes1_des_md5_data(const char *password,
Packit aea12f
			   unsigned password_len,
Packit aea12f
			   const struct pbkdf2_params *kdf_params,
Packit aea12f
			   const struct pbe_enc_params *enc_params,
Packit Service 991b93
			   const gnutls_datum_t *encrypted_data,
Packit aea12f
			   gnutls_datum_t *decrypted_data)
Packit aea12f
{
Packit aea12f
	int result;
Packit aea12f
	gnutls_datum_t dkey, d_iv;
Packit aea12f
	cipher_hd_st ch;
Packit aea12f
	uint8_t key[16];
Packit aea12f
	const unsigned block_size = 8;
Packit aea12f
Packit aea12f
	if (enc_params->cipher != GNUTLS_CIPHER_DES_CBC)
Packit aea12f
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
Packit aea12f
Packit aea12f
	if (encrypted_data->size % block_size != 0)
Packit aea12f
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
Packit aea12f
Packit aea12f
	/* generate the key
Packit aea12f
	 */
Packit aea12f
	pbkdf1_md5(password, password_len, kdf_params->salt, kdf_params->iter_count, sizeof(key), key);
Packit aea12f
Packit aea12f
	dkey.data = key;
Packit aea12f
	dkey.size = 8;
Packit aea12f
	d_iv.data = &key[8];
Packit aea12f
	d_iv.size = 8;
Packit aea12f
	result =
Packit aea12f
	    _gnutls_cipher_init(&ch, cipher_to_entry(GNUTLS_CIPHER_DES_CBC),
Packit aea12f
				&dkey, &d_iv, 0);
Packit aea12f
	if (result < 0)
Packit aea12f
		return gnutls_assert_val(result);
Packit aea12f
Packit aea12f
	result = _gnutls_cipher_decrypt(&ch, encrypted_data->data, encrypted_data->size);
Packit aea12f
	if (result < 0) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	if ((int)encrypted_data->size - encrypted_data->data[encrypted_data->size - 1] < 0) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		result = GNUTLS_E_ILLEGAL_PARAMETER;
Packit aea12f
		goto error;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	decrypted_data->data = encrypted_data->data;
Packit aea12f
	decrypted_data->size = encrypted_data->size - encrypted_data->data[encrypted_data->size - 1];
Packit aea12f
Packit aea12f
	result = 0;
Packit aea12f
 error:
Packit aea12f
	_gnutls_cipher_deinit(&ch);
Packit aea12f
Packit aea12f
	return result;
Packit aea12f
}
Packit aea12f