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