Example #1
0
void openssl_evp_asycrypt()
{
	RSA *rkey;
	BIGNUM *bne;
	EVP_PKEY *pubkey[2];
	EVP_CIPHER_CTX ctx1, ctx2;
	int i, ekl[2], len1 = 0, len2 = 0, len3 = 0;
	unsigned char ins[] = "openssl asymmetric encrypt test";
	unsigned char iv[8], pen[MAX1_LEN], *ek[2], sde[MAX1_LEN];

	ek[0] = (unsigned char *)malloc(MAX1_LEN);
	ek[1] = (unsigned char *)malloc(MAX1_LEN);
	memset(pen, 0, MAX1_LEN);
	memset(sde, 0, MAX1_LEN);
	memset(ek[0], 0, MAX1_LEN);
	memset(ek[1], 0, MAX1_LEN);

	bne = BN_new();
	BN_set_word(bne, RSA_3);
	rkey = RSA_new();
	RSA_generate_key_ex(rkey, MAX1_LEN, bne, NULL);
	pubkey[0] = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(pubkey[0], rkey);

	EVP_CIPHER_CTX_init(&ctx1);
	EVP_SealInit(&ctx1, EVP_des_ede3_cbc(), ek, ekl, iv, pubkey, 1);
	EVP_SealUpdate(&ctx1, pen, &len1, ins, strlen((char *)ins));
	EVP_SealFinal(&ctx1, pen + len1, &len3);
	len1 += len3;
	printf("\nEVP_ASYEncry(%s) = ", ins);
	for (i = 0; i < len1; i++)
		printf("0x%.02x ", pen[i]);
	printf("\n");
	EVP_CIPHER_CTX_cleanup(&ctx1);

	len3 = 0;
	EVP_CIPHER_CTX_init(&ctx2);
	EVP_OpenInit(&ctx2, EVP_des_ede3_cbc(), ek[0], ekl[0], iv, pubkey[0]);
	EVP_OpenUpdate(&ctx2, sde, &len2, pen, len1);
	EVP_OpenFinal(&ctx2, sde + len2, &len3);
	len2 += len3;
	printf("EVP_ASYDecry(");
	for (i = 0; i < len1; i++)
		printf("0x%.02x ", pen[i]);
	printf(") = %s\n", sde);
	EVP_CIPHER_CTX_cleanup(&ctx2);

	free(ek[0]);
	free(ek[1]);
	EVP_PKEY_free(pubkey[0]);
	BN_free(bne);
}
Example #2
0
/* {{{ proto opendata openssl_open(string data, string ekey, mixed privkey, [, cipher enc|string md_alg=RC4])
   Opens data */
