Пример #1
0
static
void test_load_v1_public_key(void)
{
	test_begin("test_load_v1_public_key");

	const char* data1 = "1\t716\t030131D8A5FD5167947A0AE9CB112ADED6526654635AA5887051EE2364414B60FF32EBA8FA0BBE9485DBDE8794BBBCB44BBFC0D662A4287A848BA570D4E5E45A11FE0F\td0cfaca5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615e77a0";

	const char* error = NULL;
	const char* key_hash = NULL;
	const char* encryption_key_hash = NULL;

	enum dcrypt_key_format format;
	enum dcrypt_key_version version;
	enum dcrypt_key_kind kind;
	enum dcrypt_key_encryption_type encryption_type;

	bool ret = dcrypt_key_string_get_info(data1, &format, &version,
			&kind, &encryption_type, &encryption_key_hash,
			&key_hash, &error);

	test_assert(ret == TRUE);
	test_assert(error == NULL);
	test_assert(format == DCRYPT_FORMAT_DOVECOT);
	test_assert(version == DCRYPT_KEY_VERSION_1);
	test_assert(kind == DCRYPT_KEY_KIND_PUBLIC);
	test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
	test_assert(key_hash != NULL && strcmp(key_hash, "d0cfaca5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615e77a0") == 0);
	test_assert(encryption_key_hash == NULL);

	struct dcrypt_public_key *pub_key = NULL;
	ret = dcrypt_key_load_public(&pub_key, format, data1, &error);
	test_assert(ret == TRUE);
	test_assert(error == NULL);

	test_assert(dcrypt_key_type_public(pub_key) == DCRYPT_KEY_EC);

	dcrypt_key_free_public(&pub_key);
	test_assert(pub_key == NULL);

	test_end();
}
Пример #2
0
static
int o_stream_encrypt_key_for_pubkey_v2(struct encrypt_ostream *stream, const char *malg,
	const unsigned char *key, size_t key_len, struct dcrypt_public_key *pubkey, buffer_t *res)
{
	enum dcrypt_key_type ktype;
	const char *error;
	buffer_t *encrypted_key, *ephemeral_key, *temp_key;

	ephemeral_key = buffer_create_dynamic(pool_datastack_create(), 256);
	encrypted_key = buffer_create_dynamic(pool_datastack_create(), 256);
	temp_key = buffer_create_dynamic(pool_datastack_create(), 48);

	ktype = dcrypt_key_type_public(pubkey);

	if (ktype == DCRYPT_KEY_RSA) {
		/* encrypt key as R (as we don't need DH with RSA)*/
		if (!dcrypt_rsa_encrypt(pubkey, key, key_len, encrypted_key, &error)) {
			io_stream_set_error(&stream->ostream.iostream, "Cannot encrypt key data: %s", error);
			return -1;
		}
	} else if (ktype == DCRYPT_KEY_EC) {
		/* R = our ephemeral public key */
		buffer_t *secret = buffer_create_dynamic(pool_datastack_create(), 256);

		/* derive ephemeral key and shared secret */
		if (!dcrypt_ecdh_derive_secret_peer(pubkey, ephemeral_key, secret, &error)) {
			io_stream_set_error(&stream->ostream.iostream, "Cannot perform ECDH: %s", error);
			return -1;
		}

		/* use shared secret and ephemeral key to generate encryption key/iv */
		if (!dcrypt_pbkdf2(secret->data, secret->used, ephemeral_key->data, ephemeral_key->used,
		    malg, IO_STREAM_ENCRYPT_ROUNDS, temp_key, 48, &error)) {
			safe_memset(buffer_get_modifiable_data(secret, 0), 0, secret->used);
			io_stream_set_error(&stream->ostream.iostream, "Cannot perform key encryption: %s", error);
		}
		safe_memset(buffer_get_modifiable_data(secret, 0), 0, secret->used);

		/* encrypt key with shared secret */
		struct dcrypt_context_symmetric *dctx;
		if (!dcrypt_ctx_sym_create("AES-256-CBC", DCRYPT_MODE_ENCRYPT, &dctx, &error)) {
			safe_memset(buffer_get_modifiable_data(temp_key, 0), 0, temp_key->used);
			io_stream_set_error(&stream->ostream.iostream, "Cannot perform key encryption: %s", error);
			return -1;
		}

		const unsigned char *ptr = temp_key->data;
		i_assert(temp_key->used == 48);

		dcrypt_ctx_sym_set_key(dctx, ptr, 32);
		dcrypt_ctx_sym_set_iv(dctx, ptr+32, 16);
		safe_memset(buffer_get_modifiable_data(temp_key, 0), 0, temp_key->used);

		int ec = 0;
		if (!dcrypt_ctx_sym_init(dctx, &error) ||
		    !dcrypt_ctx_sym_update(dctx, key, key_len, encrypted_key, &error) ||
		    !dcrypt_ctx_sym_final(dctx, encrypted_key, &error)) {
			io_stream_set_error(&stream->ostream.iostream, "Cannot perform key encryption: %s", error);
			ec = -1;
		}

		dcrypt_ctx_sym_destroy(&dctx);
		if (ec != 0) return ec;
	} else {
		io_stream_set_error(&stream->ostream.iostream, "Unsupported key type");
		return -1;
	}

	/* store key type */
	char kt = ktype;
	buffer_append(res, &kt, 1);
	/* store hash of public key as ID */
	dcrypt_key_id_public(stream->pub, "sha256", res, NULL);
	/* store ephemeral key (if present) */
	unsigned int val = htonl(ephemeral_key->used);
	buffer_append(res, &val, 4);
	buffer_append_buf(res, ephemeral_key, 0, (size_t)-1);
	/* store encrypted key */
	val = htonl(encrypted_key->used);
	buffer_append(res, &val, 4);
	buffer_append_buf(res, encrypted_key, 0, (size_t)-1);

	return 0;
}