LCOV - code coverage report
Current view: top level - src/plugins/crypto - openssl_operations.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 4 230 1.7 %
Date: 2019-09-12 12:28:41 Functions: 1 8 12.5 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief cryptographic interface using the libcrypto library (part of the OpenSSL project)
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : #include "crypto.h"
      11             : 
      12             : #include "gpg.h"
      13             : #include "helper.h"
      14             : #include "openssl_operations.h"
      15             : 
      16             : #include <kdbassert.h>
      17             : #include <kdberrors.h>
      18             : #include <kdbtypes.h>
      19             : #include <openssl/buffer.h>
      20             : #include <openssl/crypto.h>
      21             : #include <openssl/err.h>
      22             : #include <openssl/rand.h>
      23             : #include <pthread.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : 
      27             : #if OPENSSL_VERSION_NUMBER < 0x10100000L
      28             : #define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_cleanup
      29             : #endif
      30             : 
      31             : #define KEY_BUFFER_SIZE (ELEKTRA_CRYPTO_SSL_KEYSIZE + ELEKTRA_CRYPTO_SSL_BLOCKSIZE)
      32             : 
      33             : /*
      34             :  * Protects all calls to OpenSSL (libcrypto.so).
      35             :  *
      36             :  * This is required because we can not setup the multi-threading capabilities of OpenSSL directly from within Elektra.
      37             :  */
      38             : static pthread_mutex_t mutex_ssl = PTHREAD_MUTEX_INITIALIZER;
      39             : 
      40             : /**
      41             :  * @brief derive the cryptographic key and IV for a given (Elektra) Key k
      42             :  * @param config KeySet holding the plugin/backend configuration
      43             :  * @param errorKey holds an error description in case of failure
      44             :  * @param masterKey holds the decrypted master password from the plugin configuration
      45             :  * @param k the (Elektra)-Key to be encrypted
      46             :  * @param cKey (Elektra)-Key holding the cryptographic material
      47             :  * @param cIv (Elektra)-Key holding the initialization vector
      48             :  * @retval -1 on failure. errorKey holds the error description.
      49             :  * @retval 1 on success
      50             :  */
      51           0 : static int getKeyIvForEncryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
      52             : {
      53           0 :         kdb_octet_t salt[ELEKTRA_CRYPTO_DEFAULT_SALT_LEN] = { 0 };
      54           0 :         kdb_octet_t keyBuffer[KEY_BUFFER_SIZE] = { 0 };
      55           0 :         char * saltHexString = NULL;
      56             : 
      57           0 :         ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");
      58             : 
      59             :         // generate the salt
      60           0 :         pthread_mutex_lock (&mutex_ssl);
      61           0 :         if (!RAND_bytes (salt, ELEKTRA_CRYPTO_DEFAULT_SALT_LEN - 1))
      62             :         {
      63           0 :                 ELEKTRA_SET_INTERNAL_ERRORF (errorKey, "Failed to generate random salt with error code %lu", ERR_get_error ());
      64           0 :                 pthread_mutex_unlock (&mutex_ssl);
      65           0 :                 return -1;
      66             :         }
      67           0 :         pthread_mutex_unlock (&mutex_ssl);
      68           0 :         const int encodingResult = ELEKTRA_PLUGIN_FUNCTION (base64Encode) (errorKey, salt, sizeof (salt), &saltHexString);
      69           0 :         if (encodingResult < 0)
      70             :         {
      71             :                 // error in libinvoke - errorKey has been set by base64Encode
      72             :                 return -1;
      73             :         }
      74           0 :         if (!saltHexString)
      75             :         {
      76           0 :                 ELEKTRA_SET_OUT_OF_MEMORY_ERROR (errorKey, "Memory allocation failed");
      77           0 :                 return -1;
      78             :         }
      79           0 :         keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, saltHexString);
      80           0 :         elektraFree (saltHexString);
      81             : 
      82             :         // read iteration count
      83           0 :         const kdb_unsigned_long_t iterations = ELEKTRA_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);
      84             : 
      85             :         // generate/derive the cryptographic key and the IV
      86           0 :         pthread_mutex_lock (&mutex_ssl);
      87           0 :         if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), salt, sizeof (salt), iterations, KEY_BUFFER_SIZE,
      88             :                                      keyBuffer))
      89             :         {
      90           0 :                 ELEKTRA_SET_INTERNAL_ERRORF (errorKey,
      91             :                                              "Failed to create a cryptographic key for encryption. Libcrypto returned error code: %lu",
      92             :                                              ERR_get_error ());
      93           0 :                 pthread_mutex_unlock (&mutex_ssl);
      94           0 :                 return -1;
      95             :         }
      96           0 :         pthread_mutex_unlock (&mutex_ssl);
      97             : 
      98           0 :         keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_SSL_KEYSIZE);
      99           0 :         keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_SSL_KEYSIZE, ELEKTRA_CRYPTO_SSL_BLOCKSIZE);
     100           0 :         return 1;
     101             : }
     102             : 
     103             : /**
     104             :  * @brief derive the cryptographic key and IV for a given (Elektra) Key k
     105             :  * @param config KeySet holding the plugin/backend configuration
     106             :  * @param errorKey holds an error description in case of failure
     107             :  * @param masterKey holds the decrypted master password from the plugin configuration
     108             :  * @param k the (Elektra)-Key to be encrypted
     109             :  * @param cKey (Elektra)-Key holding the cryptographic material
     110             :  * @param cIv (Elektra)-Key holding the initialization vector
     111             :  * @retval -1 on failure. errorKey holds the error description.
     112             :  * @retval 1 on success
     113             :  */
     114           0 : static int getKeyIvForDecryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv)
     115             : {
     116             :         kdb_octet_t keyBuffer[KEY_BUFFER_SIZE];
     117           0 :         kdb_octet_t * saltBuffer = NULL;
     118           0 :         kdb_unsigned_long_t saltBufferLen = 0;
     119             : 
     120           0 :         ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL");
     121             : 
     122             :         // get the salt
     123           0 :         if (ELEKTRA_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, &saltBuffer, &saltBufferLen) != 1)
     124             :         {
     125             :                 return -1; // error set by ELEKTRA_PLUGIN_FUNCTION(getSaltFromPayload)()
     126             :         }
     127             : 
     128             :         // get the iteration count
     129           0 :         const kdb_unsigned_long_t iterations = ELEKTRA_PLUGIN_FUNCTION (getIterationCount) (errorKey, config);
     130             : 
     131             :         // derive the cryptographic key and the IV
     132           0 :         pthread_mutex_lock (&mutex_ssl);
     133           0 :         if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), saltBuffer, saltBufferLen, iterations,
     134             :                                      KEY_BUFFER_SIZE, keyBuffer))
     135             :         {
     136           0 :                 ELEKTRA_SET_INTERNAL_ERRORF (
     137             :                         errorKey, "Failed to restore the cryptographic key for decryption. Libcrypto returned the error code: %lu",
     138             :                         ERR_get_error ());
     139           0 :                 pthread_mutex_unlock (&mutex_ssl);
     140           0 :                 return -1;
     141             :         }
     142           0 :         pthread_mutex_unlock (&mutex_ssl);
     143             : 
     144           0 :         keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_SSL_KEYSIZE);
     145           0 :         keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_SSL_KEYSIZE, ELEKTRA_CRYPTO_SSL_BLOCKSIZE);
     146           0 :         return 1;
     147             : }
     148             : 
     149          16 : int elektraCryptoOpenSSLInit (Key * errorKey ELEKTRA_UNUSED)
     150             : {
     151             :         // initialize OpenSSL according to
     152             :         // https://wiki.openssl.org/index.php/Library_Initialization
     153          16 :         pthread_mutex_lock (&mutex_ssl);
     154             : #if OPENSSL_VERSION_NUMBER < 0x10100000L
     155             :         OpenSSL_add_all_algorithms ();
     156             :         ERR_load_crypto_strings ();
     157             : #endif
     158          16 :         pthread_mutex_unlock (&mutex_ssl);
     159          16 :         return 1;
     160             : }
     161             : 
     162           0 : int elektraCryptoOpenSSLHandleCreate (elektraCryptoHandle ** handle, KeySet * config, Key * errorKey, Key * masterKey, Key * k,
     163             :                                       const enum ElektraCryptoOperation op)
     164             : {
     165             :         unsigned char keyBuffer[64], ivBuffer[64];
     166             : 
     167           0 :         *handle = NULL;
     168             : 
     169             :         // retrieve/derive the cryptographic material
     170           0 :         Key * key = keyNew (0);
     171           0 :         Key * iv = keyNew (0);
     172           0 :         switch (op)
     173             :         {
     174             :         case ELEKTRA_CRYPTO_ENCRYPT:
     175           0 :                 if (getKeyIvForEncryption (config, errorKey, masterKey, k, key, iv) != 1)
     176             :                 {
     177           0 :                         keyDel (key);
     178           0 :                         keyDel (iv);
     179           0 :                         return -1;
     180             :                 }
     181             :                 break;
     182             : 
     183             :         case ELEKTRA_CRYPTO_DECRYPT:
     184           0 :                 if (getKeyIvForDecryption (config, errorKey, masterKey, k, key, iv) != 1)
     185             :                 {
     186           0 :                         keyDel (key);
     187           0 :                         keyDel (iv);
     188           0 :                         return -1;
     189             :                 }
     190             :                 break;
     191             : 
     192             :         default: // not supported
     193           0 :                 keyDel (key);
     194           0 :                 keyDel (iv);
     195           0 :                 return -1;
     196             :         }
     197             : 
     198           0 :         if (keyGetValueSize (key) != ELEKTRA_CRYPTO_SSL_KEYSIZE)
     199             :         {
     200           0 :                 keyDel (key);
     201           0 :                 keyDel (iv);
     202           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (errorKey, "Failed to create handle! Invalid key length");
     203           0 :                 return -1;
     204             :         }
     205             : 
     206           0 :         if (keyGetValueSize (iv) != ELEKTRA_CRYPTO_SSL_BLOCKSIZE)
     207             :         {
     208           0 :                 keyDel (key);
     209           0 :                 keyDel (iv);
     210             : 
     211           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (errorKey, "Failed to create handle! Invalid IV length");
     212           0 :                 return -1;
     213             :         }
     214             : 
     215           0 :         keyGetBinary (key, keyBuffer, sizeof (keyBuffer));
     216           0 :         keyGetBinary (iv, ivBuffer, sizeof (ivBuffer));
     217             : 
     218           0 :         keyDel (key);
     219           0 :         keyDel (iv);
     220             : 
     221           0 :         *handle = elektraMalloc (sizeof (elektraCryptoHandle));
     222           0 :         if (!(*handle))
     223             :         {
     224           0 :                 memset (keyBuffer, 0, sizeof (keyBuffer));
     225           0 :                 memset (ivBuffer, 0, sizeof (ivBuffer));
     226           0 :                 ELEKTRA_SET_OUT_OF_MEMORY_ERROR (errorKey, "Memory allocation failed");
     227           0 :                 return -1;
     228             :         }
     229             : 
     230           0 :         pthread_mutex_lock (&mutex_ssl);
     231             : 
     232           0 :         (*handle)->encrypt = EVP_CIPHER_CTX_new ();
     233           0 :         (*handle)->decrypt = EVP_CIPHER_CTX_new ();
     234             : 
     235           0 :         EVP_EncryptInit ((*handle)->encrypt, EVP_aes_256_cbc (), keyBuffer, ivBuffer);
     236           0 :         EVP_DecryptInit ((*handle)->decrypt, EVP_aes_256_cbc (), keyBuffer, ivBuffer);
     237             : 
     238           0 :         memset (keyBuffer, 0, sizeof (keyBuffer));
     239           0 :         memset (ivBuffer, 0, sizeof (ivBuffer));
     240             : 
     241           0 :         if (ERR_peek_error ())
     242             :         {
     243             :                 // TODO: Correct??
     244           0 :                 ELEKTRA_SET_INTERNAL_ERRORF (errorKey, "Failed to create handle! libcrypto error code was: %lu", ERR_get_error ());
     245           0 :                 elektraFree (*handle);
     246           0 :                 *handle = NULL;
     247           0 :                 pthread_mutex_unlock (&mutex_ssl);
     248           0 :                 return -1;
     249             :         }
     250           0 :         pthread_mutex_unlock (&mutex_ssl);
     251           0 :         return 1;
     252             : }
     253             : 
     254           0 : void elektraCryptoOpenSSLHandleDestroy (elektraCryptoHandle * handle)
     255             : {
     256           0 :         if (handle)
     257             :         {
     258           0 :                 pthread_mutex_lock (&mutex_ssl);
     259           0 :                 EVP_CIPHER_CTX_reset (handle->encrypt);
     260           0 :                 EVP_CIPHER_CTX_reset (handle->decrypt);
     261           0 :                 EVP_CIPHER_CTX_free (handle->encrypt);
     262           0 :                 EVP_CIPHER_CTX_free (handle->decrypt);
     263           0 :                 pthread_mutex_unlock (&mutex_ssl);
     264           0 :                 elektraFree (handle);
     265             :         }
     266           0 : }
     267             : 
     268           0 : int elektraCryptoOpenSSLEncrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
     269             : {
     270             :         // NOTE to prevent memory overflows in libcrypto the buffer holding the encrypted content (cipherBuffer) is 2 cipher blocks long.
     271             :         kdb_octet_t cipherBuffer[2 * ELEKTRA_CRYPTO_SSL_BLOCKSIZE];
     272             :         kdb_octet_t headerBuffer[ELEKTRA_CRYPTO_SSL_BLOCKSIZE];
     273           0 :         int written = 0;
     274             :         BIO * encrypted;
     275             : 
     276             :         // prepare the salt for payload output
     277           0 :         kdb_unsigned_long_t saltLen = 0;
     278           0 :         kdb_octet_t * salt = NULL;
     279             : 
     280           0 :         if (ELEKTRA_PLUGIN_FUNCTION (getSaltFromMetakey) (errorKey, k, &salt, &saltLen) != 1)
     281             :         {
     282             :                 return -1; // error set by ELEKTRA_PLUGIN_FUNCTION(getSaltFromMetakey)()
     283             :         }
     284             : 
     285             :         // remove salt as metakey because it will be encoded into the crypto payload
     286           0 :         keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, NULL);
     287             : 
     288             :         // prepare the crypto header data
     289             :         kdb_octet_t flags;
     290           0 :         const kdb_unsigned_long_t contentLen = keyGetValueSize (k);
     291           0 :         const size_t headerLen = sizeof (flags) + sizeof (contentLen);
     292             : 
     293           0 :         switch (keyIsString (k))
     294             :         {
     295             :         case 1: // string
     296             :                 flags = ELEKTRA_CRYPTO_FLAG_STRING;
     297             :                 break;
     298             :         case -1: // NULL pointer
     299           0 :                 flags = ELEKTRA_CRYPTO_FLAG_NULL;
     300           0 :                 break;
     301             :         default: // binary
     302           0 :                 flags = ELEKTRA_CRYPTO_FLAG_NONE;
     303           0 :                 break;
     304             :         }
     305             : 
     306           0 :         pthread_mutex_lock (&mutex_ssl);
     307             : 
     308           0 :         encrypted = BIO_new (BIO_s_mem ());
     309           0 :         if (!encrypted)
     310             :         {
     311           0 :                 ELEKTRA_SET_OUT_OF_MEMORY_ERROR (errorKey, "Memory allocation failed");
     312           0 :                 pthread_mutex_unlock (&mutex_ssl);
     313           0 :                 elektraFree (salt);
     314           0 :                 return -1;
     315             :         }
     316             : 
     317             :         // write out the magic number
     318           0 :         BIO_write (encrypted, ELEKTRA_CRYPTO_MAGIC_NUMBER, ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN);
     319             : 
     320             :         // encode the salt into the payload
     321           0 :         BIO_write (encrypted, &saltLen, sizeof (saltLen));
     322           0 :         BIO_write (encrypted, salt, saltLen);
     323             : 
     324             :         // encrypt the header data
     325           0 :         memcpy (headerBuffer, &flags, sizeof (flags));
     326           0 :         memcpy (headerBuffer + sizeof (flags), &contentLen, sizeof (contentLen));
     327           0 :         EVP_EncryptUpdate (handle->encrypt, cipherBuffer, &written, headerBuffer, headerLen);
     328           0 :         if (written > 0)
     329             :         {
     330           0 :                 BIO_write (encrypted, cipherBuffer, written);
     331             :         }
     332             : 
     333           0 :         if (ERR_peek_error ())
     334             :         {
     335             :                 goto error;
     336             :         }
     337             : 
     338             :         // encrypt content block by block
     339           0 :         kdb_octet_t * content = (kdb_octet_t *) keyValue (k);
     340           0 :         size_t processed = 0;
     341             : 
     342           0 :         while (processed < contentLen)
     343             :         {
     344           0 :                 kdb_unsigned_long_t partitionLen = ELEKTRA_CRYPTO_SSL_BLOCKSIZE;
     345             :                 // the last partition may not fill an entire cipher block
     346           0 :                 if (processed + ELEKTRA_CRYPTO_SSL_BLOCKSIZE > contentLen)
     347             :                 {
     348             :                         // length of last partition = total content length - number of bytes already processed
     349           0 :                         partitionLen = contentLen - processed;
     350             :                 }
     351             : 
     352           0 :                 EVP_EncryptUpdate (handle->encrypt, cipherBuffer, &written, content, partitionLen);
     353           0 :                 if (written > 0)
     354             :                 {
     355           0 :                         BIO_write (encrypted, cipherBuffer, written);
     356             :                 }
     357             : 
     358           0 :                 if (ERR_peek_error ())
     359             :                 {
     360             :                         goto error;
     361             :                 }
     362             : 
     363             :                 // move content pointer to the next partition
     364           0 :                 processed += partitionLen;
     365           0 :                 content += partitionLen;
     366             :         }
     367             : 
     368           0 :         EVP_EncryptFinal_ex (handle->encrypt, cipherBuffer, &written);
     369           0 :         if (written > 0)
     370             :         {
     371           0 :                 BIO_write (encrypted, cipherBuffer, written);
     372             :         }
     373             : 
     374           0 :         if (ERR_peek_error ())
     375             :         {
     376             :                 goto error;
     377             :         }
     378             : 
     379             :         // write back the cipher text to the key
     380             :         kdb_octet_t * output;
     381           0 :         size_t outputLen = BIO_get_mem_data (encrypted, &output);
     382           0 :         if (outputLen > 0)
     383             :         {
     384           0 :                 keySetBinary (k, output, outputLen);
     385             :         }
     386           0 :         BIO_free_all (encrypted);
     387           0 :         pthread_mutex_unlock (&mutex_ssl);
     388           0 :         elektraFree (salt);
     389           0 :         return 1;
     390             : 
     391             : error:
     392           0 :         ELEKTRA_SET_INSTALLATION_ERRORF (errorKey, "Encryption error! libcrypto error code was: %lu", ERR_get_error ());
     393           0 :         BIO_free_all (encrypted);
     394           0 :         pthread_mutex_unlock (&mutex_ssl);
     395           0 :         elektraFree (salt);
     396           0 :         return -1;
     397             : }
     398             : 
     399           0 : int elektraCryptoOpenSSLDecrypt (elektraCryptoHandle * handle, Key * k, Key * errorKey)
     400             : {
     401             :         // NOTE to prevent memory overflows in libcrypto the buffer holding the decrypted content (contentBuffer) is two cipher blocks long
     402             :         kdb_octet_t contentBuffer[2 * ELEKTRA_CRYPTO_SSL_BLOCKSIZE];
     403           0 :         int written = 0;
     404             :         kdb_octet_t * plaintext;
     405             :         size_t plaintextLen;
     406             : 
     407             :         // parse salt length from crypto payload
     408           0 :         kdb_unsigned_long_t saltLen = 0;
     409           0 :         if (ELEKTRA_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, NULL, &saltLen) != 1)
     410             :         {
     411             :                 return -1; // error set by ELEKTRA_PLUGIN_FUNCTION(getSaltFromPayload)()
     412             :         }
     413           0 :         saltLen += sizeof (kdb_unsigned_long_t);
     414             : 
     415             :         // set payload pointer
     416           0 :         const kdb_octet_t * payload = ((kdb_octet_t *) keyValue (k)) + saltLen + ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;
     417           0 :         const size_t payloadLen = keyGetValueSize (k) - saltLen - ELEKTRA_CRYPTO_MAGIC_NUMBER_LEN;
     418             : 
     419             :         // initialize crypto header data
     420           0 :         kdb_unsigned_long_t contentLen = 0;
     421           0 :         kdb_octet_t flags = ELEKTRA_CRYPTO_FLAG_NONE;
     422           0 :         const size_t headerLen = sizeof (flags) + sizeof (contentLen);
     423             : 
     424             :         // plausibility check
     425           0 :         if (payloadLen % ELEKTRA_CRYPTO_SSL_BLOCKSIZE != 0)
     426             :         {
     427           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (errorKey, "Value length is not a multiple of the block size");
     428           0 :                 return -1;
     429             :         }
     430             : 
     431           0 :         pthread_mutex_lock (&mutex_ssl);
     432             : 
     433             :         // prepare sink for plain text output
     434           0 :         BIO * decrypted = BIO_new (BIO_s_mem ());
     435           0 :         if (!decrypted)
     436             :         {
     437           0 :                 ELEKTRA_SET_OUT_OF_MEMORY_ERROR (errorKey, "Memory allocation failed");
     438           0 :                 pthread_mutex_unlock (&mutex_ssl);
     439           0 :                 return -1;
     440             :         }
     441             : 
     442             :         // decrypt the whole BLOB and store the plain text into the memory sink
     443           0 :         for (kdb_unsigned_long_t i = 0; i < payloadLen; i += ELEKTRA_CRYPTO_SSL_BLOCKSIZE)
     444             :         {
     445           0 :                 EVP_DecryptUpdate (handle->decrypt, contentBuffer, &written, (payload + i), ELEKTRA_CRYPTO_SSL_BLOCKSIZE);
     446           0 :                 if (written > 0)
     447             :                 {
     448           0 :                         BIO_write (decrypted, contentBuffer, written);
     449             :                 }
     450             : 
     451           0 :                 if (ERR_peek_error ())
     452             :                 {
     453             :                         goto error;
     454             :                 }
     455             :         }
     456             : 
     457           0 :         EVP_DecryptFinal_ex (handle->decrypt, contentBuffer, &written);
     458           0 :         if (written > 0)
     459             :         {
     460           0 :                 BIO_write (decrypted, contentBuffer, written);
     461             :         }
     462             : 
     463           0 :         if (ERR_peek_error ())
     464             :         {
     465             :                 goto error;
     466             :         }
     467             : 
     468           0 :         plaintextLen = BIO_get_mem_data (decrypted, &plaintext);
     469           0 :         if (plaintextLen < headerLen)
     470             :         {
     471           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (errorKey, "Decryption error! header data is incomplete");
     472           0 :                 goto error;
     473             :         }
     474             : 
     475             :         // restore the header
     476           0 :         memcpy (&flags, plaintext, sizeof (flags));
     477           0 :         plaintext += sizeof (flags);
     478           0 :         memcpy (&contentLen, plaintext, sizeof (contentLen));
     479           0 :         plaintext += sizeof (contentLen);
     480             : 
     481             :         // validate restored header
     482           0 :         if (contentLen > (plaintextLen - headerLen))
     483             :         {
     484           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (
     485             :                         errorKey, "Content length is bigger than amount of decrypted data. Data is possibly corrupted");
     486           0 :                 goto error;
     487             :         }
     488             : 
     489             :         // write back the cipher text to the key
     490           0 :         if ((flags & ELEKTRA_CRYPTO_FLAG_STRING) == ELEKTRA_CRYPTO_FLAG_STRING)
     491             :         {
     492           0 :                 keySetString (k, (const char *) plaintext);
     493             :         }
     494           0 :         else if ((flags & ELEKTRA_CRYPTO_FLAG_NULL) == ELEKTRA_CRYPTO_FLAG_NULL || contentLen == 0)
     495             :         {
     496           0 :                 keySetBinary (k, NULL, 0);
     497             :         }
     498             :         else
     499             :         {
     500           0 :                 keySetBinary (k, plaintext, contentLen);
     501             :         }
     502             : 
     503           0 :         BIO_free_all (decrypted);
     504           0 :         pthread_mutex_unlock (&mutex_ssl);
     505           0 :         return 1;
     506             : 
     507             : error:
     508             :         // TODO: Correct??
     509           0 :         ELEKTRA_SET_INTERNAL_ERRORF (errorKey, "Decryption error! libcrypto error code was: %lu", ERR_get_error ());
     510           0 :         BIO_free_all (decrypted);
     511           0 :         pthread_mutex_unlock (&mutex_ssl);
     512           0 :         return -1;
     513             : }
     514             : 
     515             : /**
     516             :  * @brief create a random sequence of characters with given length.
     517             :  * @param errorKey holds an error description in case of failure.
     518             :  * @param length the number of random bytes to be generated.
     519             :  * @returns allocated buffer holding a hex-encoded random string or NULL in case of error. Must be freed by the caller.
     520             :  */
     521           0 : char * elektraCryptoOpenSSLCreateRandomString (Key * errorKey, const kdb_unsigned_short_t length)
     522           0 : {
     523           0 :         char * encoded = NULL;
     524           0 :         kdb_octet_t buffer[length];
     525           0 :         pthread_mutex_lock (&mutex_ssl);
     526           0 :         if (!RAND_bytes (buffer, length))
     527             :         {
     528             :                 // TODO: Correct??
     529           0 :                 ELEKTRA_SET_INTERNAL_ERRORF (errorKey, "Failed to generate random string. libcrypto error code was: %lu", ERR_get_error ());
     530           0 :                 pthread_mutex_unlock (&mutex_ssl);
     531           0 :                 return NULL;
     532             :         }
     533           0 :         pthread_mutex_unlock (&mutex_ssl);
     534           0 :         if (ELEKTRA_PLUGIN_FUNCTION (base64Encode) (errorKey, buffer, length, &encoded) < 0)
     535             :         {
     536             :                 // error in libinvoke - errorKey has been set by base64Encode
     537             :                 return NULL;
     538             :         }
     539           0 :         if (!encoded)
     540             :         {
     541           0 :                 ELEKTRA_SET_OUT_OF_MEMORY_ERROR (errorKey, "Memory allocation failed");
     542             :         }
     543           0 :         return encoded;
     544             : }

Generated by: LCOV version 1.13