Key copying function 00/77700/4
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 30 Jun 2016 10:25:09 +0000 (12:25 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Wed, 6 Jul 2016 10:24:27 +0000 (03:24 -0700)
Change-Id: I372b7fd9c01f4eb104fc953c7995fa63dba0cba6

src/internal.h
src/key.c

index 5a6285e..dce0a61 100644 (file)
@@ -131,6 +131,8 @@ int encrypt_finalize(yaca_context_h ctx,
 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key);
 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key);
 
+yaca_key_h key_copy(const yaca_key_h key);
+
 void error_dump(const char *file, int line, const char *function, int code);
 #define ERROR_DUMP(code) error_dump(__FILE__, __LINE__, __func__, (code))
 #define ERROR_CLEAR() ERR_clear_error()
index b54f1c9..4153434 100644 (file)
--- a/src/key.c
+++ b/src/key.c
@@ -32,6 +32,7 @@
 #include <openssl/bio.h>
 #include <openssl/pem.h>
 #include <openssl/des.h>
+#include <openssl/crypto.h>
 
 #include <yaca_crypto.h>
 #include <yaca_error.h>
@@ -1000,6 +1001,53 @@ struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
        }
 }
 
+static yaca_key_h key_copy_simple(const struct yaca_key_simple_s *key)
+{
+       int ret;
+       assert(key != NULL);
+
+       struct yaca_key_simple_s *copy;
+       size_t size = sizeof(struct yaca_key_simple_s) + key->bits / 8;
+
+       ret = yaca_zalloc(size, (void**)&copy);
+       if (ret != YACA_ERROR_NONE)
+               return YACA_KEY_NULL;
+
+       memcpy(copy, key, size);
+       return (yaca_key_h)copy;
+}
+
+static yaca_key_h key_copy_evp(const struct yaca_key_evp_s *key)
+{
+       int ret;
+       assert(key != NULL);
+
+       struct yaca_key_evp_s *copy = NULL;
+       ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&copy);
+       if (ret != YACA_ERROR_NONE)
+               return YACA_KEY_NULL;
+
+       /* raise the refcount */
+       CRYPTO_add(&key->evp->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+       copy->key.type = key->key.type;
+       copy->evp = key->evp;
+       return (yaca_key_h)copy;
+}
+
+yaca_key_h key_copy(const yaca_key_h key)
+{
+       struct yaca_key_simple_s *simple = key_get_simple(key);
+       struct yaca_key_evp_s *evp = key_get_evp(key);
+
+       if (simple != NULL)
+               return key_copy_simple(simple);
+       else if (evp != NULL)
+               return key_copy_evp(evp);
+
+       return YACA_KEY_NULL;
+}
+
 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
 {
        const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;