LUA_API LUA_FUNCTION(openssl_open)
{
    size_t data_len, ekey_len;
    const char * data = luaL_checklstring(L, 1, &data_len);
    const char * ekey = luaL_checklstring(L, 2, &ekey_len);
    EVP_PKEY *pkey =  CHECK_OBJECT(3,EVP_PKEY, "openssl.evp_pkey");
    int top = lua_gettop(L);

    int len1, len2 = 0;
    unsigned char *buf;

    EVP_CIPHER_CTX ctx;
    const EVP_CIPHER *cipher = NULL;

    if(top>3) {
        if(lua_isstring(L,4))
            cipher = EVP_get_cipherbyname(lua_tostring(L,4));
        else if(lua_isuserdata(L,4))
            cipher = CHECK_OBJECT(4,EVP_CIPHER,"openssl.evp_cipher");
        else
            luaL_error(L, "#4 argument must be nil, string, or openssl.evp_cipher object");
    }
    if(!cipher)
        cipher = EVP_rc4();

    len1 = data_len + 1;
    buf = malloc(len1);

    if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len))
    {
        len2 = data_len - len1;
        if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0))
        {
            luaL_error(L,"EVP_OpenFinal() failed.");
            free(buf);
            return 0;
        }
    }
    else
    {
        luaL_error(L,"EVP_OpenInit() failed.");
        free(buf);
        return 0;
    }

    buf[len1 + len2] = '\0';
    lua_pushlstring(L, (const char*)buf, len1 + len2);
    free(buf);
    return 1;
}
Example #3
0
void openssl_evp_rsacripher()
{
	RSA *rkey;
	BIGNUM *bne;
	EVP_PKEY *pubkey[2];
	const EVP_CIPHER *type;
	EVP_CIPHER_CTX ctx1, ctx2;
	int i, ekl[2], total = 0, len1 = 0, len2 = 0;
	const unsigned char ins[COMM_LEN] = "openssl evp";
	unsigned char outs[LINE_LEN], iv[8], *ek[2], de[LINE_LEN];

	bne = BN_new();
	BN_set_word(bne, RSA_3);
	rkey = RSA_new();
	RSA_generate_key_ex(rkey, MAX1_LEN, bne, NULL);
	pubkey[0] = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(pubkey[0], rkey);
	type = EVP_des_cbc();

	ek[0] = malloc(LINE_LEN);
	ek[1] = malloc(LINE_LEN);
	EVP_CIPHER_CTX_init(&ctx1);
	EVP_SealInit(&ctx1, type, ek, ekl, iv, pubkey, 1);
	EVP_SealUpdate(&ctx1, outs, &total, ins, 11);
	EVP_SealFinal(&ctx1, outs + total, &len1);
	total += len1;
	printf("\nEVP_RSASEAL(%s) = ", ins);
	for (i = 0; i < total; i++)
		printf("0x%.02x ", outs[i]);
	EVP_CIPHER_CTX_cleanup(&ctx1);
	
	memset(de, 0, LINE_LEN);
	EVP_CIPHER_CTX_init(&ctx2);
	EVP_OpenInit(&ctx2, EVP_des_cbc(), ek[0], ekl[0], iv, pubkey[0]);
	EVP_OpenUpdate(&ctx2, de, &len2, outs, total);
	EVP_OpenFinal(&ctx2, de + len2, &len1);
	len2 += len1;
	printf("= %s\n", de);
	EVP_CIPHER_CTX_cleanup(&ctx2);

	free(ek[0]);
	free(ek[1]);
	EVP_PKEY_free(pubkey[0]);
	BN_free(bne);
}
Example #4
0
static int test_EVP_Enveloped(void)
{
    int ret = 0;
    EVP_CIPHER_CTX *ctx = NULL;
    EVP_PKEY *keypair = NULL;
    unsigned char *kek = NULL;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    static const unsigned char msg[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int len, kek_len, ciphertext_len, plaintext_len;
    unsigned char ciphertext[32], plaintext[16];
    const EVP_CIPHER *type = EVP_aes_256_cbc();

    if (!TEST_ptr(keypair = load_example_rsa_key())
            || !TEST_ptr(kek = OPENSSL_zalloc(EVP_PKEY_size(keypair)))
            || !TEST_ptr(ctx = EVP_CIPHER_CTX_new())
            || !TEST_true(EVP_SealInit(ctx, type, &kek, &kek_len, iv,
                                       &keypair, 1))
            || !TEST_true(EVP_SealUpdate(ctx, ciphertext, &ciphertext_len,
                                         msg, sizeof(msg)))
            || !TEST_true(EVP_SealFinal(ctx, ciphertext + ciphertext_len,
                                        &len)))
        goto err;

    ciphertext_len += len;

    if (!TEST_true(EVP_OpenInit(ctx, type, kek, kek_len, iv, keypair))
            || !TEST_true(EVP_OpenUpdate(ctx, plaintext, &plaintext_len,
                                         ciphertext, ciphertext_len))
            || !TEST_true(EVP_OpenFinal(ctx, plaintext + plaintext_len, &len)))
        goto err;

    plaintext_len += len;
    if (!TEST_mem_eq(msg, sizeof(msg), plaintext, plaintext_len))
        goto err;

    ret = 1;
err:
    OPENSSL_free(kek);
    EVP_PKEY_free(keypair);
    EVP_CIPHER_CTX_free(ctx);
    return ret;
}
Example #5
0
/// 使用加密密钥和初始向量解开数字信封,得到明文
int do_unseal(const EVP_CIPHER * cipher,
			  unsigned char * ebuf,int ebuflen,
			  unsigned char * iv,
			  unsigned char * kbuf,int klen,
			  unsigned char * dbuf,int * dlen)
{
    EVP_CIPHER_CTX ectx;
	unsigned char *ekey[1]; 
	int tmp_len;
	int ret = 0;
	int fd;

	ekey[0] = NULL;

	if (!g_prv_key)
		return ERR_ENV_KEY_INVALID;

	EVP_CIPHER_CTX_init(&ectx);

	do{
		ekey[0] = _alloca(klen);
		if(ekey[0] == NULL)
		{
			ret = ERR_ENV_MEMORY;
			break;
		}
		
		memcpy(ekey[0],kbuf,klen);

		if(1 != EVP_OpenInit(&ectx,cipher,ekey[0],klen,iv,g_prv_key)) 
		{
		/*
			if(ebuflen == 24)
			{
				fd = open("/hqdata/24err.ek",O_RDWR|O_CREAT|O_TRUNC);
				write(fd,kbuf,klen);
				close(fd);
			}
			if(ebuflen == 32)
			{
				fd = open("/hqdata/32err.ek",O_RDWR|O_CREAT|O_TRUNC);
				write(fd,kbuf,klen);
				close(fd);
			}
		*/	
			printf("EVP_OpenInit err!\n");
			ret = ERR_ENV_DECRYPT_FAILED;
			break; 	
		}
/*
			if(ebuflen == 24)
			{
				fd = open("/hqdata/24noerr.ek",O_RDWR|O_CREAT|O_TRUNC);
				write(fd,kbuf,klen);
				close(fd);
			}
			if(ebuflen == 32)
			{
				fd = open("/hqdata/32noerr.ek",O_RDWR|O_CREAT|O_TRUNC);
				write(fd,kbuf,klen);
				close(fd);
			}
*/		
		*dlen = 0; 
		if(1 != EVP_OpenUpdate(&ectx, dbuf + *dlen, &tmp_len, ebuf, ebuflen))
		{
			printf("EVP_OpenUpdate err!\n");
			ret = ERR_ENV_DECRYPT_FAILED;
			break;
		}

		*dlen = *dlen + tmp_len;    
		if(1 != EVP_OpenFinal(&ectx, dbuf+*dlen,&tmp_len)) 
		{
			printf("EVP_OpenFinal err!\n");
			ret = ERR_ENV_DECRYPT_FAILED;
			break;
		}

		*dlen = *dlen + tmp_len;
		dbuf[*dlen] = 0x0;  		
	}while(0);

	EVP_CIPHER_CTX_cleanup(&ectx);
	return ret;
}
bool OTEnvelope::Open(const OTPseudonym & theRecipient, OTString & theContents)
{
	bool retval = false;
	
    EVP_CIPHER_CTX	ctx;

    unsigned char	buffer[4096];
    unsigned char	buffer_out[4096 + EVP_MAX_IV_LENGTH];
    unsigned char	iv[EVP_MAX_IV_LENGTH];

    size_t			len = 0;
    int				len_out = 0;
    
	unsigned char *	ek = NULL;
    int				eklen = 0;
    uint32_t		eklen_n = 0;
	
	memset(buffer, 0, 4096);
	memset(buffer_out, 0, 4096 + EVP_MAX_IV_LENGTH);
	memset(iv, 0, EVP_MAX_IV_LENGTH);

	OTAsymmetricKey &	privateKey	= (OTAsymmetricKey &)theRecipient.GetPrivateKey();
	EVP_PKEY *			pkey		= (EVP_PKEY *)privateKey.GetKey();
	
	if (NULL == pkey)
	{
		OTLog::Error("Null private key in OTEnvelope::Open\n");
		return false;
	}
		
	EVP_CIPHER_CTX_init(&ctx);
    ek = (unsigned char*)malloc(EVP_PKEY_size(pkey));  // I assume this is for the AES key
	
	OT_ASSERT(NULL != ek);
	
	memset(ek, 0, EVP_PKEY_size(pkey));

	eklen = EVP_PKEY_size(pkey);
	
	
	//int EVP_OpenInit(EVP_CIPHER_CTX *ctx,
	//EVP_CIPHER *type,
	//unsigned char *ek, 
	//int ekl,
	//unsigned char *iv,
	//EVP_PKEY *priv);
	
	//EVP_OpenInit() initializes a cipher context ctx for decryption with cipher type. It decrypts the encrypted 
	//	symmetric key of length ekl bytes passed in the ek parameter using the private key priv. The IV is supplied 
	//	in the iv parameter.
		

	theContents.Release();	// This is where we'll put the decrypted data.
	m_dataContents.reset(); // reset the fread position on this object.
	
	int nReadLength = 0;
	int nReadKey = 0;
	int nReadIV = 0;
	
	// First we read the encrypted key size.
	if (0 == (nReadLength = m_dataContents.OTfread((char*)&eklen_n, sizeof(eklen_n))))
	{
		OTLog::Error("Error reading encrypted key size in OTEnvelope::Open\n");
		free(ek); ek = NULL;
		return false;
	}
	
	// convert it from network to host endian.
	eklen = ntohl(eklen_n);
	
	// Next we read the encrypted key itself.
	if (0 == (nReadKey = m_dataContents.OTfread((char*)ek, eklen)))
	{
		OTLog::Error("Error reading encrypted key size in OTEnvelope::Open\n");
		free(ek); ek = NULL;
		return false;
	}
	
	// Next we read the initialization vector.
	if (0 == (nReadIV = m_dataContents.OTfread((char*)iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()))))
	{
		OTLog::Error("Error reading initialization vector in OTEnvelope::Open\n");
		free(ek); ek = NULL;
		return false;
	}
	
	OTData ciphertext((const void*)((unsigned char *)m_dataContents.GetPointer() + nReadLength + nReadKey + nReadIV), 
					  m_dataContents.GetSize() - nReadLength - nReadKey - nReadIV);
	
	
	
	// Now we process ciphertext and write the decrypted data to plaintext.
	OTData plaintext;

	if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv, pkey))
    {
        OTLog::Error("EVP_OpenInit: failed.\n");
		free(ek); ek = NULL;
		return false;
    }
		
    while ((len = ciphertext.OTfread((char*)buffer, sizeof(buffer))) > 0)
    {
        if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer, len))
        {
            OTLog::Error("EVP_OpenUpdate: failed.\n");
			free(ek); ek = NULL;
			return false;
        }
		
		OTData dataOpenUpdate(buffer_out, len_out);
		plaintext += dataOpenUpdate;
	}
	
    if (!EVP_OpenFinal(&ctx, buffer_out, &len_out))
    {
		OTLog::Error("EVP_OpenFinal: failed.\n");
 		free(ek); ek = NULL;
		return false;
    }
	
	OTData dataOpenFinal(buffer_out, len_out);
	plaintext += dataOpenFinal;
	
	// Make sure it's null terminated
	int nIndex = plaintext.GetSize()-1;
	((unsigned char*)plaintext.GetPointer())[nIndex] = 0;
	
	// Set it into theContents (to return the plaintext to the caller)
	theContents.Set((const char *)plaintext.GetPointer());
	
	retval = true;
	
    free(ek); ek = NULL;
	
    return retval;
	
}
Example #7
0
void main_decrypt(void)
{
	char buf[512];
	char ebuf[512];
	unsigned int buflen;
        EVP_CIPHER_CTX ectx;
        unsigned char iv[8];
	unsigned char *encryptKey; 
	unsigned int ekeylen; 
	EVP_PKEY *privateKey;

	memset(iv, '\0', sizeof(iv));

	privateKey = ReadPrivateKey(PRIVFILE);
	if (!privateKey)
	{
		fprintf(stderr, "Error: can't load private key");
		exit(1);	
	}

     	read(STDIN, &ekeylen, sizeof(ekeylen));
	ekeylen = ntohl(ekeylen);

	if (ekeylen != EVP_PKEY_size(privateKey))
	{
        	EVP_PKEY_free(privateKey);
		fprintf(stderr, "keylength mismatch");
		exit(1);	
	}

	encryptKey = malloc(sizeof(char) * ekeylen);
	if (!encryptKey)
	{
        	EVP_PKEY_free(privateKey);
		perror("malloc");
		exit(1);
	}

	read(STDIN, encryptKey, ekeylen);
	read(STDIN, iv, sizeof(iv));

	EVP_OpenInit(&ectx,
		   EVP_des_ede3_cbc(), 
		   encryptKey,
		   ekeylen,
		   iv,
		   privateKey); 	

	while(1)
	{
		int readlen = read(STDIN, ebuf, sizeof(ebuf));

		if (readlen <= 0)
		{
			if (readlen < 0)
				perror("read");

			break;
		}

		EVP_OpenUpdate(&ectx, buf, &buflen, ebuf, readlen);

		write(STDOUT, buf, buflen);
	}

        EVP_OpenFinal(&ectx, buf, &buflen);

	write(STDOUT, buf, buflen);

        EVP_PKEY_free(privateKey);
	free(encryptKey);
}
Example #8
0
uint8_t* decrypt(const char* keypath, const uint8_t* c, const size_t clen, size_t* plen, uint8_t* iv, uint8_t* ek, size_t ekl){
    // Context and key
    EVP_CIPHER_CTX *decctx;
    FILE* dkeyfh;
    EVP_PKEY *dkey=NULL;

    // Return codes and errors
    unsigned long decerr;

    /* The buffer with the plaintext */
    uint8_t* p;

    /* envelope related */
    int outl;
	int plenint;
    const EVP_CIPHER* type = EVP_aes_256_cbc();

    /*
     * Open a private key for decryption
     */
    dkeyfh = fopen(keypath,"r");
    if (!dkeyfh)
    {
        fprintf(stderr, "%s: Cannot open key file\n", __func__);
        p = NULL;
        goto exit_decrypt;
    }
    dkey = PEM_read_PrivateKey(dkeyfh, &dkey, NULL, NULL);
    if (!dkey){
        fprintf(stderr,"Cannot read decryption key from file %s\n", keypath);
        p = NULL;
        fclose(dkeyfh);
        goto exit_decrypt;
    }

    decctx = malloc(sizeof(EVP_CIPHER_CTX));
    if (decctx == NULL)
    {
        fprintf(stderr, "%s: Out of memory\n", __func__);
        p = NULL;
        fclose(dkeyfh);
        goto exit_decrypt;
    }
    EVP_CIPHER_CTX_init(decctx);
    if (!decctx){
        fprintf(stderr,"Cannot initialize an decryption context\n");
        p = NULL;
        goto cleanup_decrypt;
    }

    p = malloc(clen + EVP_CIPHER_block_size(type));
    if (p == NULL)
    {
        fprintf(stderr,"%s: Out of memory\n", __func__);
        goto cleanup_decrypt;
    }

    if (EVP_OpenInit(decctx, type, ek, ekl, iv, dkey) != 1){
        ERR_load_crypto_strings();
        decerr = ERR_get_error();
        fprintf(stderr,"Decrypt failed\n");
        printf("%s\n", ERR_error_string(decerr, NULL));
        ERR_free_strings();
        p = NULL;
        goto cleanup_decrypt;
    }

    if (EVP_OpenUpdate( decctx, p, &plenint, c, clen) != 1){
        ERR_load_crypto_strings();
        decerr = ERR_get_error();
        fprintf(stderr,"Decrypt failed\n");
        printf("%s\n", ERR_error_string(decerr, NULL));
        ERR_free_strings();
        p = NULL;
        goto cleanup_decrypt;
    }

    if(EVP_OpenFinal(decctx, p, &outl) != 1){
        ERR_load_crypto_strings();
        decerr = ERR_get_error();
        fprintf(stderr,"Decrypt failed\n");
        printf("%s\n", ERR_error_string(decerr, NULL));
        ERR_free_strings();
        p = NULL;
    }
    *plen = outl + plenint;

    cleanup_decrypt:
    EVP_CIPHER_CTX_cleanup(decctx);
    free(decctx);
    EVP_PKEY_free(dkey);

    exit_decrypt:
    return p;
}
Example #9
0
unsigned char *rsa_decrypt(unsigned char *ciphertext, int *len)
{

    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_PKEY *pkey;
    unsigned char *encrypted_key;
    unsigned int encrypted_key_length;
    uint32_t eklen_n;
    unsigned char iv[EVP_MAX_IV_LENGTH];


    pkey = load_privkey("private.pem");
    encrypted_key = malloc(EVP_PKEY_size(pkey));

    // plaintext will always be equal to or lesser than length of ciphertext
    int plaintext_len = *len;

    // the length of ciphertest is at most plaintext + ciphers block size.
    int ciphertext_len = plaintext_len + EVP_CIPHER_block_size(EVP_des_ede_cbc());

    unsigned char *plaintext = (unsigned char *)malloc(ciphertext_len);

    /* First need to fetch the encrypted key length, encrypted key and IV */
    int pos = 0;
    memcpy(&eklen_n, ciphertext + pos, sizeof(eklen_n));
    pos += sizeof(eklen_n);

    encrypted_key_length = ntohl(eklen_n);

    memcpy(encrypted_key, ciphertext + pos, encrypted_key_length);
    pos += encrypted_key_length;

    memcpy(iv, ciphertext + pos, EVP_CIPHER_iv_length(EVP_des_ede_cbc()));
    pos += EVP_CIPHER_iv_length(EVP_des_ede_cbc());

    // Now we have our encrypted_key and the iv we can decrypt the reamining
    // data
    if (!EVP_OpenInit(&ctx, EVP_des_ede_cbc(), encrypted_key, encrypted_key_length, iv, pkey))
    {
        fprintf(stderr, "EVP_OpenInit: failed.\n");
        goto out_free;
    }

    if (!EVP_OpenUpdate(&ctx, plaintext, &plaintext_len, ciphertext + pos, ciphertext_len))
    {
        fprintf(stderr, "EVP_OpenUpdate: failed.\n");
        goto out_free;
    }

    int total_len = plaintext_len;

    if (!EVP_OpenFinal(&ctx, plaintext + total_len, &plaintext_len))
    {
        fprintf(stderr, "EVP_OpenFinal warning: failed.\n");
    }


out_free:
    EVP_PKEY_free(pkey);
    free(encrypted_key);

    EVP_CIPHER_CTX_cleanup(&ctx);

    *len = plaintext_len + total_len;
    return  plaintext;

}
Example #10
0
/*
* RSA public decryption function.
* Dencrypt 'in_len' bytes from 'envelope' buffer with the private key contained in 'priv_key_file' 
* Parameter 'outlen' is the size of output buffer 
* It returns the received plaintext or NULL if an error occurs.
*/
unsigned char* asym_decrypt(unsigned char* envelope, int in_len, int* out_len, char* priv_key_file){
	EVP_PKEY* priv_key;
	int ret;	
	EVP_CIPHER_CTX* ctx;
	unsigned char* encrypted_key;
	int encrypted_key_len;
	unsigned char* iv;
	int iv_len;
	unsigned char* ciphertext;
	int ciphertext_len;
	unsigned char* output;
	int output_len;
	int app;
	
		
	if(ciphertext == NULL || in_len < 0 || out_len == NULL || priv_key_file == NULL)
		return NULL;
	
	//Reads the receiver's public key for its file
	priv_key = read_priv_key(priv_key_file);
	
	//Note: envelope format -> <IV><Dim_Key><Ecrypt_KEY><Ciphertext>
	
	//Set to the head the iv pointer
	iv = envelope;
	iv_len = EVP_CIPHER_iv_length(SYM_CIPHER);
	
	//Read from the envelop the encrypted_key_len
	memcpy(&encrypted_key_len, envelope + iv_len, sizeof(int));
	
	//Set the encrypted_key pointer
	encrypted_key = envelope + iv_len + sizeof(int);
	
	//Set the ciphertext pointer
	ciphertext = envelope + iv_len + sizeof(int) + encrypted_key_len;
	ciphertext_len = in_len - iv_len - sizeof(int) - encrypted_key_len;
	
	//Instantiate and initialize the context
	ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
	EVP_CIPHER_CTX_init(ctx);
	ret = EVP_OpenInit(ctx, SYM_CIPHER, encrypted_key, encrypted_key_len, iv, priv_key);
	if(ret == 0)
		goto error;
	
	//Decrypt the ciphertext
	output_len = ciphertext_len;
	output = malloc(output_len);
	output_len = 0;
	ret = EVP_OpenUpdate(ctx, output, &app, ciphertext, ciphertext_len);
	if(ret == 0)
		goto error;
		
	output_len += app;
	ret = EVP_OpenFinal(ctx, output + app, &app);
	if(ret == 0)
		goto error;
	output_len += app;
	
	*out_len = output_len;
	
	//Cleanup	
	EVP_CIPHER_CTX_cleanup(ctx);
   	free(ctx);
	free(priv_key);
	
	return output;
error:
	if(ctx != NULL){
		EVP_CIPHER_CTX_cleanup(ctx);
   		free(ctx);
	}
	if(encrypted_key != NULL)
		free(ciphertext);	
	if(priv_key != NULL)
		free(priv_key);
	if(iv != NULL)		
		free(iv);
	if(ciphertext != NULL)
		free(ciphertext);		
	if(output != NULL)
		free(output);
	return NULL;
	
}
Example #11
0
/** Decrypt some data.
 *  \param key Key to use for decryption.  Use gale_crypto_target() to find the
 *         keys you can use, pick one you own, and supply private key data.
 *  \param data Encrypted group.  Will be replaced by decrypted group.
 *  \return Nonzero iff the operation succeeded.
 *  \sa gale_crypto_seal(), gale_crypto_target() */
