From: Martti Rannanjärvi Date: Thu, 13 Oct 2016 20:38:36 +0000 (+0300) Subject: lib-dcrypt: enc_key and pw must be NULL on storing unencrypted private key X-Git-Tag: 2.2.26~130 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae0f3892a489a92b962677699f6c8e353ad309ce;p=thirdparty%2Fdovecot%2Fcore.git lib-dcrypt: enc_key and pw must be NULL on storing unencrypted private key Add tests for password and key encryption, and get_info on them. Also give examples of valid cipher values for password and key encryption in dcrypt.h comment. --- diff --git a/src/lib-dcrypt/dcrypt-openssl.c b/src/lib-dcrypt/dcrypt-openssl.c index fb8ad39fa7..8438a45af3 100644 --- a/src/lib-dcrypt/dcrypt-openssl.c +++ b/src/lib-dcrypt/dcrypt-openssl.c @@ -1456,7 +1456,7 @@ bool dcrypt_openssl_store_private_key_dovecot(struct dcrypt_private_key *key, co obj = OBJ_nid2obj(EVP_PKEY_id(pkey)); } - int enctype = 0; + int enctype = DCRYPT_KEY_ENCRYPTION_TYPE_NONE; int ln = OBJ_obj2txt(objtxt, sizeof(objtxt), obj, 1); if (ln < 1) return dcrypt_openssl_error(error_r); @@ -1500,6 +1500,8 @@ bool dcrypt_openssl_store_private_key_dovecot(struct dcrypt_private_key *key, co i_assert(password != NULL); enctype = DCRYPT_DOVECOT_KEY_ENCRYPT_PASSWORD; cipher2 = cipher; + } else if (enctype == DCRYPT_KEY_ENCRYPTION_TYPE_NONE) { + i_assert(enc_key == NULL && password == NULL); } /* put in OID and encryption type */ @@ -1507,7 +1509,7 @@ bool dcrypt_openssl_store_private_key_dovecot(struct dcrypt_private_key *key, co objtxt, enctype)); /* perform encryption if desired */ - if (enctype > 0) { + if (enctype != DCRYPT_KEY_ENCRYPTION_TYPE_NONE) { if (!dcrypt_openssl_encrypt_private_key_dovecot(buf, enctype, cipher2, password, enc_key, destination, error_r)) { buffer_set_used_size(destination, dest_used); return FALSE; diff --git a/src/lib-dcrypt/dcrypt.h b/src/lib-dcrypt/dcrypt.h index 337b2efed3..f150053ca6 100644 --- a/src/lib-dcrypt/dcrypt.h +++ b/src/lib-dcrypt/dcrypt.h @@ -178,6 +178,11 @@ bool dcrypt_key_load_private(struct dcrypt_private_key **key_r, const char *data bool dcrypt_key_load_public(struct dcrypt_public_key **key_r, const char *data, const char **error_r); +/** + * When encrypting with public key, the cipher parameter here must begin with + * ecdh-, for example ecdh-aes-256-ctr. An example of a valid cipher for + * encrypting with password would be aes-256-ctr. + */ bool dcrypt_key_store_private(struct dcrypt_private_key *key, enum dcrypt_key_format format, const char *cipher, buffer_t *destination, const char *password, struct dcrypt_public_key *enc_key, const char **error_r); diff --git a/src/lib-dcrypt/test-crypto.c b/src/lib-dcrypt/test-crypto.c index 649f1b6599..f5eb96b093 100644 --- a/src/lib-dcrypt/test-crypto.c +++ b/src/lib-dcrypt/test-crypto.c @@ -591,6 +591,81 @@ void test_get_info_invalid_keys(void) { test_end(); } +static +void test_get_info_key_encrypted(void) { + test_begin("test_get_info_key_encrypted"); + + struct dcrypt_keypair p1, p2; + const char *error = NULL; + bool ret = dcrypt_keypair_generate(&p1, DCRYPT_KEY_EC, 0, "sect571k1", &error); + test_assert(ret == TRUE); + ret = dcrypt_keypair_generate(&p2, DCRYPT_KEY_EC, 0, "sect571k1", &error); + test_assert(ret == TRUE); + + string_t* buf = str_new(default_pool, 4096); + + buffer_set_used_size(buf, 0); + ret = dcrypt_key_store_private(p1.priv, DCRYPT_FORMAT_DOVECOT, "ecdh-aes-256-ctr", buf, NULL, p2.pub, &error); + test_assert(ret == TRUE); + + enum dcrypt_key_format format; + enum dcrypt_key_version version; + enum dcrypt_key_kind kind; + enum dcrypt_key_encryption_type enc_type; + const char *enc_hash; + const char *key_hash; + + ret = dcrypt_key_string_get_info(str_c(buf), &format, &version, + &kind, &enc_type, &enc_hash, &key_hash, &error); + test_assert(ret == TRUE); + test_assert(format == DCRYPT_FORMAT_DOVECOT); + test_assert(version == DCRYPT_KEY_VERSION_2); + test_assert(kind == DCRYPT_KEY_KIND_PRIVATE); + test_assert(enc_type == DCRYPT_KEY_ENCRYPTION_TYPE_KEY); + test_assert(enc_hash != NULL); + test_assert(key_hash != NULL); + + dcrypt_keypair_unref(&p1); + dcrypt_keypair_unref(&p2); + + test_end(); +} + +static +void test_get_info_pw_encrypted(void) { + test_begin("test_get_info_pw_encrypted"); + + struct dcrypt_keypair p1; + const char *error; + bool ret = dcrypt_keypair_generate(&p1, DCRYPT_KEY_EC, 0, "sect571k1", &error); + test_assert(ret == TRUE); + + string_t* buf = str_new(default_pool, 4096); + ret = dcrypt_key_store_private(p1.priv, DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", buf, "pw", NULL, &error); + test_assert(ret == TRUE); + + enum dcrypt_key_format format; + enum dcrypt_key_version version; + enum dcrypt_key_kind kind; + enum dcrypt_key_encryption_type enc_type; + const char *enc_hash; + const char *key_hash; + + ret = dcrypt_key_string_get_info(str_c(buf), &format, &version, + &kind, &enc_type, &enc_hash, &key_hash, &error); + test_assert(ret == TRUE); + test_assert(format == DCRYPT_FORMAT_DOVECOT); + test_assert(version == DCRYPT_KEY_VERSION_2); + test_assert(kind == DCRYPT_KEY_KIND_PRIVATE); + test_assert(enc_type == DCRYPT_KEY_ENCRYPTION_TYPE_PASSWORD); + test_assert(enc_hash == NULL); + test_assert(key_hash != NULL); + + dcrypt_keypair_unref(&p1); + + test_end(); +} + static void test_load_invalid_keys(void) { test_begin("test_load_invalid_keys"); @@ -634,6 +709,8 @@ int main(void) { test_gen_and_get_info_rsa_pem, test_get_info_rsa_private_key, test_get_info_invalid_keys, + test_get_info_key_encrypted, + test_get_info_pw_encrypted, test_load_invalid_keys, NULL };