Exemple #1
0
ASN1_OCTET_STRING *
PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
    const char *pass, int passlen,
    void *obj, int zbuf)
{
	ASN1_OCTET_STRING *oct;
	unsigned char *in = NULL;
	int inlen;

	if (!(oct = ASN1_OCTET_STRING_new ())) {
		PKCS12error(ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	inlen = ASN1_item_i2d(obj, &in, it);
	if (!in) {
		PKCS12error(PKCS12_R_ENCODE_ERROR);
		goto err;
	}
	if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
	    &oct->length, 1)) {
		PKCS12error(PKCS12_R_ENCRYPT_ERROR);
		goto err;
	}
	if (zbuf)
		explicit_bzero(in, inlen);
	free(in);
	return oct;

err:
	free(in);
	ASN1_OCTET_STRING_free(oct);
	return NULL;
}
Exemple #2
0
int
PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
    int saltlen, int id, int iter, int n, unsigned char *out,
    const EVP_MD *md_type)
{
	int ret;
	unsigned char *unipass;
	int uniplen;

	if (!pass) {
		unipass = NULL;
		uniplen = 0;
	} else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
		PKCS12error(ERR_R_MALLOC_FAILURE);
		return 0;
	}
	ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
	    id, iter, n, out, md_type);
	if (ret <= 0)
		return 0;
	if (unipass) {
		explicit_bzero(unipass, uniplen);
		free(unipass);
	}
	return ret;
}
Exemple #3
0
unsigned char *
PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, int passlen,
    unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de)
{
	unsigned char *out;
	int outlen, i;
	EVP_CIPHER_CTX ctx;

	EVP_CIPHER_CTX_init(&ctx);
	/* Decrypt data */
	if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
	    algor->parameter, &ctx, en_de)) {
		out = NULL;
		PKCS12error(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
		goto err;
	}

	if (!(out = malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) {
		PKCS12error(ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) {
		free(out);
		out = NULL;
		PKCS12error(ERR_R_EVP_LIB);
		goto err;
	}

	outlen = i;
	if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) {
		free(out);
		out = NULL;
		PKCS12error(PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
		goto err;
	}
	outlen += i;
	if (datalen)
		*datalen = outlen;
	if (data)
		*data = out;

err:
	EVP_CIPHER_CTX_cleanup(&ctx);
	return out;

}
Exemple #4
0
/* Generate a MAC */
int
PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
    unsigned char *mac, unsigned int *maclen)
{
	const EVP_MD *md_type;
	HMAC_CTX hmac;
	unsigned char key[EVP_MAX_MD_SIZE], *salt;
	int saltlen, iter;
	int md_size;

	if (!PKCS7_type_is_data(p12->authsafes)) {
		PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA);
		return 0;
	}

	salt = p12->mac->salt->data;
	saltlen = p12->mac->salt->length;
	if (!p12->mac->iter)
		iter = 1;
	else if ((iter = ASN1_INTEGER_get(p12->mac->iter)) <= 0) {
		PKCS12error(PKCS12_R_DECODE_ERROR);
		return 0;
	}
	if (!(md_type = EVP_get_digestbyobj(
	    p12->mac->dinfo->algor->algorithm))) {
		PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
		return 0;
	}
	md_size = EVP_MD_size(md_type);
	if (md_size < 0)
		return 0;
	if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
	    md_size, key, md_type)) {
		PKCS12error(PKCS12_R_KEY_GEN_ERROR);
		return 0;
	}
	HMAC_CTX_init(&hmac);
	if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) ||
	    !HMAC_Update(&hmac, p12->authsafes->d.data->data,
	    p12->authsafes->d.data->length) ||
	    !HMAC_Final(&hmac, mac, maclen)) {
		HMAC_CTX_cleanup(&hmac);
		return 0;
	}
	HMAC_CTX_cleanup(&hmac);
	return 1;
}
Exemple #5
0
/* Verify the mac */
int
PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
{
	unsigned char mac[EVP_MAX_MD_SIZE];
	unsigned int maclen;

	if (p12->mac == NULL) {
		PKCS12error(PKCS12_R_MAC_ABSENT);
		return 0;
	}
	if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
		PKCS12error(PKCS12_R_MAC_GENERATION_ERROR);
		return 0;
	}
	if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) ||
	    memcmp(mac, p12->mac->dinfo->digest->data, maclen))
		return 0;
	return 1;
}
Exemple #6
0
void *
PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
    const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf)
{
	unsigned char *out;
	const unsigned char *p;
	void *ret;
	int outlen;

	if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
	    &out, &outlen, 0)) {
		PKCS12error(PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
		return NULL;
	}
	p = out;
	ret = ASN1_item_d2i(NULL, &p, outlen, it);
	if (zbuf)
		explicit_bzero(out, outlen);
	if (!ret)
		PKCS12error(PKCS12_R_DECODE_ERROR);
	free(out);
	return ret;
}
Exemple #7
0
X509_SIG *
PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
    int passlen, unsigned char *salt, int saltlen, int iter,
    PKCS8_PRIV_KEY_INFO *p8inf)
{
	X509_SIG *p8 = NULL;
	X509_ALGOR *pbe;

	if (!(p8 = X509_SIG_new())) {
		PKCS12error(ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (pbe_nid == -1)
		pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
	else
		pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
	if (!pbe) {
		PKCS12error(ERR_R_ASN1_LIB);
		goto err;
	}
	X509_ALGOR_free(p8->algor);
	p8->algor = pbe;
	ASN1_OCTET_STRING_free(p8->digest);
	p8->digest = PKCS12_item_i2d_encrypt(pbe,
	    &PKCS8_PRIV_KEY_INFO_it, pass, passlen, p8inf, 1);
	if (!p8->digest) {
		PKCS12error(PKCS12_R_ENCRYPT_ERROR);
		goto err;
	}

	return p8;

err:
	X509_SIG_free(p8);
	return NULL;
}
Exemple #8
0
/* Set up a mac structure */
int
PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
    const EVP_MD *md_type)
{
	if (!(p12->mac = PKCS12_MAC_DATA_new()))
		return PKCS12_ERROR;
	if (iter > 1) {
		if (!(p12->mac->iter = ASN1_INTEGER_new())) {
			PKCS12error(ERR_R_MALLOC_FAILURE);
			return 0;
		}
		if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
			PKCS12error(ERR_R_MALLOC_FAILURE);
			return 0;
		}
	}
	if (!saltlen)
		saltlen = PKCS12_SALT_LEN;
	if (!(p12->mac->salt->data = malloc(saltlen))) {
		PKCS12error(ERR_R_MALLOC_FAILURE);
		return 0;
	}
	p12->mac->salt->length = saltlen;
	if (!salt)
		arc4random_buf(p12->mac->salt->data, saltlen);
	else
		memcpy (p12->mac->salt->data, salt, saltlen);
	p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
	if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
		PKCS12error(ERR_R_MALLOC_FAILURE);
		return 0;
	}
	p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;

	return 1;
}
Exemple #9
0
int
PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *salt,
    int saltlen, int iter, const EVP_MD *md_type)
{
	unsigned char mac[EVP_MAX_MD_SIZE];
	unsigned int maclen;

	if (!md_type)
		md_type = EVP_sha1();
	if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) ==
	    PKCS12_ERROR) {
		PKCS12error(PKCS12_R_MAC_SETUP_ERROR);
		return 0;
	}
	if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
		PKCS12error(PKCS12_R_MAC_GENERATION_ERROR);
		return 0;
	}
	if (!(ASN1_STRING_set(p12->mac->dinfo->digest, mac, maclen))) {
		PKCS12error(PKCS12_R_MAC_STRING_SET_ERROR);
		return 0;
	}
	return 1;
}
Exemple #10
0
int
PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
    int saltlen, int id, int iter, int n, unsigned char *out,
    const EVP_MD *md_type)
{
	unsigned char *B, *D, *I, *p, *Ai;
	int Slen, Plen, Ilen, Ijlen;
	int i, j, u, v;
	int ret = 0;
	BIGNUM *Ij, *Bpl1;	/* These hold Ij and B + 1 */
	EVP_MD_CTX ctx;

	v = EVP_MD_block_size(md_type);
	u = EVP_MD_size(md_type);
	if (u < 0)
		return 0;

	EVP_MD_CTX_init(&ctx);
	D = malloc(v);
	Ai = malloc(u);
	B = malloc(v + 1);
	Slen = v * ((saltlen + v - 1) / v);
	if (passlen)
		Plen = v * ((passlen + v - 1)/v);
	else
		Plen = 0;
	Ilen = Slen + Plen;
	I = malloc(Ilen);
	Ij = BN_new();
	Bpl1 = BN_new();
	if (!D || !Ai || !B || !I || !Ij || !Bpl1)
		goto err;
	for (i = 0; i < v; i++)
		D[i] = id;
	p = I;
	for (i = 0; i < Slen; i++)
		*p++ = salt[i % saltlen];
	for (i = 0; i < Plen; i++)
		*p++ = pass[i % passlen];
	for (;;) {
		if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
		    !EVP_DigestUpdate(&ctx, D, v) ||
		    !EVP_DigestUpdate(&ctx, I, Ilen) ||
		    !EVP_DigestFinal_ex(&ctx, Ai, NULL))
			goto err;
		for (j = 1; j < iter; j++) {
			if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
			    !EVP_DigestUpdate(&ctx, Ai, u) ||
			    !EVP_DigestFinal_ex(&ctx, Ai, NULL))
				goto err;
		}
		memcpy (out, Ai, min (n, u));
		if (u >= n) {
			ret = 1;
			goto end;
		}
		n -= u;
		out += u;
		for (j = 0; j < v; j++)
			B[j] = Ai[j % u];
		/* Work out B + 1 first then can use B as tmp space */
		if (!BN_bin2bn (B, v, Bpl1))
			goto err;
		if (!BN_add_word (Bpl1, 1))
			goto err;
		for (j = 0; j < Ilen; j += v) {
			if (!BN_bin2bn(I + j, v, Ij))
				goto err;
			if (!BN_add(Ij, Ij, Bpl1))
				goto err;
			if (!BN_bn2bin(Ij, B))
				goto err;
			Ijlen = BN_num_bytes (Ij);
			/* If more than 2^(v*8) - 1 cut off MSB */
			if (Ijlen > v) {
				if (!BN_bn2bin (Ij, B))
					goto err;
				memcpy (I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
				/* If less than v bytes pad with zeroes */
			} else if (Ijlen < v) {
				memset(I + j, 0, v - Ijlen);
				if (!BN_bn2bin(Ij, I + j + v - Ijlen))
					goto err;
#endif
			} else if (!BN_bn2bin (Ij, I + j))
				goto err;
		}
	}

err:
	PKCS12error(ERR_R_MALLOC_FAILURE);

end:
	free(Ai);
	free(B);
	free(D);
	free(I);
	BN_free(Ij);
	BN_free(Bpl1);
	EVP_MD_CTX_cleanup(&ctx);
	return ret;
}