int gale_crypto_open(struct gale_group key,struct gale_group *cipher) {
	struct gale_fragment frag;
	struct gale_data data;
	unsigned char iv[IV_LEN];
	u32 i,key_count;
	EVP_PKEY *private_key = NULL;
	RSA *rsa;
	struct gale_text raw_name;
	struct gale_data session_key,plain;
	EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
	int length,is_successful = 0;

	if (gale_group_null(*cipher)) goto cleanup;
	frag = gale_group_first(*cipher);
	if (gale_text_compare(G_("security/encryption"),frag.name)
	||  frag_data != frag.type) {
		gale_alert(GALE_WARNING,G_("can't decrypt unencrypted data"),0);
		goto cleanup;
	}

	data = frag.value.data;
	if (!gale_unpack_compare(&data,magic2,sizeof(magic2))
	||  !gale_unpack_copy(&data,iv,sizeof(iv))
	||  !gale_unpack_u32(&data,&key_count)) goto cleanup;

	private_key = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(private_key,RSA_new());
	rsa = EVP_PKEY_get0_RSA(private_key);
	raw_name = key_i_swizzle(crypto_i_rsa(key,rsa));
	if (!crypto_i_private_valid(rsa)) {
		gale_alert(GALE_WARNING,G_("invalid private key"),0);
		goto cleanup;
	}

	session_key = null_data;
	for (i = 0; i < key_count; ++i) {
		struct gale_text name;
		if (!gale_unpack_text(&data,&name)) goto cleanup;
		if (gale_text_compare(raw_name,name)) {
			if (!gale_unpack_skip(&data)) goto cleanup;
			continue;
		}

		if (!gale_unpack_u32(&data,&session_key.l)) goto cleanup;
		session_key.p = gale_malloc(session_key.l);
		if (!gale_unpack_copy(&data,session_key.p,session_key.l)) 
			goto cleanup;
	}

	if (0 == session_key.l) {
		gale_alert(GALE_WARNING,G_("key doesn't fit encrypted data"),0);
		goto cleanup;
	}

	if (!EVP_OpenInit(context,EVP_des_ede3_cbc(),
		session_key.p,session_key.l,iv,private_key)) {
		crypto_i_error();
		goto cleanup;
	}

	plain.p = gale_malloc(data.l);
	plain.l = 0;

	EVP_OpenUpdate(context,plain.p + plain.l,&length,data.p,data.l);
	plain.l += length;
	EVP_OpenFinal(context,plain.p + plain.l,&length);
	plain.l += length;

	if (!gale_unpack_u32(&plain,&i) || 0 != i
	||  !gale_unpack_group(&plain,cipher)) {
		gale_alert(GALE_WARNING,G_("invalid encrypted data"),0);
		goto cleanup;
	}

	is_successful = 1;
cleanup:
	if (NULL != private_key) EVP_PKEY_free(private_key);
	return is_successful;
}