Line data Source code
1 : /*
2 : * Copyright (C) 2001-2016 Free Software Foundation, Inc.
3 : * Copyright (C) 2015-2017 Red Hat, Inc.
4 : *
5 : * Author: Nikos Mavrogiannopoulos
6 : *
7 : * This file is part of GnuTLS.
8 : *
9 : * The GnuTLS is free software; you can redistribute it and/or
10 : * modify it under the terms of the GNU Lesser General Public License
11 : * as published by the Free Software Foundation; either version 2.1 of
12 : * the License, or (at your option) any later version.
13 : *
14 : * This library is distributed in the hope that it will be useful, but
15 : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : * Lesser General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>
21 : *
22 : */
23 :
24 : /* Some of the stuff needed for Certificate authentication is contained
25 : * in this file.
26 : */
27 :
28 : #include "gnutls_int.h"
29 : #include "errors.h"
30 : #include <auth/cert.h>
31 : #include <datum.h>
32 : #include <mpi.h>
33 : #include <global.h>
34 : #include <algorithms.h>
35 : #include <dh.h>
36 : #include "str.h"
37 : #include <state.h>
38 : #include <auth.h>
39 : #include <x509.h>
40 : #include <str_array.h>
41 : #include <x509/verify-high.h>
42 : #include "x509/x509_int.h"
43 : #include "x509/common.h"
44 : #include "dh.h"
45 : #include "cert-cred.h"
46 :
47 :
48 : /*
49 : * Adds a public/private key pair to a certificate credential
50 : */
51 : int
52 11343 : _gnutls_certificate_credential_append_keypair(gnutls_certificate_credentials_t res,
53 : gnutls_privkey_t key,
54 : gnutls_str_array_t names,
55 : gnutls_pcert_st * crt,
56 : int nr)
57 : {
58 22686 : res->sorted_cert_idx = gnutls_realloc_fast(res->sorted_cert_idx,
59 11343 : (1 + res->ncerts) *
60 : sizeof(unsigned int));
61 11343 : if (res->sorted_cert_idx == NULL)
62 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
63 :
64 22686 : res->certs = gnutls_realloc_fast(res->certs,
65 11343 : (1 + res->ncerts) *
66 : sizeof(certs_st));
67 11343 : if (res->certs == NULL)
68 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
69 :
70 11343 : memset(&res->certs[res->ncerts], 0, sizeof(res->certs[0]));
71 :
72 11343 : res->certs[res->ncerts].cert_list = crt;
73 11343 : res->certs[res->ncerts].cert_list_length = nr;
74 11343 : res->certs[res->ncerts].names = names;
75 11343 : res->certs[res->ncerts].pkey = key;
76 :
77 11343 : if (_gnutls13_sign_get_compatible_with_privkey(key))
78 11278 : res->tls13_ok = 1;
79 :
80 : /* move RSA-PSS certificates before any RSA key.
81 : * Note that we cannot assume that any previous pointers
82 : * to sorted list are ok, due to the realloc in res->certs. */
83 11343 : if (crt->pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
84 : unsigned i,ridx;
85 : unsigned tmp;
86 :
87 45 : for (i=0;i<res->ncerts;i++) {
88 7 : ridx = res->sorted_cert_idx[i];
89 :
90 7 : if (res->certs[ridx].cert_list->pubkey->params.algo == GNUTLS_PK_RSA) {
91 7 : tmp = ridx;
92 7 : res->sorted_cert_idx[i] = res->ncerts;
93 7 : res->sorted_cert_idx[res->ncerts] = tmp;
94 7 : goto finish;
95 : }
96 : }
97 : }
98 :
99 : /* otherwise append it normally on the end */
100 11336 : res->sorted_cert_idx[res->ncerts] = res->ncerts;
101 :
102 : finish:
103 : return 0;
104 :
105 : }
106 :
107 :
108 : /**
109 : * gnutls_certificate_set_key:
110 : * @res: is a #gnutls_certificate_credentials_t type.
111 : * @names: is an array of DNS names belonging to the public-key (NULL if none)
112 : * @names_size: holds the size of the names list
113 : * @pcert_list: contains a certificate list (chain) or raw public-key
114 : * @pcert_list_size: holds the size of the certificate list
115 : * @key: is a #gnutls_privkey_t key corresponding to the first public-key in pcert_list
116 : *
117 : * This function sets a public/private key pair in the
118 : * gnutls_certificate_credentials_t type. The given public key may be encapsulated
119 : * in a certificate or can be given as a raw key. This function may be
120 : * called more than once, in case multiple key pairs exist for
121 : * the server. For clients that want to send more than their own end-
122 : * entity certificate (e.g., also an intermediate CA cert), the full
123 : * certificate chain must be provided in @pcert_list.
124 : *
125 : * Note that the @key will become part of the credentials structure and must
126 : * not be deallocated. It will be automatically deallocated when the @res structure
127 : * is deinitialized.
128 : *
129 : * If this function fails, the @res structure is at an undefined state and it must
130 : * not be reused to load other keys or certificates.
131 : *
132 : * Note that, this function by default returns zero on success and a negative value on error.
133 : * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
134 : * it returns an index (greater or equal to zero). That index can be used for other functions to refer to the added key-pair.
135 : *
136 : * Since GnuTLS 3.6.6 this function also handles raw public keys.
137 : *
138 : * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
139 : *
140 : * Since: 3.0
141 : **/
142 : int
143 63 : gnutls_certificate_set_key(gnutls_certificate_credentials_t res,
144 : const char **names,
145 : int names_size,
146 : gnutls_pcert_st * pcert_list,
147 : int pcert_list_size,
148 : gnutls_privkey_t key)
149 : {
150 63 : int ret, i;
151 63 : gnutls_str_array_t str_names;
152 63 : gnutls_pcert_st *new_pcert_list;
153 :
154 : /* Sanity checks */
155 : // Check for a valid credential struct
156 63 : if (res == NULL) {
157 0 : return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
158 : }
159 :
160 : // A complete key pair must be given
161 63 : if (pcert_list == NULL || key == NULL) {
162 0 : return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
163 : }
164 :
165 : /* Process the names, if any */
166 63 : _gnutls_str_array_init(&str_names);
167 :
168 63 : if (names != NULL && names_size > 0) {
169 54 : for (i = 0; i < names_size; i++) {
170 36 : ret =
171 72 : _gnutls_str_array_append_idna(&str_names, names[i],
172 36 : strlen(names[i]));
173 36 : if (ret < 0) {
174 0 : ret = gnutls_assert_val(ret);
175 0 : goto cleanup;
176 : }
177 : }
178 45 : } else if (names == NULL && pcert_list[0].type == GNUTLS_CRT_X509) {
179 45 : gnutls_x509_crt_t crt;
180 :
181 45 : ret = gnutls_x509_crt_init(&crt);
182 45 : if (ret < 0) {
183 0 : gnutls_assert();
184 0 : goto cleanup;
185 : }
186 :
187 45 : ret = gnutls_x509_crt_import(crt, &pcert_list[0].cert, GNUTLS_X509_FMT_DER);
188 45 : if (ret < 0) {
189 0 : gnutls_assert();
190 0 : gnutls_x509_crt_deinit(crt);
191 0 : goto cleanup;
192 : }
193 :
194 45 : ret = _gnutls_get_x509_name(crt, &str_names);
195 45 : gnutls_x509_crt_deinit(crt);
196 :
197 45 : if (ret < 0) {
198 0 : gnutls_assert();
199 0 : goto cleanup;
200 : }
201 : }
202 :
203 63 : if (res->pin.cb)
204 0 : gnutls_privkey_set_pin_function(key, res->pin.cb,
205 : res->pin.data);
206 :
207 63 : new_pcert_list = gnutls_malloc(sizeof(gnutls_pcert_st) * pcert_list_size);
208 63 : if (new_pcert_list == NULL) {
209 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
210 : }
211 63 : memcpy(new_pcert_list, pcert_list, sizeof(gnutls_pcert_st) * pcert_list_size);
212 :
213 63 : ret =
214 63 : _gnutls_certificate_credential_append_keypair(res, key, str_names,
215 : new_pcert_list,
216 : pcert_list_size);
217 63 : if (ret < 0) {
218 0 : gnutls_assert();
219 0 : gnutls_free(new_pcert_list);
220 0 : goto cleanup;
221 : }
222 :
223 63 : res->ncerts++;
224 :
225 : /* Unlike gnutls_certificate_set_x509_key, we deinitialize everything
226 : * local after a failure. That is because the caller is responsible for
227 : * freeing these values after a failure, and if we keep references we
228 : * lead to double freeing */
229 63 : if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
230 1 : gnutls_assert();
231 1 : gnutls_free(new_pcert_list);
232 1 : res->ncerts--;
233 1 : goto cleanup;
234 : }
235 :
236 62 : CRED_RET_SUCCESS(res);
237 :
238 1 : cleanup:
239 1 : _gnutls_str_array_clear(&str_names);
240 : return ret;
241 : }
242 :
243 : /**
244 : * gnutls_certificate_free_keys:
245 : * @sc: is a #gnutls_certificate_credentials_t type.
246 : *
247 : * This function will delete all the keys and the certificates associated
248 : * with the given credentials. This function must not be called when a
249 : * TLS negotiation that uses the credentials is in progress.
250 : *
251 : **/
252 6922 : void gnutls_certificate_free_keys(gnutls_certificate_credentials_t sc)
253 : {
254 6922 : unsigned i, j;
255 :
256 17884 : for (i = 0; i < sc->ncerts; i++) {
257 23014 : for (j = 0; j < sc->certs[i].cert_list_length; j++) {
258 12052 : gnutls_pcert_deinit(&sc->certs[i].cert_list[j]);
259 : }
260 10962 : gnutls_free(sc->certs[i].cert_list);
261 :
262 10979 : for (j = 0; j < sc->certs[i].ocsp_data_length; j++) {
263 17 : gnutls_free(sc->certs[i].ocsp_data[j].response.data);
264 : }
265 10962 : _gnutls_str_array_clear(&sc->certs[i].names);
266 10962 : gnutls_privkey_deinit(sc->certs[i].pkey);
267 : }
268 :
269 6922 : gnutls_free(sc->certs);
270 6922 : gnutls_free(sc->sorted_cert_idx);
271 :
272 6922 : sc->ncerts = 0;
273 6922 : }
274 :
275 : /**
276 : * gnutls_certificate_free_cas:
277 : * @sc: is a #gnutls_certificate_credentials_t type.
278 : *
279 : * This function was operational on very early versions of gnutls.
280 : * Due to internal refactorings and the fact that this was hardly ever
281 : * used, it is currently a no-op.
282 : *
283 : **/
284 0 : void gnutls_certificate_free_cas(gnutls_certificate_credentials_t sc)
285 : {
286 0 : return;
287 : }
288 :
289 : /**
290 : * gnutls_certificate_get_issuer:
291 : * @sc: is a #gnutls_certificate_credentials_t type.
292 : * @cert: is the certificate to find issuer for
293 : * @issuer: Will hold the issuer if any. Should be treated as constant.
294 : * @flags: Use zero or %GNUTLS_TL_GET_COPY
295 : *
296 : * This function will return the issuer of a given certificate.
297 : * If the flag %GNUTLS_TL_GET_COPY is specified a copy of the issuer
298 : * will be returned which must be freed using gnutls_x509_crt_deinit().
299 : * In that case the provided @issuer must not be initialized.
300 : *
301 : * As with gnutls_x509_trust_list_get_issuer() this function requires
302 : * the %GNUTLS_TL_GET_COPY flag in order to operate with PKCS#11 trust
303 : * lists in a thread-safe way.
304 : *
305 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
306 : * negative error value.
307 : *
308 : * Since: 3.0
309 : **/
310 : int
311 5 : gnutls_certificate_get_issuer(gnutls_certificate_credentials_t sc,
312 : gnutls_x509_crt_t cert,
313 : gnutls_x509_crt_t * issuer,
314 : unsigned int flags)
315 : {
316 5 : return gnutls_x509_trust_list_get_issuer(sc->tlist, cert, issuer,
317 : flags);
318 : }
319 :
320 : /**
321 : * gnutls_certificate_get_crt_raw:
322 : * @sc: is a #gnutls_certificate_credentials_t type.
323 : * @idx1: the index of the certificate chain if multiple are present
324 : * @idx2: the index of the certificate in the chain. Zero gives the server's certificate.
325 : * @cert: Will hold the DER encoded certificate.
326 : *
327 : * This function will return the DER encoded certificate of the
328 : * server or any other certificate on its certificate chain (based on @idx2).
329 : * The returned data should be treated as constant and only accessible during the lifetime
330 : * of @sc. The @idx1 matches the value gnutls_certificate_set_x509_key() and friends
331 : * functions.
332 : *
333 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
334 : * negative error value. In case the indexes are out of bounds %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
335 : * is returned.
336 : *
337 : * Since: 3.2.5
338 : **/
339 : int
340 64 : gnutls_certificate_get_crt_raw(gnutls_certificate_credentials_t sc,
341 : unsigned idx1,
342 : unsigned idx2, gnutls_datum_t * cert)
343 : {
344 64 : if (idx1 >= sc->ncerts)
345 0 : return
346 0 : gnutls_assert_val
347 : (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
348 :
349 64 : if (idx2 >= sc->certs[idx1].cert_list_length)
350 0 : return
351 0 : gnutls_assert_val
352 : (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
353 :
354 64 : cert->data = sc->certs[idx1].cert_list[idx2].cert.data;
355 64 : cert->size = sc->certs[idx1].cert_list[idx2].cert.size;
356 :
357 64 : return 0;
358 : }
359 :
360 : /**
361 : * gnutls_certificate_free_ca_names:
362 : * @sc: is a #gnutls_certificate_credentials_t type.
363 : *
364 : * This function will delete all the CA name in the given
365 : * credentials. Clients may call this to save some memory since in
366 : * client side the CA names are not used. Servers might want to use
367 : * this function if a large list of trusted CAs is present and
368 : * sending the names of it would just consume bandwidth without providing
369 : * information to client.
370 : *
371 : * CA names are used by servers to advertise the CAs they support to
372 : * clients.
373 : **/
374 0 : void gnutls_certificate_free_ca_names(gnutls_certificate_credentials_t sc)
375 : {
376 0 : _gnutls_free_datum(&sc->tlist->x509_rdn_sequence);
377 0 : }
378 :
379 :
380 : /**
381 : * gnutls_certificate_free_credentials:
382 : * @sc: is a #gnutls_certificate_credentials_t type.
383 : *
384 : * Free a gnutls_certificate_credentials_t structure.
385 : *
386 : * This function does not free any temporary parameters associated
387 : * with this structure (ie RSA and DH parameters are not freed by this
388 : * function).
389 : **/
390 : void
391 6922 : gnutls_certificate_free_credentials(gnutls_certificate_credentials_t sc)
392 : {
393 : // Check for valid pointer and otherwise do nothing
394 6922 : if (sc == NULL)
395 : return;
396 :
397 6922 : gnutls_x509_trust_list_deinit(sc->tlist, 1);
398 6922 : gnutls_certificate_free_keys(sc);
399 6922 : memset(sc->pin_tmp, 0, sizeof(sc->pin_tmp));
400 :
401 6922 : if (sc->deinit_dh_params) {
402 0 : gnutls_dh_params_deinit(sc->dh_params);
403 : }
404 :
405 6922 : gnutls_free(sc);
406 : }
407 :
408 :
409 : /**
410 : * gnutls_certificate_allocate_credentials:
411 : * @res: is a pointer to a #gnutls_certificate_credentials_t type.
412 : *
413 : * Allocate a gnutls_certificate_credentials_t structure.
414 : *
415 : * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
416 : **/
417 : int
418 7332 : gnutls_certificate_allocate_credentials(gnutls_certificate_credentials_t *
419 : res)
420 : {
421 7332 : int ret;
422 :
423 7332 : *res = gnutls_calloc(1, sizeof(certificate_credentials_st));
424 :
425 7332 : if (*res == NULL)
426 : return GNUTLS_E_MEMORY_ERROR;
427 :
428 7332 : ret = gnutls_x509_trust_list_init(&(*res)->tlist, 0);
429 7332 : if (ret < 0) {
430 0 : gnutls_assert();
431 0 : gnutls_free(*res);
432 0 : return GNUTLS_E_MEMORY_ERROR;
433 : }
434 7332 : (*res)->verify_bits = DEFAULT_MAX_VERIFY_BITS;
435 7332 : (*res)->verify_depth = DEFAULT_MAX_VERIFY_DEPTH;
436 :
437 :
438 7332 : return 0;
439 : }
440 :
441 : /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
442 : * space for them.
443 : */
444 8 : static gnutls_pcert_st *alloc_and_load_x509_certs(gnutls_x509_crt_t *
445 : certs, unsigned ncerts)
446 : {
447 8 : gnutls_pcert_st *local_certs;
448 8 : int ret = 0;
449 8 : unsigned i, j;
450 :
451 8 : if (certs == NULL)
452 : return NULL;
453 :
454 8 : local_certs = gnutls_malloc(sizeof(gnutls_pcert_st) * ncerts);
455 8 : if (local_certs == NULL) {
456 0 : gnutls_assert();
457 0 : return NULL;
458 : }
459 :
460 24 : for (i = 0; i < ncerts; i++) {
461 16 : ret = gnutls_pcert_import_x509(&local_certs[i], certs[i], 0);
462 16 : if (ret < 0)
463 : break;
464 : }
465 :
466 8 : if (ret < 0) {
467 0 : gnutls_assert();
468 0 : for (j = 0; j < i; j++) {
469 0 : gnutls_pcert_deinit(&local_certs[j]);
470 : }
471 0 : gnutls_free(local_certs);
472 0 : return NULL;
473 : }
474 :
475 : return local_certs;
476 : }
477 :
478 : /* converts the given x509 key to gnutls_privkey* and allocates
479 : * space for it.
480 : */
481 : static gnutls_privkey_t
482 8 : alloc_and_load_x509_key(gnutls_x509_privkey_t key, int deinit)
483 : {
484 8 : gnutls_privkey_t local_key;
485 8 : int ret = 0;
486 :
487 8 : if (key == NULL)
488 : return NULL;
489 :
490 8 : ret = gnutls_privkey_init(&local_key);
491 8 : if (ret < 0) {
492 0 : gnutls_assert();
493 0 : return NULL;
494 : }
495 :
496 8 : ret =
497 8 : gnutls_privkey_import_x509(local_key, key,
498 : deinit ?
499 : GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE : 0);
500 8 : if (ret < 0) {
501 0 : gnutls_assert();
502 0 : gnutls_privkey_deinit(local_key);
503 0 : return NULL;
504 : }
505 :
506 8 : return local_key;
507 : }
508 :
509 : #ifdef ENABLE_PKCS11
510 :
511 : /* converts the given raw key to gnutls_privkey* and allocates
512 : * space for it.
513 : */
514 : static gnutls_privkey_t
515 0 : alloc_and_load_pkcs11_key(gnutls_pkcs11_privkey_t key, int deinit)
516 : {
517 0 : gnutls_privkey_t local_key;
518 0 : int ret = 0;
519 :
520 0 : if (key == NULL)
521 : return NULL;
522 :
523 0 : ret = gnutls_privkey_init(&local_key);
524 0 : if (ret < 0) {
525 0 : gnutls_assert();
526 0 : return NULL;
527 : }
528 :
529 0 : ret =
530 0 : gnutls_privkey_import_pkcs11(local_key, key,
531 : deinit ?
532 : GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
533 : : 0);
534 0 : if (ret < 0) {
535 0 : gnutls_assert();
536 0 : gnutls_privkey_deinit(local_key);
537 0 : return NULL;
538 : }
539 :
540 0 : return local_key;
541 : }
542 :
543 : #endif
544 :
545 : /**
546 : * gnutls_certificate_server_set_request:
547 : * @session: is a #gnutls_session_t type.
548 : * @req: is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE, GNUTLS_CERT_IGNORE
549 : *
550 : * This function specifies if we (in case of a server) are going to
551 : * send a certificate request message to the client. If @req is
552 : * GNUTLS_CERT_REQUIRE then the server will return the %GNUTLS_E_NO_CERTIFICATE_FOUND
553 : * error if the peer does not provide a certificate. If you do not call this
554 : * function then the client will not be asked to send a certificate. Invoking
555 : * the function with @req GNUTLS_CERT_IGNORE has the same effect.
556 : **/
557 : void
558 10446 : gnutls_certificate_server_set_request(gnutls_session_t session,
559 : gnutls_certificate_request_t req)
560 : {
561 10446 : session->internals.send_cert_req = req;
562 10446 : }
563 :
564 9 : static int call_legacy_cert_cb1(gnutls_session_t session,
565 : const struct gnutls_cert_retr_st *info,
566 : gnutls_pcert_st **certs,
567 : unsigned int *pcert_length,
568 : gnutls_ocsp_data_st **ocsp,
569 : unsigned int *ocsp_length,
570 : gnutls_privkey_t *privkey,
571 : unsigned int *flags)
572 : {
573 9 : gnutls_retr2_st st2;
574 9 : gnutls_pcert_st *local_certs = NULL;
575 9 : gnutls_privkey_t local_key = NULL;
576 9 : unsigned i;
577 9 : int ret;
578 :
579 9 : *ocsp_length = 0;
580 :
581 9 : memset(&st2, 0, sizeof(st2));
582 :
583 18 : ret = info->cred->legacy_cert_cb1(session, info->req_ca_rdn, info->nreqs,
584 9 : info->pk_algos, info->pk_algos_length,
585 : &st2);
586 9 : if (ret < 0)
587 0 : return gnutls_assert_val(ret);
588 :
589 9 : if (st2.ncerts == 0) {
590 1 : *pcert_length = 0;
591 1 : *ocsp_length = 0;
592 1 : *privkey = NULL;
593 1 : return 0;
594 : }
595 :
596 8 : if (st2.cert_type != GNUTLS_CRT_X509) {
597 0 : gnutls_assert();
598 0 : ret = GNUTLS_E_INVALID_REQUEST;
599 0 : goto cleanup;
600 : }
601 :
602 8 : local_certs =
603 8 : alloc_and_load_x509_certs(st2.cert.x509, st2.ncerts);
604 8 : if (local_certs == NULL) {
605 0 : gnutls_assert();
606 0 : ret = GNUTLS_E_MEMORY_ERROR;
607 0 : goto cleanup;
608 : }
609 :
610 8 : switch (st2.key_type) {
611 : #ifdef ENABLE_PKCS11
612 0 : case GNUTLS_PRIVKEY_PKCS11:
613 0 : if (st2.key.pkcs11 != NULL) {
614 0 : local_key =
615 0 : alloc_and_load_pkcs11_key(st2.key.pkcs11,
616 0 : st2.deinit_all);
617 0 : if (local_key == NULL) {
618 0 : gnutls_assert();
619 0 : ret = GNUTLS_E_INTERNAL_ERROR;
620 0 : goto cleanup;
621 : }
622 : }
623 : break;
624 : #endif
625 8 : case GNUTLS_PRIVKEY_X509:
626 8 : if (st2.key.x509 != NULL) {
627 8 : local_key =
628 16 : alloc_and_load_x509_key(st2.key.x509,
629 8 : st2.deinit_all);
630 8 : if (local_key == NULL) {
631 0 : gnutls_assert();
632 0 : ret = GNUTLS_E_INTERNAL_ERROR;
633 0 : goto cleanup;
634 : }
635 : }
636 : break;
637 0 : default:
638 0 : gnutls_assert();
639 0 : ret = GNUTLS_E_INVALID_REQUEST;
640 0 : goto cleanup;
641 : }
642 :
643 8 : *privkey = local_key;
644 8 : *certs = local_certs;
645 8 : *pcert_length = st2.ncerts;
646 :
647 : /* flag the caller to deinitialize our values */
648 8 : *flags |= GNUTLS_CERT_RETR_DEINIT_ALL;
649 :
650 8 : ret = 0;
651 :
652 8 : cleanup:
653 :
654 8 : if (st2.cert_type == GNUTLS_CRT_X509) {
655 8 : if (st2.deinit_all) {
656 24 : for (i = 0; i < st2.ncerts; i++) {
657 16 : gnutls_x509_crt_deinit(st2.cert.x509[i]);
658 : }
659 8 : gnutls_free(st2.cert.x509);
660 : }
661 : }
662 :
663 : return ret;
664 :
665 : }
666 :
667 : /**
668 : * gnutls_certificate_set_retrieve_function:
669 : * @cred: is a #gnutls_certificate_credentials_t type.
670 : * @func: is the callback function
671 : *
672 : * This function sets a callback to be called in order to retrieve the
673 : * certificate to be used in the handshake. The callback will take control
674 : * only if a certificate is requested by the peer. You are advised
675 : * to use gnutls_certificate_set_retrieve_function2() because it
676 : * is much more efficient in the processing it requires from gnutls.
677 : *
678 : * The callback's function prototype is:
679 : * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
680 : * const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, gnutls_retr2_st* st);
681 : *
682 : * @req_ca_dn is only used in X.509 certificates.
683 : * Contains a list with the CA names that the server considers trusted.
684 : * This is a hint and typically the client should send a certificate that is signed
685 : * by one of these CAs. These names, when available, are DER encoded. To get a more
686 : * meaningful value use the function gnutls_x509_rdn_get().
687 : *
688 : * @pk_algos contains a list with server's acceptable public key algorithms.
689 : * The certificate returned should support the server's given algorithms.
690 : *
691 : * @st should contain the certificates and private keys.
692 : *
693 : * If the callback function is provided then gnutls will call it, in the
694 : * handshake, after the certificate request message has been received.
695 : *
696 : * In server side pk_algos and req_ca_dn are NULL.
697 : *
698 : * The callback function should set the certificate list to be sent,
699 : * and return 0 on success. If no certificate was selected then the
700 : * number of certificates should be set to zero. The value (-1)
701 : * indicates error and the handshake will be terminated. If both certificates
702 : * are set in the credentials and a callback is available, the callback
703 : * takes predence.
704 : *
705 : * Since: 3.0
706 : **/
707 11 : void gnutls_certificate_set_retrieve_function
708 : (gnutls_certificate_credentials_t cred,
709 : gnutls_certificate_retrieve_function * func)
710 : {
711 11 : cred->legacy_cert_cb1 = func;
712 11 : if (!func)
713 1 : cred->get_cert_callback3 = NULL;
714 : else
715 10 : cred->get_cert_callback3 = call_legacy_cert_cb1;
716 11 : }
717 :
718 219 : static int call_legacy_cert_cb2(gnutls_session_t session,
719 : const struct gnutls_cert_retr_st *info,
720 : gnutls_pcert_st **certs,
721 : unsigned int *pcert_length,
722 : gnutls_ocsp_data_st **ocsp,
723 : unsigned int *ocsp_length,
724 : gnutls_privkey_t *privkey,
725 : unsigned int *flags)
726 : {
727 219 : int ret;
728 219 : *ocsp_length = 0;
729 : /* flags will be assumed to be zero */
730 :
731 438 : ret = info->cred->legacy_cert_cb2(session, info->req_ca_rdn, info->nreqs,
732 219 : info->pk_algos, info->pk_algos_length,
733 : certs, pcert_length, privkey);
734 219 : if (ret < 0) {
735 0 : gnutls_assert();
736 : }
737 219 : return ret;
738 : }
739 :
740 : /**
741 : * gnutls_certificate_set_retrieve_function2:
742 : * @cred: is a #gnutls_certificate_credentials_t type.
743 : * @func: is the callback function
744 : *
745 : * This function sets a callback to be called in order to retrieve the
746 : * certificate to be used in the handshake. The callback will take control
747 : * only if a certificate is requested by the peer.
748 : *
749 : * The callback's function prototype is:
750 : * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
751 : * const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, gnutls_pcert_st** pcert,
752 : * unsigned int *pcert_length, gnutls_privkey_t * pkey);
753 : *
754 : * @req_ca_dn is only used in X.509 certificates.
755 : * Contains a list with the CA names that the server considers trusted.
756 : * This is a hint and typically the client should send a certificate that is signed
757 : * by one of these CAs. These names, when available, are DER encoded. To get a more
758 : * meaningful value use the function gnutls_x509_rdn_get().
759 : *
760 : * @pk_algos contains a list with server's acceptable public key algorithms.
761 : * The certificate returned should support the server's given algorithms.
762 : *
763 : * @pcert should contain a single certificate and public key or a list of them.
764 : *
765 : * @pcert_length is the size of the previous list.
766 : *
767 : * @pkey is the private key.
768 : *
769 : * If the callback function is provided then gnutls will call it, in the
770 : * handshake, after the certificate request message has been received.
771 : * All the provided by the callback values will not be released or
772 : * modified by gnutls.
773 : *
774 : * In server side pk_algos and req_ca_dn are NULL.
775 : *
776 : * The callback function should set the certificate list to be sent,
777 : * and return 0 on success. If no certificate was selected then the
778 : * number of certificates should be set to zero. The value (-1)
779 : * indicates error and the handshake will be terminated. If both certificates
780 : * are set in the credentials and a callback is available, the callback
781 : * takes predence.
782 : *
783 : * Since: 3.0
784 : **/
785 324 : void gnutls_certificate_set_retrieve_function2
786 : (gnutls_certificate_credentials_t cred,
787 : gnutls_certificate_retrieve_function2 * func)
788 : {
789 324 : cred->legacy_cert_cb2 = func;
790 324 : if (!func)
791 1 : cred->get_cert_callback3 = NULL;
792 : else
793 323 : cred->get_cert_callback3 = call_legacy_cert_cb2;
794 324 : }
795 :
796 : /**
797 : * gnutls_certificate_set_retrieve_function3:
798 : * @cred: is a #gnutls_certificate_credentials_t type.
799 : * @func: is the callback function
800 : *
801 : * This function sets a callback to be called in order to retrieve the
802 : * certificate and OCSP responses to be used in the handshake. @func will
803 : * be called only if the peer requests a certificate either during handshake
804 : * or during post-handshake authentication.
805 : *
806 : * The callback's function prototype is defined in `abstract.h':
807 : *
808 : * int gnutls_certificate_retrieve_function3(
809 : * gnutls_session_t,
810 : * const struct gnutls_cert_retr_st *info,
811 : * gnutls_pcert_st **certs,
812 : * unsigned int *pcert_length,
813 : * gnutls_ocsp_data_st **ocsp,
814 : * unsigned int *ocsp_length,
815 : * gnutls_privkey_t *privkey,
816 : * unsigned int *flags);
817 : *
818 : * The info field of the callback contains:
819 : * @req_ca_dn which is a list with the CA names that the server considers trusted.
820 : * This is a hint and typically the client should send a certificate that is signed
821 : * by one of these CAs. These names, when available, are DER encoded. To get a more
822 : * meaningful value use the function gnutls_x509_rdn_get().
823 : * @pk_algos contains a list with server's acceptable public key algorithms.
824 : * The certificate returned should support the server's given algorithms.
825 : *
826 : * The callback should fill-in the following values.
827 : *
828 : * @pcert should contain an allocated list of certificates and public keys.
829 : * @pcert_length is the size of the previous list.
830 : * @ocsp should contain an allocated list of OCSP responses.
831 : * @ocsp_length is the size of the previous list.
832 : * @pkey is the private key.
833 : *
834 : * If flags in the callback are set to %GNUTLS_CERT_RETR_DEINIT_ALL then
835 : * all provided values must be allocated using gnutls_malloc(), and will
836 : * be released by gnutls; otherwise they will not be touched by gnutls.
837 : *
838 : * The callback function should set the certificate and OCSP response
839 : * list to be sent, and return 0 on success. If no certificates are available,
840 : * the @pcert_length and @ocsp_length should be set to zero. The return
841 : * value (-1) indicates error and the handshake will be terminated. If both
842 : * certificates are set in the credentials and a callback is available, the
843 : * callback takes predence.
844 : *
845 : * Since: 3.6.3
846 : **/
847 7 : void gnutls_certificate_set_retrieve_function3
848 : (gnutls_certificate_credentials_t cred,
849 : gnutls_certificate_retrieve_function3 *func)
850 : {
851 7 : cred->get_cert_callback3 = func;
852 7 : }
853 :
854 : /**
855 : * gnutls_certificate_set_verify_function:
856 : * @cred: is a #gnutls_certificate_credentials_t type.
857 : * @func: is the callback function
858 : *
859 : * This function sets a callback to be called when peer's certificate
860 : * has been received in order to verify it on receipt rather than
861 : * doing after the handshake is completed.
862 : *
863 : * The callback's function prototype is:
864 : * int (*callback)(gnutls_session_t);
865 : *
866 : * If the callback function is provided then gnutls will call it, in the
867 : * handshake, just after the certificate message has been received.
868 : * To verify or obtain the certificate the gnutls_certificate_verify_peers2(),
869 : * gnutls_certificate_type_get(), gnutls_certificate_get_peers() functions
870 : * can be used.
871 : *
872 : * The callback function should return 0 for the handshake to continue
873 : * or non-zero to terminate.
874 : *
875 : * Since: 2.10.0
876 : **/
877 : void
878 10458 : gnutls_certificate_set_verify_function
879 : (gnutls_certificate_credentials_t cred,
880 : gnutls_certificate_verify_function * func)
881 : {
882 10458 : cred->verify_callback = func;
883 10458 : }
884 :
885 : /**
886 : * gnutls_x509_trust_list_set_getissuer_function:
887 : * @tlist: is a #gnutls_x509_trust_list_t type.
888 : * @func: is the callback function
889 : *
890 : * This function sets a callback to be called when the peer's certificate
891 : * chain is incomplete due a missing intermediate certificate/certificates.
892 : *
893 : * The callback's function prototype is defined in `abstract.h':
894 : * int (*callback)(
895 : * gnutls_x509_trust_list_t tlist,
896 : * const gnutls_x509_crt_t crt);
897 : *
898 : * If the callback function is provided then gnutls will call it, in the
899 : * certificate verification procedure.
900 : * To verify or obtain the certificate the verification functions such as
901 : * gnutls_x509_trust_list_verify_crt() and gnutls_x509_trust_list_verify_crt2()
902 : * can be used.
903 : *
904 : * The callback function should return 0 if the missing issuer certificate
905 : * for 'crt' was properly populated and added to the 'tlist' using
906 : * gnutls_x509_trust_list_add_cas() or non-zero to continue the certificate list
907 : * verification but with issuer as %NULL.
908 : *
909 : * Since: 3.7.0
910 : **/
911 2 : void gnutls_x509_trust_list_set_getissuer_function(gnutls_x509_trust_list_t tlist,
912 : gnutls_x509_trust_list_getissuer_function * func)
913 : {
914 2 : tlist->issuer_callback = func;
915 2 : }
916 :
917 : /**
918 : * gnutls_x509_trust_list_set_ptr:
919 : * @tlist: is a #gnutls_x509_trust_list_t type.
920 : * @ptr: is the user pointer
921 : *
922 : * This function will set (associate) the user given pointer @ptr to
923 : * the tlist structure. This pointer can be accessed with
924 : * gnutls_x509_trust_list_get_ptr(). Useful in the callback function
925 : * gnutls_x509_trust_list_set_getissuer_function.
926 : *
927 : * Since: 3.7.0
928 : **/
929 0 : void gnutls_x509_trust_list_set_ptr(gnutls_x509_trust_list_t tlist, void *ptr)
930 : {
931 0 : tlist->usr_ptr = ptr;
932 0 : }
933 :
934 : /**
935 : * gnutls_x509_trust_list_get_ptr:
936 : * @tlist: is a #gnutls_x509_trust_list_t type.
937 : *
938 : * Get user pointer for tlist. Useful in callback function
939 : * gnutls_x509_trust_list_set_getissuer_function.
940 : * This is the pointer set with gnutls_x509_trust_list_set_ptr().
941 : *
942 : * Returns: the user given pointer from the tlist structure, or
943 : * %NULL if it was never set.
944 : *
945 : * Since: 3.7.0
946 : **/
947 0 : void *gnutls_x509_trust_list_get_ptr(gnutls_x509_trust_list_t tlist)
948 : {
949 0 : return tlist->usr_ptr;
950 : }
951 :
952 : #define TEST_TEXT "test text"
953 : /* returns error if the certificate has different algorithm than
954 : * the given key parameters.
955 : */
956 11343 : int _gnutls_check_key_cert_match(gnutls_certificate_credentials_t res)
957 : {
958 11343 : gnutls_datum_t test = {(void*)TEST_TEXT, sizeof(TEST_TEXT)-1};
959 11343 : gnutls_datum_t sig = {NULL, 0};
960 11343 : gnutls_digest_algorithm_t dig;
961 11343 : int pk, pk2, ret;
962 11343 : unsigned sign_algo;
963 :
964 11343 : if (res->flags & GNUTLS_CERTIFICATE_SKIP_KEY_CERT_MATCH)
965 : return 0;
966 :
967 11340 : pk =
968 11340 : gnutls_pubkey_get_pk_algorithm(res->certs[res->ncerts - 1].
969 : cert_list[0].pubkey, NULL);
970 11340 : pk2 =
971 11340 : gnutls_privkey_get_pk_algorithm(res->certs[res->ncerts - 1].pkey,
972 : NULL);
973 :
974 11340 : if (GNUTLS_PK_IS_RSA(pk) && GNUTLS_PK_IS_RSA(pk2)) {
975 4493 : if (pk2 == GNUTLS_PK_RSA_PSS && pk == GNUTLS_PK_RSA) {
976 0 : _gnutls_debug_log("you cannot mix an RSA-PSS key with an RSA certificate\n");
977 0 : return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
978 : }
979 :
980 4493 : if (pk2 == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA_PSS)
981 : pk = GNUTLS_PK_RSA_PSS;
982 6847 : } else if (pk2 != pk) {
983 2 : gnutls_assert();
984 2 : _gnutls_debug_log("key is %s, certificate is %s\n", gnutls_pk_get_name(pk2),
985 : gnutls_pk_get_name(pk));
986 2 : return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
987 : }
988 :
989 11293 : if (pk == GNUTLS_PK_GOST_01)
990 : dig = GNUTLS_DIG_GOSTR_94;
991 11338 : else if (pk == GNUTLS_PK_GOST_12_256)
992 : dig = GNUTLS_DIG_STREEBOG_256;
993 11327 : else if (pk == GNUTLS_PK_GOST_12_512)
994 : dig = GNUTLS_DIG_STREEBOG_512;
995 : else
996 11315 : dig = GNUTLS_DIG_SHA256;
997 :
998 11338 : sign_algo = gnutls_pk_to_sign(pk, dig);
999 :
1000 : /* now check if keys really match. We use the sign/verify approach
1001 : * because we cannot always obtain the parameters from the abstract
1002 : * keys (e.g. PKCS #11). */
1003 11338 : ret = gnutls_privkey_sign_data2(res->certs[res->ncerts - 1].pkey,
1004 : sign_algo, 0, &test, &sig);
1005 11338 : if (ret < 0) {
1006 : /* for some reason we couldn't sign that. That shouldn't have
1007 : * happened, but since it did, report the issue and do not
1008 : * try the key matching test */
1009 4074 : _gnutls_debug_log("%s: failed signing\n", __func__);
1010 4074 : goto finish;
1011 : }
1012 :
1013 7264 : ret = gnutls_pubkey_verify_data2(res->certs[res->ncerts - 1].cert_list[0].pubkey,
1014 : sign_algo,
1015 : GNUTLS_VERIFY_ALLOW_BROKEN, &test, &sig);
1016 :
1017 7264 : gnutls_free(sig.data);
1018 :
1019 7264 : if (ret < 0)
1020 1 : return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
1021 :
1022 7263 : finish:
1023 : return 0;
1024 : }
1025 :
1026 : /**
1027 : * gnutls_certificate_verification_status_print:
1028 : * @status: The status flags to be printed
1029 : * @type: The certificate type
1030 : * @out: Newly allocated datum with (0) terminated string.
1031 : * @flags: should be zero
1032 : *
1033 : * This function will pretty print the status of a verification
1034 : * process -- eg. the one obtained by gnutls_certificate_verify_peers3().
1035 : *
1036 : * The output @out needs to be deallocated using gnutls_free().
1037 : *
1038 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1039 : * negative error value.
1040 : *
1041 : * Since: 3.1.4
1042 : **/
1043 : int
1044 777 : gnutls_certificate_verification_status_print(unsigned int status,
1045 : gnutls_certificate_type_t
1046 : type, gnutls_datum_t * out,
1047 : unsigned int flags)
1048 : {
1049 777 : gnutls_buffer_st str;
1050 :
1051 777 : _gnutls_buffer_init(&str);
1052 :
1053 777 : if (status == 0)
1054 497 : _gnutls_buffer_append_str(&str,
1055 497 : _
1056 : ("The certificate is trusted. "));
1057 : else
1058 280 : _gnutls_buffer_append_str(&str,
1059 280 : _
1060 : ("The certificate is NOT trusted. "));
1061 :
1062 777 : if (type == GNUTLS_CRT_X509) {
1063 777 : if (status & GNUTLS_CERT_REVOKED)
1064 12 : _gnutls_buffer_append_str(&str,
1065 12 : _
1066 : ("The certificate chain is revoked. "));
1067 :
1068 777 : if (status & GNUTLS_CERT_MISMATCH)
1069 0 : _gnutls_buffer_append_str(&str,
1070 0 : _
1071 : ("The certificate doesn't match the local copy (TOFU). "));
1072 :
1073 777 : if (status & GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED)
1074 2 : _gnutls_buffer_append_str(&str,
1075 2 : _
1076 : ("The revocation or OCSP data are old and have been superseded. "));
1077 :
1078 777 : if (status & GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE)
1079 0 : _gnutls_buffer_append_str(&str,
1080 0 : _
1081 : ("The revocation or OCSP data are issued with a future date. "));
1082 :
1083 777 : if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1084 181 : _gnutls_buffer_append_str(&str,
1085 181 : _
1086 : ("The certificate issuer is unknown. "));
1087 :
1088 777 : if (status & GNUTLS_CERT_SIGNER_NOT_CA)
1089 8 : _gnutls_buffer_append_str(&str,
1090 8 : _
1091 : ("The certificate issuer is not a CA. "));
1092 : }
1093 :
1094 777 : if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1095 34 : _gnutls_buffer_append_str(&str,
1096 34 : _
1097 : ("The certificate chain uses insecure algorithm. "));
1098 :
1099 777 : if (status & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE)
1100 25 : _gnutls_buffer_append_str(&str,
1101 25 : _
1102 : ("The certificate chain violates the signer's constraints. "));
1103 :
1104 777 : if (status & GNUTLS_CERT_PURPOSE_MISMATCH)
1105 0 : _gnutls_buffer_append_str(&str,
1106 0 : _
1107 : ("The certificate chain does not match the intended purpose. "));
1108 :
1109 777 : if (status & GNUTLS_CERT_NOT_ACTIVATED)
1110 6 : _gnutls_buffer_append_str(&str,
1111 6 : _
1112 : ("The certificate chain uses not yet valid certificate. "));
1113 :
1114 777 : if (status & GNUTLS_CERT_EXPIRED)
1115 28 : _gnutls_buffer_append_str(&str,
1116 28 : _
1117 : ("The certificate chain uses expired certificate. "));
1118 :
1119 777 : if (status & GNUTLS_CERT_SIGNATURE_FAILURE)
1120 12 : _gnutls_buffer_append_str(&str,
1121 12 : _
1122 : ("The signature in the certificate is invalid. "));
1123 :
1124 777 : if (status & GNUTLS_CERT_UNEXPECTED_OWNER)
1125 146 : _gnutls_buffer_append_str(&str,
1126 146 : _
1127 : ("The name in the certificate does not match the expected. "));
1128 :
1129 777 : if (status & GNUTLS_CERT_MISSING_OCSP_STATUS)
1130 2 : _gnutls_buffer_append_str(&str,
1131 2 : _
1132 : ("The certificate requires the server to include an OCSP status in its response, but the OCSP status is missing. "));
1133 :
1134 777 : if (status & GNUTLS_CERT_INVALID_OCSP_STATUS)
1135 3 : _gnutls_buffer_append_str(&str,
1136 3 : _
1137 : ("The received OCSP status response is invalid. "));
1138 :
1139 777 : if (status & GNUTLS_CERT_UNKNOWN_CRIT_EXTENSIONS)
1140 15 : _gnutls_buffer_append_str(&str,
1141 15 : _
1142 : ("The certificate contains an unknown critical extension. "));
1143 :
1144 777 : return _gnutls_buffer_to_datum(&str, out, 1);
1145 : }
1146 :
1147 : #if defined(ENABLE_DHE) || defined(ENABLE_ANON)
1148 : /**
1149 : * gnutls_certificate_set_dh_params:
1150 : * @res: is a gnutls_certificate_credentials_t type
1151 : * @dh_params: the Diffie-Hellman parameters.
1152 : *
1153 : * This function will set the Diffie-Hellman parameters for a
1154 : * certificate server to use. These parameters will be used in
1155 : * Ephemeral Diffie-Hellman cipher suites. Note that only a pointer
1156 : * to the parameters are stored in the certificate handle, so you
1157 : * must not deallocate the parameters before the certificate is deallocated.
1158 : *
1159 : * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
1160 : * or later. Since 3.6.0, DH parameters are negotiated
1161 : * following RFC7919.
1162 : *
1163 : **/
1164 : void
1165 228 : gnutls_certificate_set_dh_params(gnutls_certificate_credentials_t res,
1166 : gnutls_dh_params_t dh_params)
1167 : {
1168 228 : if (res->deinit_dh_params) {
1169 0 : res->deinit_dh_params = 0;
1170 0 : gnutls_dh_params_deinit(res->dh_params);
1171 0 : res->dh_params = NULL;
1172 : }
1173 :
1174 228 : res->dh_params = dh_params;
1175 228 : res->dh_sec_param = gnutls_pk_bits_to_sec_param(GNUTLS_PK_DH, _gnutls_mpi_get_nbits(dh_params->params[0]));
1176 228 : }
1177 :
1178 :
1179 : /**
1180 : * gnutls_certificate_set_known_dh_params:
1181 : * @res: is a gnutls_certificate_credentials_t type
1182 : * @sec_param: is an option of the %gnutls_sec_param_t enumeration
1183 : *
1184 : * This function will set the Diffie-Hellman parameters for a
1185 : * certificate server to use. These parameters will be used in
1186 : * Ephemeral Diffie-Hellman cipher suites and will be selected from
1187 : * the FFDHE set of RFC7919 according to the security level provided.
1188 : *
1189 : * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
1190 : * or later. Since 3.6.0, DH parameters are negotiated
1191 : * following RFC7919.
1192 : *
1193 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1194 : * negative error value.
1195 : *
1196 : * Since: 3.5.6
1197 : **/
1198 : int
1199 2672 : gnutls_certificate_set_known_dh_params(gnutls_certificate_credentials_t res,
1200 : gnutls_sec_param_t sec_param)
1201 : {
1202 2672 : res->dh_sec_param = sec_param;
1203 :
1204 2672 : return 0;
1205 : }
1206 :
1207 : #endif /* DH */
|