LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - privkey_pkcs8_pbes1.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 79 89 88.8 %
Date: 2020-10-30 04:50:48 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2016 Red Hat
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : #include "gnutls_int.h"
      24             : 
      25             : #include <datum.h>
      26             : #include <global.h>
      27             : #include "errors.h"
      28             : #include <common.h>
      29             : #include <x509.h>
      30             : #include <x509_b64.h>
      31             : #include "x509_int.h"
      32             : #include "pkcs7_int.h"
      33             : #include <algorithms.h>
      34             : #include <nettle/md5.h>
      35             : 
      36             : /* This file includes support for PKCS#8 PBES1 with DES and MD5.
      37             :  * We only support decryption for compatibility with other software.
      38             :  */
      39             : 
      40          31 : int _gnutls_read_pbkdf1_params(const uint8_t * data, int data_size,
      41             :                        struct pbkdf2_params *kdf_params,
      42             :                        struct pbe_enc_params *enc_params)
      43             : {
      44          31 :         ASN1_TYPE pasn = ASN1_TYPE_EMPTY;
      45          31 :         int len;
      46          31 :         int ret, result;
      47             : 
      48          31 :         memset(kdf_params, 0, sizeof(*kdf_params));
      49          31 :         memset(enc_params, 0, sizeof(*enc_params));
      50             : 
      51          62 :         if ((result =
      52          31 :                      asn1_create_element(_gnutls_get_pkix(),
      53             :                                          "PKIX1.pkcs-5-PBE-params",
      54             :                                          &pasn)) != ASN1_SUCCESS) {
      55           0 :                 gnutls_assert();
      56           0 :                 return _gnutls_asn2err(result);
      57             :         }
      58             : 
      59             :         /* Decode the parameters.
      60             :          */
      61          31 :         result =
      62          31 :             _asn1_strict_der_decode(&pasn, data, data_size, NULL);
      63          31 :         if (result != ASN1_SUCCESS) {
      64           2 :                 gnutls_assert();
      65           2 :                 ret = _gnutls_asn2err(result);
      66           2 :                 goto error;
      67             :         }
      68             : 
      69          29 :         ret =
      70          29 :             _gnutls_x509_read_uint(pasn, "iterationCount",
      71             :                            &kdf_params->iter_count);
      72          29 :         if (ret < 0) {
      73           2 :                 gnutls_assert();
      74           2 :                 goto error;
      75             :         }
      76             : 
      77          27 :         if (kdf_params->iter_count >= MAX_ITER_COUNT || kdf_params->iter_count == 0) {
      78           2 :                 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
      79           2 :                 goto error;
      80             :         }
      81             : 
      82          25 :         len = sizeof(kdf_params->salt);
      83          25 :         result =
      84          50 :             asn1_read_value(pasn, "salt",
      85          25 :                     kdf_params->salt, &len);
      86          25 :         if (result != ASN1_SUCCESS) {
      87           0 :                 gnutls_assert();
      88           0 :                 ret = _gnutls_asn2err(result);
      89           0 :                 goto error;
      90             :         }
      91             : 
      92          25 :         if (len != 8) {
      93           1 :                 gnutls_assert();
      94           1 :                 ret = GNUTLS_E_ILLEGAL_PARAMETER;
      95           1 :                 goto error;
      96             :         }
      97             : 
      98          24 :         enc_params->cipher = GNUTLS_CIPHER_DES_CBC;
      99             : 
     100          24 :         ret = 0;
     101          31 :  error:
     102          31 :         asn1_delete_structure2(&pasn, ASN1_DELETE_FLAG_ZEROIZE);
     103          31 :         return ret;
     104             : 
     105             : }
     106             : 
     107          20 : static void pbkdf1_md5(const char *password, unsigned password_len,
     108             :         const uint8_t salt[8], unsigned iter_count, unsigned key_size, uint8_t *key)
     109             : {
     110          20 :         struct md5_ctx ctx;
     111          20 :         uint8_t tmp[16];
     112          20 :         unsigned i;
     113             : 
     114          20 :         if (key_size > sizeof(tmp))
     115           0 :                 abort();
     116             : 
     117       80324 :         for (i=0;i<iter_count;i++) {
     118       80304 :                 md5_init(&ctx);
     119       80304 :                 if (i==0) {
     120          20 :                         md5_update(&ctx, password_len, (uint8_t*)password);
     121          20 :                         md5_update(&ctx, 8, salt);
     122          20 :                         md5_digest(&ctx, 16, tmp);
     123             :                 } else {
     124       80284 :                         md5_update(&ctx, 16, tmp);
     125       80284 :                         md5_digest(&ctx, 16, tmp);
     126             :                 }
     127             :         }
     128             : 
     129          20 :         memcpy(key, tmp, key_size);
     130          20 :         return;
     131             : }
     132             : 
     133             : int
     134          22 : _gnutls_decrypt_pbes1_des_md5_data(const char *password,
     135             :                            unsigned password_len,
     136             :                            const struct pbkdf2_params *kdf_params,
     137             :                            const struct pbe_enc_params *enc_params,
     138             :                            const gnutls_datum_t *encrypted_data,
     139             :                            gnutls_datum_t *decrypted_data)
     140             : {
     141          22 :         int result;
     142          22 :         gnutls_datum_t dkey, d_iv;
     143          22 :         cipher_hd_st ch;
     144          22 :         uint8_t key[16];
     145          22 :         const unsigned block_size = 8;
     146             : 
     147          22 :         if (enc_params->cipher != GNUTLS_CIPHER_DES_CBC)
     148           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     149             : 
     150          22 :         if (encrypted_data->size % block_size != 0)
     151           2 :                 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
     152             : 
     153             :         /* generate the key
     154             :          */
     155          20 :         pbkdf1_md5(password, password_len, kdf_params->salt, kdf_params->iter_count, sizeof(key), key);
     156             : 
     157          20 :         dkey.data = key;
     158          20 :         dkey.size = 8;
     159          20 :         d_iv.data = &key[8];
     160          20 :         d_iv.size = 8;
     161          20 :         result =
     162          20 :             _gnutls_cipher_init(&ch, cipher_to_entry(GNUTLS_CIPHER_DES_CBC),
     163             :                                 &dkey, &d_iv, 0);
     164          20 :         if (result < 0)
     165           0 :                 return gnutls_assert_val(result);
     166             : 
     167          20 :         result = _gnutls_cipher_decrypt(&ch, encrypted_data->data, encrypted_data->size);
     168          20 :         if (result < 0) {
     169           0 :                 gnutls_assert();
     170           0 :                 goto error;
     171             :         }
     172             : 
     173          20 :         if ((int)encrypted_data->size - encrypted_data->data[encrypted_data->size - 1] < 0) {
     174           1 :                 gnutls_assert();
     175           1 :                 result = GNUTLS_E_ILLEGAL_PARAMETER;
     176           1 :                 goto error;
     177             :         }
     178             : 
     179          19 :         decrypted_data->data = encrypted_data->data;
     180          19 :         decrypted_data->size = encrypted_data->size - encrypted_data->data[encrypted_data->size - 1];
     181             : 
     182          19 :         result = 0;
     183          20 :  error:
     184          20 :         _gnutls_cipher_deinit(&ch);
     185             : 
     186             :         return result;
     187             : }
     188             : 

Generated by: LCOV version 1.14