Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/privkey_pkcs8_pbes1.c
Line
Count
Source (jump to first uncovered line)
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
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
0
{
44
0
  asn1_node pasn = NULL;
45
0
  int len;
46
0
  int ret, result;
47
48
0
  memset(kdf_params, 0, sizeof(*kdf_params));
49
0
  memset(enc_params, 0, sizeof(*enc_params));
50
51
0
  if ((result =
52
0
       asn1_create_element(_gnutls_get_pkix(),
53
0
         "PKIX1.pkcs-5-PBE-params",
54
0
         &pasn)) != ASN1_SUCCESS) {
55
0
    gnutls_assert();
56
0
    return _gnutls_asn2err(result);
57
0
  }
58
59
  /* Decode the parameters.
60
   */
61
0
  result = _asn1_strict_der_decode(&pasn, data, data_size, NULL);
62
0
  if (result != ASN1_SUCCESS) {
63
0
    gnutls_assert();
64
0
    ret = _gnutls_asn2err(result);
65
0
    goto error;
66
0
  }
67
68
0
  ret =
69
0
      _gnutls_x509_read_uint(pasn, "iterationCount",
70
0
           &kdf_params->iter_count);
71
0
  if (ret < 0) {
72
0
    gnutls_assert();
73
0
    goto error;
74
0
  }
75
76
0
  if (kdf_params->iter_count >= MAX_ITER_COUNT
77
0
      || kdf_params->iter_count == 0) {
78
0
    ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
79
0
    goto error;
80
0
  }
81
82
0
  len = sizeof(kdf_params->salt);
83
0
  result = asn1_read_value(pasn, "salt", kdf_params->salt, &len);
84
0
  if (result != ASN1_SUCCESS) {
85
0
    gnutls_assert();
86
0
    ret = _gnutls_asn2err(result);
87
0
    goto error;
88
0
  }
89
90
0
  if (len != 8) {
91
0
    gnutls_assert();
92
0
    ret = GNUTLS_E_ILLEGAL_PARAMETER;
93
0
    goto error;
94
0
  }
95
96
0
  enc_params->cipher = GNUTLS_CIPHER_DES_CBC;
97
98
0
  ret = 0;
99
0
 error:
100
0
  asn1_delete_structure2(&pasn, ASN1_DELETE_FLAG_ZEROIZE);
101
0
  return ret;
102
103
0
}
104
105
static void pbkdf1_md5(const char *password, unsigned password_len,
106
           const uint8_t salt[8], unsigned iter_count,
107
           unsigned key_size, uint8_t * key)
108
0
{
109
0
  struct md5_ctx ctx;
110
0
  uint8_t tmp[16];
111
0
  unsigned i;
112
113
0
  if (key_size > sizeof(tmp))
114
0
    abort();
115
116
0
  for (i = 0; i < iter_count; i++) {
117
0
    md5_init(&ctx);
118
0
    if (i == 0) {
119
0
      md5_update(&ctx, password_len, (uint8_t *) password);
120
0
      md5_update(&ctx, 8, salt);
121
0
      md5_digest(&ctx, 16, tmp);
122
0
    } else {
123
0
      md5_update(&ctx, 16, tmp);
124
0
      md5_digest(&ctx, 16, tmp);
125
0
    }
126
0
  }
127
128
0
  memcpy(key, tmp, key_size);
129
0
  return;
130
0
}
131
132
int
133
_gnutls_decrypt_pbes1_des_md5_data(const char *password,
134
           unsigned password_len,
135
           const struct pbkdf2_params *kdf_params,
136
           const struct pbe_enc_params *enc_params,
137
           const gnutls_datum_t * encrypted_data,
138
           gnutls_datum_t * decrypted_data)
139
0
{
140
0
  int result;
141
0
  gnutls_datum_t dkey, d_iv;
142
0
  gnutls_cipher_hd_t ch;
143
0
  uint8_t key[16];
144
0
  const unsigned block_size = 8;
145
146
0
  if (enc_params->cipher != GNUTLS_CIPHER_DES_CBC)
147
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
148
149
0
  if (encrypted_data->size % block_size != 0)
150
0
    return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
151
152
  /* generate the key
153
   */
154
0
  pbkdf1_md5(password, password_len, kdf_params->salt,
155
0
       kdf_params->iter_count, sizeof(key), key);
156
157
0
  dkey.data = key;
158
0
  dkey.size = 8;
159
0
  d_iv.data = &key[8];
160
0
  d_iv.size = 8;
161
0
  result = gnutls_cipher_init(&ch, GNUTLS_CIPHER_DES_CBC, &dkey, &d_iv);
162
0
  if (result < 0) {
163
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
164
0
    return gnutls_assert_val(result);
165
0
  }
166
0
  _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
167
168
0
  result =
169
0
      gnutls_cipher_decrypt(ch, encrypted_data->data,
170
0
          encrypted_data->size);
171
0
  if (result < 0) {
172
0
    gnutls_assert();
173
0
    goto error;
174
0
  }
175
176
0
  if ((int)encrypted_data->size -
177
0
      encrypted_data->data[encrypted_data->size - 1] < 0) {
178
0
    gnutls_assert();
179
0
    result = GNUTLS_E_ILLEGAL_PARAMETER;
180
0
    goto error;
181
0
  }
182
183
0
  decrypted_data->data = encrypted_data->data;
184
0
  decrypted_data->size =
185
0
      encrypted_data->size - encrypted_data->data[encrypted_data->size -
186
0
              1];
187
188
0
  result = 0;
189
0
 error:
190
0
  gnutls_cipher_deinit(ch);
191
192
0
  return result;
193
0
}