]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dcrypt: enc_key and pw must be NULL on storing unencrypted private key
authorMartti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
Thu, 13 Oct 2016 20:38:36 +0000 (23:38 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 17 Oct 2016 20:10:26 +0000 (23:10 +0300)
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.

src/lib-dcrypt/dcrypt-openssl.c
src/lib-dcrypt/dcrypt.h
src/lib-dcrypt/test-crypto.c

index fb8ad39fa72ccac58e2d7fef3dbb5cbf6a420f83..8438a45af3ab8f0726ea2281b001c4944b56ce4d 100644 (file)
@@ -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;
index 337b2efed3dde995088646993dc1862caa62e94d..f150053ca636a383a26e0628877492e680e79e9f 100644 (file)
@@ -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);
 
index 649f1b65999298ea7446252d4b4446704d4414a0..f5eb96b093ee8a242722daabda34ac6ed5f29447 100644 (file)
@@ -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
        };