コード例 #1
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_boolean_t wi_cipher_decrypt_bytes(wi_cipher_t *cipher, const void *encrypted_buffer, wi_uinteger_t encrypted_length, void **out_buffer, wi_uinteger_t *out_length) {
	void		*decrypted_buffer;
	int			decrypted_length, padded_length;
	
	decrypted_buffer = wi_malloc(encrypted_length + EVP_CIPHER_block_size(cipher->cipher));
	
	if(EVP_DecryptUpdate(&cipher->decrypt_ctx, decrypted_buffer, &decrypted_length, encrypted_buffer, encrypted_length) != 1) {
		wi_error_set_openssl_error();
		
		wi_free(decrypted_buffer);
		
		return false;
	}
	
	if(EVP_DecryptFinal_ex(&cipher->decrypt_ctx, decrypted_buffer + decrypted_length, &padded_length) != 1) {
		wi_error_set_openssl_error();
		
		wi_free(decrypted_buffer);
		
		return false;
	}
	
	if(EVP_DecryptInit_ex(&cipher->decrypt_ctx, NULL, NULL, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_free(decrypted_buffer);
		
		return false;
	}
	
	*out_buffer = decrypted_buffer;
	*out_length = decrypted_length + padded_length;
	
	return true;
}
コード例 #2
0
ファイル: wi-error.c プロジェクト: asvitkine/phxd
void wi_error_set_openssl_ssl_error_with_result(void *ssl, int result) {
	wi_error_t		*error;
	int				code;
	
	code = SSL_get_error(ssl, result);
	
	if(code == SSL_ERROR_SYSCALL) {
		if(ERR_peek_error() == 0) {
			if(result == 0)
				wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
			else
				wi_error_set_errno(errno);
		} else {
			wi_error_set_openssl_error();
		}
	}
	else if(code == SSL_ERROR_SSL) {
		wi_error_set_openssl_error();
	} else {
		error = _wi_error_get_error();
		error->domain = WI_ERROR_DOMAIN_OPENSSL_SSL;
		error->code = code;

		wi_release(error->string);

		switch(error->code) {
			case SSL_ERROR_NONE:
				error->string = wi_retain(WI_STR("SSL: No error"));
				break;

			case SSL_ERROR_ZERO_RETURN:
				error->string = wi_retain(WI_STR("SSL: Zero return"));
				break;
				
			case SSL_ERROR_WANT_READ:
				error->string = wi_retain(WI_STR("SSL: Want read"));
				break;
				
			case SSL_ERROR_WANT_WRITE:
				error->string = wi_retain(WI_STR("SSL: Want write"));
				break;
				
			case SSL_ERROR_WANT_CONNECT:
				error->string = wi_retain(WI_STR("SSL: Want connect"));
				break;
				
			case SSL_ERROR_WANT_ACCEPT:
				error->string = wi_retain(WI_STR("SSL: Want accept"));
				break;
				
			case SSL_ERROR_WANT_X509_LOOKUP:
				error->string = wi_retain(WI_STR("SSL: Want X509 lookup"));
				break;
		}
	}
	
	ERR_clear_error();
}
コード例 #3
0
ファイル: wi-error.c プロジェクト: balr0g/libwired-old
void wi_error_set_openssl_ssl_error_with_result(void *ssl, int result) {
	wi_string_t		*string;
	int				code;
	
	code = SSL_get_error(ssl, result);
	
	if(code == SSL_ERROR_SYSCALL) {
		if(ERR_peek_error() == 0) {
			if(result == 0)
				wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
			else
				wi_error_set_errno(errno);
		} else {
			wi_error_set_openssl_error();
		}
	}
	else if(code == SSL_ERROR_SSL) {
		wi_error_set_openssl_error();
	} else {
		switch(code) {
			case SSL_ERROR_NONE:
				string = WI_STR("SSL: No error");
				break;

			case SSL_ERROR_ZERO_RETURN:
				string = WI_STR("SSL: Zero return");
				break;
				
			case SSL_ERROR_WANT_READ:
				string = WI_STR("SSL: Want read");
				break;
				
			case SSL_ERROR_WANT_WRITE:
				string = WI_STR("SSL: Want write");
				break;
				
			case SSL_ERROR_WANT_CONNECT:
				string = WI_STR("SSL: Want connect");
				break;
				
			case SSL_ERROR_WANT_ACCEPT:
				string = WI_STR("SSL: Want accept");
				break;
				
			case SSL_ERROR_WANT_X509_LOOKUP:
				string = WI_STR("SSL: Want X509 lookup");
				break;
			
			default:
				string = NULL;
				break;
		}
		
		wi_error_set_error_with_string(WI_ERROR_DOMAIN_OPENSSL_SSL, code, string);
	}
	
	ERR_clear_error();
}
コード例 #4
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_cipher_t * wi_cipher_init_with_key(wi_cipher_t *cipher, wi_cipher_type_t type, wi_data_t *key, wi_data_t *iv) {
	unsigned char		*key_buffer, *iv_buffer;
	
	cipher->type	= type;
	cipher->cipher	= _wi_cipher_cipher(cipher);
	
	key_buffer		= (unsigned char *) wi_data_bytes(key);
	iv_buffer		= iv ? (unsigned char *) wi_data_bytes(iv) : NULL;
	
	if(EVP_EncryptInit(&cipher->encrypt_ctx, cipher->cipher, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	if(EVP_DecryptInit(&cipher->decrypt_ctx, cipher->cipher, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	_wi_cipher_configure_cipher(cipher);

	if(EVP_EncryptInit(&cipher->encrypt_ctx, cipher->cipher, key_buffer, iv_buffer) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}

	if(EVP_DecryptInit(&cipher->decrypt_ctx, cipher->cipher, key_buffer, iv_buffer) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	cipher->key		= wi_retain(key);
	cipher->iv		= wi_retain(iv);

	return cipher;
}
コード例 #5
0
ファイル: wi-x509.c プロジェクト: ProfDrLuigi/zanka
wi_x509_t * wi_x509_init_with_pem_file(wi_x509_t *x509, wi_string_t *path) {
	FILE		*fp;
	
	fp = fopen(wi_string_cstring(path), "r");
	
	if(!fp) {
		wi_error_set_errno(errno);
		
		wi_release(x509);
		
		return NULL;
	}
	
	x509->x509 = PEM_read_X509(fp, NULL, NULL, NULL);
	
	fclose(fp);
	
	if(!x509->x509) {
		wi_error_set_openssl_error();
		
		wi_release(x509);
		
		return NULL;
	}
	
	return x509;
}
コード例 #6
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_rsa_t * wi_rsa_init_with_pem_file(wi_rsa_t *rsa, wi_string_t *path) {
	FILE		*fp;
	
	fp = fopen(wi_string_cstring(path), "r");
	
	if(!fp) {
		wi_error_set_errno(errno);
		
		wi_release(rsa);
		
		return NULL;
	}
	
	rsa->rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
	
	fclose(fp);
	
	if(!rsa->rsa) {
		wi_error_set_openssl_error();
		
		wi_release(rsa);
		
		return NULL;
	}
	
	return rsa;
}
コード例 #7
0
ファイル: wi-socket.c プロジェクト: ProfDrLuigi/zanka
wi_socket_tls_t * wi_socket_tls_init_with_type(wi_socket_tls_t *tls, wi_socket_tls_type_t type) {
	SSL_METHOD		*method;
	
	switch(type) {
		default:
		case WI_SOCKET_TLS_CLIENT:
			method = TLSv1_client_method();
			break;

		case WI_SOCKET_TLS_SERVER:
			method = TLSv1_server_method();
			break;
	}
	
	tls->ssl_ctx = SSL_CTX_new(method);
	
	if(!tls->ssl_ctx) {
		wi_error_set_openssl_error();
		
		wi_release(NULL);
		
		return NULL;
	}
	
	SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_AUTO_RETRY);
	SSL_CTX_set_quiet_shutdown(tls->ssl_ctx, 1);
	
	return tls;
}
コード例 #8
0
ファイル: wi-socket.c プロジェクト: ProfDrLuigi/zanka
wi_boolean_t wi_socket_tls_set_certificate(wi_socket_tls_t *tls, wi_x509_t *x509) {
	if(SSL_CTX_use_certificate(tls->ssl_ctx, wi_x509_x509(x509)) != 1) {
		wi_error_set_openssl_error();

		return false;
	}
	
	return true;
}
コード例 #9
0
ファイル: wi-socket.c プロジェクト: ProfDrLuigi/zanka
wi_rsa_t * wi_socket_ssl_public_key(wi_socket_t *socket) {
#ifdef HAVE_OPENSSL_SSL_H
	RSA			*rsa = NULL;
	X509		*x509 = NULL;
	EVP_PKEY	*pkey = NULL;

	x509 = SSL_get_peer_certificate(socket->ssl);

	if(!x509) {
		wi_error_set_openssl_error();
		
		goto end;
	}
	
	pkey = X509_get_pubkey(x509);
	
	if(!pkey) {
		wi_error_set_openssl_error();

		goto end;
	}
	
	rsa = EVP_PKEY_get1_RSA(pkey);
	
	if(!rsa)
		wi_error_set_openssl_error();

end:
	if(x509)
		X509_free(x509);
	
	if(pkey)
		EVP_PKEY_free(pkey);
	
	return wi_autorelease(wi_rsa_init_with_rsa(wi_rsa_alloc(), rsa));
#else
	return NULL;
#endif
}
コード例 #10
0
ファイル: wi-socket.c プロジェクト: ProfDrLuigi/zanka
wi_boolean_t wi_socket_tls_set_private_key(wi_socket_tls_t *tls, wi_rsa_t *rsa) {
	tls->private_key = false;
	
	if(SSL_CTX_use_RSAPrivateKey(tls->ssl_ctx, wi_rsa_rsa(rsa)) != 1) {
		wi_error_set_openssl_error();

		return false;
	}
	
	tls->private_key = true;
	
	return true;
}
コード例 #11
0
ファイル: wi-rsa.c プロジェクト: axelandersson/libwired
wi_rsa_t * wi_rsa_init_with_bits(wi_rsa_t *rsa, wi_uinteger_t size) {
    rsa->rsa = RSA_generate_key(size, RSA_F4, NULL, NULL);
    
    if(!rsa->rsa) {
        wi_error_set_openssl_error();
        
        wi_release(rsa);
        
        return NULL;
    }
    
    return rsa;
}
コード例 #12
0
ファイル: wi-socket.c プロジェクト: ProfDrLuigi/zanka
wi_boolean_t wi_socket_tls_set_dh(wi_socket_tls_t *tls, const unsigned char *p, size_t p_size, const unsigned char *g, size_t g_size) {
	tls->dh = DH_new();
	
	if(!tls->dh) {
		wi_error_set_openssl_error();

		return false;
	}

	tls->dh->p = BN_bin2bn(p, p_size, NULL);
	tls->dh->g = BN_bin2bn(g, g_size, NULL);

	if(!tls->dh->p || !tls->dh->g) {
		wi_error_set_openssl_error();

		DH_free(tls->dh);
		tls->dh = NULL;
		
		return false;
	}
	
	return true;
}
コード例 #13
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_boolean_t wi_rsa_decrypt_bytes(wi_rsa_t *rsa, const void *encrypted_buffer, wi_uinteger_t encrypted_length, void **out_buffer, wi_uinteger_t *out_length) {
	void		*decrypted_buffer;
	int32_t		decrypted_length;
	
	decrypted_buffer = wi_malloc(RSA_size(rsa->rsa));
	decrypted_length = RSA_private_decrypt(encrypted_length, encrypted_buffer, decrypted_buffer, rsa->rsa, RSA_PKCS1_PADDING);

	if(decrypted_length == -1) {
		wi_error_set_openssl_error();
		
		wi_free(decrypted_buffer);

		return false;
	}
	
	*out_buffer = decrypted_buffer;
	*out_length = decrypted_length;

	return true;
}
コード例 #14
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_data_t * wi_rsa_private_key(wi_rsa_t *rsa) {
	unsigned char	*buffer;
	int				length;

	if(!rsa->private_key) {
		buffer = NULL;
		length = i2d_RSAPrivateKey(rsa->rsa, &buffer);
		
		if(length <= 0) {
			wi_error_set_openssl_error();
			
			return NULL;
		}
		
		rsa->private_key = wi_data_init_with_bytes(wi_data_alloc(), buffer, length);

		OPENSSL_free(buffer);
	}
	
	return rsa->private_key;
}
コード例 #15
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_rsa_t * wi_rsa_init_with_public_key(wi_rsa_t *rsa, wi_data_t *data) {
	const unsigned char	*buffer;
	long				length;
	
	buffer = wi_data_bytes(data);
	length = wi_data_length(data);
	
	rsa->rsa = d2i_RSAPublicKey(NULL, (const unsigned char **) &buffer, length);

	if(!rsa->rsa) {
		wi_error_set_openssl_error();
		
		wi_release(rsa);
		
		return NULL;
	}
	
	rsa->public_key = wi_retain(data);
	
	return rsa;
}
コード例 #16
0
ファイル: wi-x509.c プロジェクト: ProfDrLuigi/zanka
wi_x509_t * wi_x509_init_with_common_name(wi_x509_t *x509, wi_rsa_t *rsa, wi_string_t *common_name) {
	X509_REQ		*req;
	EVP_PKEY		*pkey = NULL;
	X509_NAME		*name = NULL;
	BIGNUM			*bn = NULL;
	
	req = X509_REQ_new();
	
	if(!req)
		goto err;

	if(X509_REQ_set_version(req, 0) != 1)
		goto err;
	
	name = X509_NAME_new();
	
	if(X509_NAME_add_entry_by_NID(name,
								  NID_commonName,
								  MBSTRING_ASC,
								  (unsigned char *) wi_string_cstring(common_name),
								  -1,
								  -1,
								  0) != 1)
		goto err;

	if(X509_REQ_set_subject_name(req, name) != 1)
		goto err;

	pkey = EVP_PKEY_new();
	EVP_PKEY_set1_RSA(pkey, wi_rsa_rsa(rsa));
	
	if(X509_REQ_set_pubkey(req, pkey) != 1)
		goto err;
	
	x509->x509 = X509_new();
	
	if(!x509->x509)
		goto err;
	
	bn = BN_new();
	
	if(!bn)
		goto err;
	
	if(BN_pseudo_rand(bn, 64, 0, 0) != 1)
		goto err;
	
	if(!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(x509->x509)))
		goto err;
	
	if(X509_set_issuer_name(x509->x509, X509_REQ_get_subject_name(req)) != 1)
		goto err;

	if(!X509_gmtime_adj(X509_get_notBefore(x509->x509), 0))
		goto err;

	if(!X509_gmtime_adj(X509_get_notAfter(x509->x509), 3600 * 24 * 365))
		goto err;

	if(X509_set_subject_name(x509->x509, X509_REQ_get_subject_name(req)) != 1)
		goto end;

	if(X509_set_pubkey(x509->x509, pkey) != 1)
		goto err;
	
	if(X509_sign(x509->x509, pkey, EVP_sha1()) == 0)
		goto err;
	
	goto end;
	
err:
	wi_error_set_openssl_error();

	wi_release(x509);

	x509 = NULL;
	
end:
	if(req)
		X509_REQ_free(req);
	
	if(pkey)
		EVP_PKEY_free(pkey);
	
	if(name)
		X509_NAME_free(name);

	if(bn)
		BN_free(bn);
	
	return x509;
}
コード例 #17
0
ファイル: wi-cipher.c プロジェクト: ProfDrLuigi/zanka
wi_integer_t wi_cipher_decrypt_bytes(wi_cipher_t *cipher, const void *encrypted_buffer, wi_uinteger_t encrypted_length, void *decrypted_buffer) {
#ifdef WI_CIPHER_OPENSSL
	int			decrypted_length, padded_length;
	
	if(EVP_DecryptUpdate(&cipher->decrypt_ctx, decrypted_buffer, &decrypted_length, encrypted_buffer, encrypted_length) != 1) {
		wi_error_set_openssl_error();
		
		return -1;
	}
	
	if(EVP_DecryptFinal_ex(&cipher->decrypt_ctx, decrypted_buffer + decrypted_length, &padded_length) != 1) {
		wi_error_set_openssl_error();
		
		return -1;
	}
	
	if(EVP_DecryptInit_ex(&cipher->decrypt_ctx, NULL, NULL, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		return -1;
	}
	
	return decrypted_length + padded_length;
#endif

#ifdef WI_CIPHER_COMMONCRYPTO
	CCCryptorStatus		status;
	size_t				available_length, decrypted_length, padded_length;
	
	available_length = wi_cipher_block_size(cipher) + encrypted_length;
	
	status = CCCryptorUpdate(cipher->decrypt_ref,
							 encrypted_buffer,
							 encrypted_length,
							 decrypted_buffer,
							 available_length,
							 &decrypted_length);
	
	if(status != kCCSuccess) {
		wi_error_set_commoncrypto_error(status);
		
		return -1;
	}

	status = CCCryptorFinal(cipher->decrypt_ref,
							decrypted_buffer + decrypted_length,
							available_length - decrypted_length,
							&padded_length);
	
	if(status != kCCSuccess) {
		wi_error_set_commoncrypto_error(status);
		
		return -1;
	}
	
	status = CCCryptorReset(cipher->decrypt_ref, cipher->iv ? wi_data_bytes(cipher->iv) : NULL);
	
	if(status != kCCSuccess) {
		wi_error_set_commoncrypto_error(status);
		
		return -1;
	}
	
	return decrypted_length + padded_length;
#endif
}
コード例 #18
0
ファイル: wi-crypto.c プロジェクト: ProfDrLuigi/zanka
wi_cipher_t * wi_cipher_init_with_random_key(wi_cipher_t *cipher, wi_cipher_type_t type) {
	unsigned char		*key_buffer, *iv_buffer;
	int					key_length, iv_length;
	
	cipher->type	= type;
	cipher->cipher	= _wi_cipher_cipher(cipher);
	
	key_length		= EVP_MAX_KEY_LENGTH;
	key_buffer		= wi_malloc(key_length);
	iv_length		= EVP_CIPHER_iv_length(cipher->cipher);
	iv_buffer		= (iv_length > 0) ? wi_malloc(iv_length) : NULL;
	
	if(RAND_bytes(key_buffer, key_length) <= 0) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	if(iv_buffer) {
		if(RAND_bytes(iv_buffer, iv_length) <= 0) {
			wi_error_set_openssl_error();
			
			wi_release(cipher);
			
			return NULL;
		}
	}

	if(EVP_EncryptInit_ex(&cipher->encrypt_ctx, cipher->cipher, NULL, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	if(EVP_DecryptInit_ex(&cipher->decrypt_ctx, cipher->cipher, NULL, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	_wi_cipher_configure_cipher(cipher);

	if(EVP_EncryptInit_ex(&cipher->encrypt_ctx, cipher->cipher, NULL, key_buffer, iv_buffer) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}

	if(EVP_DecryptInit_ex(&cipher->decrypt_ctx, cipher->cipher, NULL, key_buffer, iv_buffer) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	cipher->key		= wi_data_init_with_bytes_no_copy(wi_data_alloc(), key_buffer, key_length, true);
	cipher->iv		= (iv_length > 0) ? wi_data_init_with_bytes_no_copy(wi_data_alloc(), iv_buffer, iv_length, true) : NULL;

	return cipher;
}
コード例 #19
0
ファイル: wi-socket.c プロジェクト: ProfDrLuigi/zanka
wi_boolean_t wi_socket_accept_tls(wi_socket_t *socket, wi_socket_tls_t *tls, wi_time_interval_t timeout) {
	wi_socket_state_t	state;
	int					err, result;
	wi_boolean_t		blocking;
	
	socket->ssl = SSL_new(tls->ssl_ctx);
	
	if(!socket->ssl) {
		wi_error_set_openssl_error();
		
		return false;
	}
	
	if(SSL_set_fd(socket->ssl, socket->sd) != 1) {
		wi_error_set_openssl_error();
		
		return false;
	}
	
	if(!tls->private_key && tls->dh) {
		if(SSL_set_tmp_dh(socket->ssl, tls->dh) != 1) {
			wi_error_set_openssl_error();
			
			return false;
		}
	}
	
	if(timeout > 0.0) {
		blocking = wi_socket_blocking(socket);
		
		if(blocking)
			wi_socket_set_blocking(socket, false);
		
		result = SSL_accept(socket->ssl);
		
		if(result != 1) {
			do {
				err = SSL_get_error(socket->ssl, result);
				
				if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
					wi_error_set_openssl_ssl_error_with_result(socket->ssl, result);
					
					return false;
				}

				state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE));

				if(state == WI_SOCKET_ERROR)
					break;
				else if(state == WI_SOCKET_READY) {
					result = SSL_accept(socket->ssl);
					
					if(result == 1)
						break;
				}
				
				timeout -= 1.0;
			} while(timeout >= 0.0);

			if(state == WI_SOCKET_ERROR)
				return false;
			
			if(timeout <= 0.0) {
				wi_error_set_errno(ETIMEDOUT);
				
				return false;
			}
		}
		
		if(blocking)
			wi_socket_set_blocking(socket, true);
	} else {
		result = SSL_accept(socket->ssl);
		
		if(result != 1) {
			wi_error_set_openssl_ssl_error_with_result(socket->ssl, result);
			
			return false;
		}
	}
	
	return true;
}
コード例 #20
0
ファイル: wi-cipher.c プロジェクト: ProfDrLuigi/zanka
static wi_cipher_t * _wi_cipher_init_with_key(wi_cipher_t *cipher, wi_data_t *key, wi_data_t *iv) {
#ifdef WI_CIPHER_COMMONCRYPTO
	CCCryptorStatus		status;
#endif
	unsigned char		*key_buffer, *iv_buffer;
	
	key_buffer			= (unsigned char *) wi_data_bytes(key);
	iv_buffer			= iv ? (unsigned char *) wi_data_bytes(iv) : NULL;

	cipher->key			= wi_retain(key);
	cipher->iv			= wi_retain(iv);
	
#ifdef WI_CIPHER_OPENSSL
	if(EVP_EncryptInit(&cipher->encrypt_ctx, cipher->cipher, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	if(EVP_DecryptInit(&cipher->decrypt_ctx, cipher->cipher, NULL, NULL) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	_wi_cipher_configure_cipher(cipher);
	
	if(EVP_EncryptInit(&cipher->encrypt_ctx, cipher->cipher, key_buffer, iv_buffer) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
	
	if(EVP_DecryptInit(&cipher->decrypt_ctx, cipher->cipher, key_buffer, iv_buffer) != 1) {
		wi_error_set_openssl_error();
		
		wi_release(cipher);
		
		return NULL;
	}
#endif
	
#ifdef WI_CIPHER_COMMONCRYPTO
	status = CCCryptorCreate(kCCEncrypt,
							 cipher->algorithm,
							 kCCOptionPKCS7Padding,
							 key_buffer,
							 wi_data_length(cipher->key),
							 iv_buffer,
							 &cipher->encrypt_ref);
	
	if(status != kCCSuccess) {
		wi_error_set_commoncrypto_error(status);
		
		wi_release(cipher);
		
		return NULL;
	}
	
	status = CCCryptorCreate(kCCDecrypt,
							 cipher->algorithm,
							 kCCOptionPKCS7Padding,
							 key_buffer,
							 wi_data_length(cipher->key),
							 iv_buffer,
							 &cipher->decrypt_ref);
	
	if(status != kCCSuccess) {
		wi_error_set_commoncrypto_error(status);
		
		wi_release(cipher);
		
		return NULL;
	}
#endif

	return cipher;
}