Coverage Report

Created: 2025-03-18 06:55

/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
35
/* This file includes support for PKCS#8 PBES1 with DES and MD5.
36
 * We only support decryption for compatibility with other software.
37
 */
38
39
int _gnutls_read_pbkdf1_params(const uint8_t *data, int data_size,
40
             struct pbkdf2_params *kdf_params,
41
             struct pbe_enc_params *enc_params)
42
0
{
43
0
  asn1_node pasn = NULL;
44
0
  int len;
45
0
  int ret, result;
46
47
0
  memset(kdf_params, 0, sizeof(*kdf_params));
48
0
  memset(enc_params, 0, sizeof(*enc_params));
49
50
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
51
0
            "PKIX1.pkcs-5-PBE-params", &pasn)) !=
52
0
      ASN1_SUCCESS) {
53
0
    gnutls_assert();
54
0
    return _gnutls_asn2err(result);
55
0
  }
56
57
  /* Decode the parameters.
58
   */
59
0
  result = _asn1_strict_der_decode(&pasn, data, data_size, NULL);
60
0
  if (result != ASN1_SUCCESS) {
61
0
    gnutls_assert();
62
0
    ret = _gnutls_asn2err(result);
63
0
    goto error;
64
0
  }
65
66
0
  ret = _gnutls_x509_read_uint(pasn, "iterationCount",
67
0
             &kdf_params->iter_count);
68
0
  if (ret < 0) {
69
0
    gnutls_assert();
70
0
    goto error;
71
0
  }
72
73
0
  if (kdf_params->iter_count >= MAX_ITER_COUNT ||
74
0
      kdf_params->iter_count == 0) {
75
0
    ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
76
0
    goto error;
77
0
  }
78
79
0
  len = sizeof(kdf_params->salt);
80
0
  result = asn1_read_value(pasn, "salt", kdf_params->salt, &len);
81
0
  if (result != ASN1_SUCCESS) {
82
0
    gnutls_assert();
83
0
    ret = _gnutls_asn2err(result);
84
0
    goto error;
85
0
  }
86
87
0
  if (len != 8) {
88
0
    gnutls_assert();
89
0
    ret = GNUTLS_E_ILLEGAL_PARAMETER;
90
0
    goto error;
91
0
  }
92
93
0
  enc_params->cipher = GNUTLS_CIPHER_DES_CBC;
94
95
0
  ret = 0;
96
0
error:
97
0
  asn1_delete_structure2(&pasn, ASN1_DELETE_FLAG_ZEROIZE);
98
0
  return ret;
99
0
}
100
101
static int pbkdf1(gnutls_digest_algorithm_t dig, const char *password,
102
      unsigned password_len, const uint8_t salt[8],
103
      unsigned iter_count, unsigned key_size, uint8_t *key)
104
0
{
105
0
  uint8_t tmp[20];
106
0
  unsigned i;
107
0
  gnutls_hash_hd_t hd;
108
0
  int ret;
109
110
0
  if (key_size > sizeof(tmp))
111
0
    abort();
112
113
0
  ret = gnutls_hash_init(&hd, dig);
114
0
  if (ret < 0)
115
0
    return gnutls_assert_val(ret);
116
0
  ret = gnutls_hash(hd, (uint8_t *)password, password_len);
117
0
  if (ret < 0)
118
0
    return gnutls_assert_val(ret);
119
0
  ret = gnutls_hash(hd, salt, 8);
120
0
  if (ret < 0)
121
0
    return gnutls_assert_val(ret);
122
0
  gnutls_hash_deinit(hd, tmp);
123
124
0
  for (i = 1; i < iter_count; i++) {
125
0
    ret = gnutls_hash_init(&hd, dig);
126
0
    if (ret < 0)
127
0
      return gnutls_assert_val(ret);
128
0
    ret = gnutls_hash(hd, tmp, gnutls_hash_get_len(dig));
129
0
    if (ret < 0)
130
0
      return gnutls_assert_val(ret);
131
0
    gnutls_hash_deinit(hd, tmp);
132
0
  }
133
134
0
  memcpy(key, tmp, key_size);
135
0
  return 0;
136
0
}
137
138
static int _gnutls_decrypt_pbes1_des_data(
139
  gnutls_digest_algorithm_t dig, const char *password,
140
  unsigned password_len, const struct pbkdf2_params *kdf_params,
141
  const struct pbe_enc_params *enc_params,
142
  const gnutls_datum_t *encrypted_data, gnutls_datum_t *decrypted_data)
