예제 #1
0
파일: p12_decr.c 프로젝트: ciz/openssl
/*
 * Encrypt/Decrypt a buffer based on password and algor, result in a
 * OPENSSL_malloc'ed buffer
 */
unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
                                const char *pass, int passlen,
                                const unsigned char *in, int inlen,
                                unsigned char **data, int *datalen, int en_de)
{
    unsigned char *out = NULL;
    int outlen, i;
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();

    if (ctx == NULL) {
        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    /* Decrypt data */
    if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
                            algor->parameter, ctx, en_de)) {
        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
                  PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
        goto err;
    }

    if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx)))
            == NULL) {
        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

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

    outlen = i;
    if (!EVP_CipherFinal_ex(ctx, out + i, &i)) {
        OPENSSL_free(out);
        out = NULL;
        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
                  PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
        goto err;
    }
    outlen += i;
    if (datalen)
        *datalen = outlen;
    if (data)
        *data = out;
 err:
    EVP_CIPHER_CTX_free(ctx);
    return out;

}
예제 #2
0
/* //////////////////////////// PRIVATE/PROTECTED //////////////////////////////////// */
OsStatus OsEncryption::init(Direction direction)
{
    OsStatus retval = OS_FAILED;

#if defined(OSENCRYPTION)
    release();

    if (mKeyLen > 0 && mKey != NULL && mDataLen > 0 && mData != NULL)
    {
        ERR_clear_error();

        SSLeay_add_all_algorithms();
        mAlgorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC,
            PKCS5_DEFAULT_ITER, mSalt, mSaltLen);

        if (mAlgorithm != NULL)
        {
            EVP_CIPHER_CTX_init(&(mContext));
            if (EVP_PBE_CipherInit(mAlgorithm->algorithm, (const char *)mKey, mKeyLen,
                                   mAlgorithm->parameter, &(mContext), (int)direction))
            {
                int blockSize = EVP_CIPHER_CTX_block_size(&mContext);
                int allocLen = mDataLen + mHeaderLen + blockSize + 1; // plus 1 for null terminator on decrypt
                mResults = (unsigned char *)OPENSSL_malloc(allocLen);
                if (mResults == NULL)
                {
                    OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not allocate cryption buffer(size=%d)",
                                  allocLen);
                }
                else
                {
                    retval = OS_SUCCESS;
                }
            }
            else
            {
                OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not initialize cipher");
            }
        }
        else
        {
            OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not initialize cryption algorithm");
        }
    }
    else
    {
        OsSysLog::add(FAC_AUTH, PRI_ERR, "No encryption key(%d) or data(%d) set.\n",
            mKeyLen, mDataLen);
    }
#endif

    return retval;
}
예제 #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;

}
예제 #4
0
int
cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
    int en_de)
{
	CMS_EncryptedContentInfo *ec;
	CMS_PasswordRecipientInfo *pwri;
	const unsigned char *p = NULL;
	int plen;
	int r = 0;
	X509_ALGOR *algtmp, *kekalg = NULL;
	EVP_CIPHER_CTX kekctx;
	const EVP_CIPHER *kekcipher;
	unsigned char *key = NULL;
	size_t keylen;

	ec = cms->d.envelopedData->encryptedContentInfo;

	pwri = ri->d.pwri;
	EVP_CIPHER_CTX_init(&kekctx);

	if (!pwri->pass) {
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
		return 0;
	}
	algtmp = pwri->keyEncryptionAlgorithm;

	if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
		    CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
		return 0;
	}

	if (algtmp->parameter->type == V_ASN1_SEQUENCE) {
		p = algtmp->parameter->value.sequence->data;
		plen = algtmp->parameter->value.sequence->length;
		kekalg = d2i_X509_ALGOR(NULL, &p, plen);
	}
	if (kekalg == NULL) {
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
		    CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
		return 0;
	}

	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);

	if (!kekcipher) {
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
		    CMS_R_UNKNOWN_CIPHER);
		goto err;
	}

	/* Fixup cipher based on AlgorithmIdentifier to set IV etc */
	if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
		goto err;
	EVP_CIPHER_CTX_set_padding(&kekctx, 0);
	if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) {
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
		    CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
		goto err;
	}

	algtmp = pwri->keyDerivationAlgorithm;

	/* Finish password based key derivation to setup key in "ctx" */

	if (EVP_PBE_CipherInit(algtmp->algorithm,
	    (char *)pwri->pass, pwri->passlen,
	    algtmp->parameter, &kekctx, en_de) < 0) {
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
		goto err;
	}

	/* Finally wrap/unwrap the key */

	if (en_de) {

		if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
			goto err;

		key = malloc(keylen);

		if (!key)
			goto err;

		if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
			goto err;
		pwri->encryptedKey->data = key;
		pwri->encryptedKey->length = keylen;
	} else {
		key = malloc(pwri->encryptedKey->length);

		if (!key) {
			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
			    ERR_R_MALLOC_FAILURE);
			goto err;
		}
		if (!kek_unwrap_key(key, &keylen,
		    pwri->encryptedKey->data,
		    pwri->encryptedKey->length, &kekctx)) {
			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
			    CMS_R_UNWRAP_FAILURE);
			goto err;
		}

		ec->key = key;
		ec->keylen = keylen;

	}

	r = 1;

err:
	EVP_CIPHER_CTX_cleanup(&kekctx);
	if (!r && key)
		free(key);
	X509_ALGOR_free(kekalg);

	return r;
}