예제 #1
0
파일: pvkfmt.c 프로젝트: MiKTeX/miktex
static int
i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb,
    void *u)
{
	int outlen = 24, pklen;
	unsigned char *p, *salt = NULL;
	EVP_CIPHER_CTX cctx;

	EVP_CIPHER_CTX_init(&cctx);
	if (enclevel)
		outlen += PVK_SALTLEN;
	pklen = do_i2b(NULL, pk, 0);
	if (pklen < 0)
		return -1;
	outlen += pklen;
	p = malloc(outlen);
	if (!p) {
		PEMerror(ERR_R_MALLOC_FAILURE);
		return -1;
	}

	write_ledword(&p, MS_PVKMAGIC);
	write_ledword(&p, 0);
	if (pk->type == EVP_PKEY_DSA)
		write_ledword(&p, MS_KEYTYPE_SIGN);
	else
		write_ledword(&p, MS_KEYTYPE_KEYX);
	write_ledword(&p, enclevel ? 1 : 0);
	write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
	write_ledword(&p, pklen);
	if (enclevel) {
		arc4random_buf(p, PVK_SALTLEN);
		salt = p;
		p += PVK_SALTLEN;
	}
	do_i2b(&p, pk, 0);
	if (enclevel == 0) {
		*out = p;
		return outlen;
	} else {
		char psbuf[PEM_BUFSIZE];
		unsigned char keybuf[20];
		int enctmplen, inlen;
		if (cb)
			inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
		else
			inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
		if (inlen <= 0) {
			PEMerror(PEM_R_BAD_PASSWORD_READ);
			goto error;
		}
		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
		    (unsigned char *)psbuf, inlen))
			goto error;
		if (enclevel == 1)
			memset(keybuf + 5, 0, 11);
		p = salt + PVK_SALTLEN + 8;
		if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
			goto error;
		explicit_bzero(keybuf, 20);
		if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
			goto error;
		if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
			goto error;
	}
	EVP_CIPHER_CTX_cleanup(&cctx);
	*out = p;
	return outlen;

error:
	EVP_CIPHER_CTX_cleanup(&cctx);
	free(p);
	return -1;
}
예제 #2
0
파일: pvkfmt.c 프로젝트: 277800076/openssl
static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
                   pem_password_cb *cb, void *u)
{
    int outlen = 24, pklen;
    unsigned char *p, *salt = NULL;
    EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();
    if (enclevel)
        outlen += PVK_SALTLEN;
    pklen = do_i2b(NULL, pk, 0);
    if (pklen < 0)
        return -1;
    outlen += pklen;
    if (!out)
        return outlen;
    if (*out)
        p = *out;
    else {
        p = OPENSSL_malloc(outlen);
        if (p == NULL) {
            PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
            return -1;
        }
        *out = p;
    }

    write_ledword(&p, MS_PVKMAGIC);
    write_ledword(&p, 0);
    if (EVP_PKEY_id(pk) == EVP_PKEY_DSA)
        write_ledword(&p, MS_KEYTYPE_SIGN);
    else
        write_ledword(&p, MS_KEYTYPE_KEYX);
    write_ledword(&p, enclevel ? 1 : 0);
    write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
    write_ledword(&p, pklen);
    if (enclevel) {
        if (RAND_bytes(p, PVK_SALTLEN) <= 0)
            goto error;
        salt = p;
        p += PVK_SALTLEN;
    }
    do_i2b(&p, pk, 0);
    if (enclevel == 0)
        return outlen;
    else {
        char psbuf[PEM_BUFSIZE];
        unsigned char keybuf[20];
        int enctmplen, inlen;
        if (cb)
            inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
        else
            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
        if (inlen <= 0) {
            PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
            goto error;
        }
        if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
                            (unsigned char *)psbuf, inlen))
            goto error;
        if (enclevel == 1)
            memset(keybuf + 5, 0, 11);
        p = salt + PVK_SALTLEN + 8;
        if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
            goto error;
        OPENSSL_cleanse(keybuf, 20);
        if (!EVP_DecryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
            goto error;
        if (!EVP_DecryptFinal_ex(cctx, p + enctmplen, &enctmplen))
            goto error;
    }
    EVP_CIPHER_CTX_free(cctx);
    return outlen;

 error:
    EVP_CIPHER_CTX_free(cctx);
    return -1;
}
예제 #3
0
파일: pvkfmt.c 프로젝트: MiKTeX/miktex
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;
	}