Exemplo n.º 1
0
static EVP_PKEY *
do_PVK_body(const unsigned char **in, unsigned int saltlen,
    unsigned int keylen, pem_password_cb *cb, void *u)
{
	EVP_PKEY *ret = NULL;
	const unsigned char *p = *in;
	unsigned int magic;
	unsigned char *enctmp = NULL, *q;
	EVP_CIPHER_CTX cctx;

	EVP_CIPHER_CTX_init(&cctx);
	if (saltlen) {
		char psbuf[PEM_BUFSIZE];
		unsigned char keybuf[20];
		int enctmplen, inlen;

		if (cb)
			inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
		else
			inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
		if (inlen <= 0) {
			PEMerror(PEM_R_BAD_PASSWORD_READ);
			goto err;
		}
		enctmp = malloc(keylen + 8);
		if (!enctmp) {
			PEMerror(ERR_R_MALLOC_FAILURE);
			goto err;
		}
		if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf,
		    inlen)) {
			goto err;
		}
		p += saltlen;
		/* Copy BLOBHEADER across, decrypt rest */
		memcpy(enctmp, p, 8);
		p += 8;
		if (keylen < 8) {
			PEMerror(PEM_R_PVK_TOO_SHORT);
			goto err;
		}
		inlen = keylen - 8;
		q = enctmp + 8;
		if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
			goto err;
		if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
			goto err;
		if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
			goto err;
		magic = read_ledword((const unsigned char **)&q);
		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
			q = enctmp + 8;
			memset(keybuf + 5, 0, 11);
			if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
			    NULL))
				goto err;
			explicit_bzero(keybuf, 20);
			if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
				goto err;
			if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen,
			    &enctmplen))
				goto err;
			magic = read_ledword((const unsigned char **)&q);
			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
				PEMerror(PEM_R_BAD_DECRYPT);
				goto err;
			}
		} else
			explicit_bzero(keybuf, 20);
		p = enctmp;
	}

	ret = b2i_PrivateKey(&p, keylen);

err:
	EVP_CIPHER_CTX_cleanup(&cctx);
	if (enctmp && saltlen)
		free(enctmp);
	return ret;
}
static EVP_PKEY *do_PVK_body(const unsigned char **in,
		unsigned int saltlen, unsigned int keylen,
		pem_password_cb *cb, void *u)
	{
	EVP_PKEY *ret = NULL;
	const unsigned char *p = *in;
	unsigned int magic;
	unsigned char *enctmp = NULL, *q;
	if (saltlen)
		{
		char psbuf[PEM_BUFSIZE];
		unsigned char keybuf[20];
		EVP_CIPHER_CTX cctx;
		int enctmplen, inlen;
		if (cb)
			inlen=cb(psbuf,PEM_BUFSIZE,0,u);
		else
			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
		if (inlen <= 0)
			{
			PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ);
			return NULL;
			}
		enctmp = (unsigned char*)OPENSSL_malloc(keylen + 8);
		if (!enctmp)
			{
			PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		if (!derive_pvk_key(keybuf, p, saltlen,
			    (unsigned char *)psbuf, inlen))
			return NULL;
		p += saltlen;
		/* Copy BLOBHEADER across, decrypt rest */
		TINYCLR_SSL_MEMCPY(enctmp, p, 8);
		p += 8;
		inlen = keylen - 8;
		q = enctmp + 8;
		EVP_CIPHER_CTX_init(&cctx);
		EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
		EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
		EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen);
		magic = read_ledword((const unsigned char **)&q);
		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
			{
			q = enctmp + 8;
			TINYCLR_SSL_MEMSET(keybuf + 5, 0, 11);
			EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
								NULL);
			OPENSSL_cleanse(keybuf, 20);
			EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
			EVP_DecryptFinal_ex(&cctx, q + enctmplen,
								&enctmplen);
			magic = read_ledword((const unsigned char **)&q);
			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
				{
				EVP_CIPHER_CTX_cleanup(&cctx);
				PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
				goto err;
				}
			}
		else
			OPENSSL_cleanse(keybuf, 20);
		EVP_CIPHER_CTX_cleanup(&cctx);
		p = enctmp;
		}

	ret = b2i_PrivateKey(&p, keylen);
	err:
	if (enctmp && saltlen)
		OPENSSL_free(enctmp);
	return ret;
	}