143
0
{
144
0
  int result;
145
0
  gnutls_datum_t dkey, d_iv;
146
0
  gnutls_cipher_hd_t ch;
147
0
  uint8_t key[20];
148
0
  const unsigned block_size = 8;
149
150
0
  if (enc_params->cipher != GNUTLS_CIPHER_DES_CBC)
151
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
152
153
0
  if (encrypted_data->size % block_size != 0)
154
0
    return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
155
156
  /* generate the key
157
   */
158
0
  result = pbkdf1(dig, password, password_len, kdf_params->salt,
159
0
      kdf_params->iter_count, gnutls_hash_get_len(dig), key);
160
0
  if (result < 0) {
161
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
162
0
    return gnutls_assert_val(result);
163
0
  }
164
165
0
  dkey.data = key;
166
0
  dkey.size = 8;
167
0
  d_iv.data = &key[8];
168
0
  d_iv.size = 8;
169
0
  result = gnutls_cipher_init(&ch, GNUTLS_CIPHER_DES_CBC, &dkey, &d_iv);
170
0
  if (result < 0) {
171
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
172
0
    return gnutls_assert_val(result);
173
0
  }
174
0
  _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
175
176
0
  result = gnutls_cipher_decrypt(ch, encrypted_data->data,
177
0
               encrypted_data->size);
178
0
  if (result < 0) {
179
0
    gnutls_assert();
180
0
    goto error;
181
0
  }
182
183
0
  if ((int)encrypted_data->size -
184
0
        encrypted_data->data[encrypted_data->size - 1] <
185
0
      0) {
186
0
    gnutls_assert();
187
0
    result = GNUTLS_E_ILLEGAL_PARAMETER;
188
0
    goto error;
189
0
  }
190
191
0
  decrypted_data->data = encrypted_data->data;
192
0
  decrypted_data->size = encrypted_data->size -
193
0
             encrypted_data->data[encrypted_data->size - 1];
194
195
0
  result = 0;
196
0
error:
197
0
  gnutls_cipher_deinit(ch);
198
199
0
  return result;
200
0
}
201
202
int _gnutls_decrypt_pbes1_des_md5_data(const char *password,
203
               unsigned password_len,
204
               const struct pbkdf2_params *kdf_params,
205
               const struct pbe_enc_params *enc_params,
206
               const gnutls_datum_t *encrypted_data,
207
               gnutls_datum_t *decrypted_data)
208
0
{
209
0
  return _gnutls_decrypt_pbes1_des_data(GNUTLS_DIG_MD5, password,
210
0
                password_len, kdf_params,
211
0
                enc_params, encrypted_data,
212
0
                decrypted_data);
213
0
}
214
215
int _gnutls_decrypt_pbes1_des_sha1_data(const char *password,
216
          unsigned password_len,
217
          const struct pbkdf2_params *kdf_params,
218
          const struct pbe_enc_params *enc_params,
219
          const gnutls_datum_t *encrypted_data,
220
          gnutls_datum_t *decrypted_data)
221
0
{
222
0
  return _gnutls_decrypt_pbes1_des_data(GNUTLS_DIG_SHA1, password,
223
0
                password_len, kdf_params,
224
0
                enc_params, encrypted_data,
225
0
                decrypted_data);
226
0
}