Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/x509/prov-seed.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2017 Red Hat, Inc.
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
#include "datum.h"
25
#include "global.h"
26
#include "errors.h"
27
#include "common.h"
28
#include "x509.h"
29
#include "x509_int.h"
30
#include "mpi.h"
31
#include "prov-seed.h"
32
33
/* This function encodes a seed value and a hash algorithm OID to the format
34
 * described in RFC8479. The output is the DER encoded form.
35
 */
36
int _x509_encode_provable_seed(gnutls_x509_privkey_t pkey, gnutls_datum_t *der)
37
0
{
38
0
  asn1_node c2;
39
0
  int ret, result;
40
0
  const char *oid;
41
42
0
  oid = gnutls_digest_get_oid(pkey->params.palgo);
43
0
  if (oid == NULL)
44
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
45
46
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
47
0
            "GNUTLS.ProvableSeed", &c2)) !=
48
0
      ASN1_SUCCESS) {
49
0
    gnutls_assert();
50
0
    return _gnutls_asn2err(result);
51
0
  }
52
53
0
  result = asn1_write_value(c2, "seed", pkey->params.seed,
54
0
          pkey->params.seed_size);
55
0
  if (result != ASN1_SUCCESS) {
56
0
    gnutls_assert();
57
0
    ret = _gnutls_asn2err(result);
58
0
    goto cleanup;
59
0
  }
60
61
0
  result = asn1_write_value(c2, "algorithm", oid, 1);
62
0
  if (result != ASN1_SUCCESS) {
63
0
    gnutls_assert();
64
0
    ret = _gnutls_asn2err(result);
65
0
    goto cleanup;
66
0
  }
67
68
0
  ret = _gnutls_x509_der_encode(c2, "", der, 0);
69
0
  if (ret < 0) {
70
0
    gnutls_assert();
71
0
    goto cleanup;
72
0
  }
73
74
0
  ret = 0;
75
76
0
cleanup:
77
0
  asn1_delete_structure2(&c2, ASN1_DELETE_FLAG_ZEROIZE);
78
0
  return ret;
79
0
}
80
81
/* This function decodes a DER encoded form of seed and a hash algorithm, as in
82
 * RFC8479.
83
 */
84
int _x509_decode_provable_seed(gnutls_x509_privkey_t pkey,
85
             const gnutls_datum_t *der)
86
0
{
87
0
  asn1_node c2;
88
0
  int ret, result;
89
0
  char oid[MAX_OID_SIZE];
90
0
  int oid_size;
91
0
  gnutls_datum_t seed = { NULL, 0 };
92
93
0
  if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
94
0
            "GNUTLS.ProvableSeed", &c2)) !=
95
0
      ASN1_SUCCESS) {
96
0
    gnutls_assert();
97
0
    return _gnutls_asn2err(result);
98
0
  }
99
100
0
  result = _asn1_strict_der_decode(&c2, der->data, der->size, NULL);
101
0
  if (result != ASN1_SUCCESS) {
102
0
    gnutls_assert();
103
0
    ret = _gnutls_asn2err(result);
104
0
    goto cleanup;
105
0
  }
106
107
0
  ret = _gnutls_x509_read_value(c2, "seed", &seed);
108
0
  if (ret < 0) {
109
0
    gnutls_assert();
110
0
    goto cleanup;
111
0
  }
112
113
0
  if (seed.size <= sizeof(pkey->params.seed)) {
114
0
    memcpy(pkey->params.seed, seed.data, seed.size);
115
0
    pkey->params.seed_size = seed.size;
116
0
  } else {
117
0
    ret = 0; /* ignore struct */
118
0
    _gnutls_debug_log(
119
0
      "%s: ignoring ProvableSeed due to very long params\n",
120
0
      __func__);
121
0
    goto cleanup;
122
0
  }
123
124
0
  oid_size = sizeof(oid);
125
0
  result = asn1_read_value(c2, "algorithm", oid, &oid_size);
126
0
  if (result != ASN1_SUCCESS) {
127
0
    gnutls_assert();
128
0
    ret = _gnutls_asn2err(result);
129
0
    goto cleanup;
130
0
  }
131
132
0
  pkey->params.palgo = gnutls_oid_to_digest(oid);
133
0
  pkey->params.pkflags |= GNUTLS_PK_FLAG_PROVABLE;
134
135
0
  ret = 0;
136
137
0
cleanup:
138
0
  gnutls_free(seed.data);
139
0
  asn1_delete_structure2(&c2, ASN1_DELETE_FLAG_ZEROIZE);
140
0
  return ret;
141
0
}