2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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 3 of
11 * the License, or (at your option) any later version.
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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include "gnutls_auth.h"
25 #include "gnutls_errors.h"
26 #include <auth/cert.h>
27 #include "gnutls_dh.h"
28 #include "gnutls_num.h"
29 #include "gnutls_datum.h"
30 #include <gnutls_pk.h>
31 #include <algorithms.h>
32 #include <gnutls_global.h>
33 #include <gnutls_record.h>
34 #include <gnutls_sig.h>
35 #include <gnutls_state.h>
36 #include <gnutls_pk.h>
37 #include <gnutls_str.h>
40 #include <gnutls_x509.h>
41 #include <gnutls/ocsp.h>
42 #include "x509/common.h"
43 #include "x509/x509_int.h"
44 #include <gnutls_str_array.h>
45 #include "read-file.h"
47 # include <wincrypt.h>
51 * some x509 certificate parsing functions.
54 /* Check if the number of bits of the key in the certificate
58 check_bits (gnutls_session_t session
, gnutls_x509_crt_t crt
, unsigned int max_bits
)
63 ret
= gnutls_x509_crt_get_pk_algorithm (crt
, &bits
);
71 if (bits
> max_bits
&& max_bits
> 0)
74 return GNUTLS_E_CONSTRAINT_ERROR
;
77 if (gnutls_pk_bits_to_sec_param(pk
, bits
) == GNUTLS_SEC_PARAM_INSECURE
)
80 _gnutls_audit_log(session
, "The security level of the certificate (%s: %u) is weak\n", gnutls_pk_get_name(pk
), bits
);
81 if (session
->internals
.priorities
.allow_weak_keys
== 0)
82 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR
);
89 #define MAX_OCSP_VALIDITY_SECS (3*60*60*24)
91 /* If the certificate is revoked status will be GNUTLS_CERT_REVOKED.
94 * Zero on success, a negative error code otherwise.
97 check_ocsp_response (gnutls_session_t session
, gnutls_x509_crt_t cert
,
98 gnutls_x509_crt_t issuer
,
99 gnutls_datum_t
*data
, unsigned int * ostatus
)
101 gnutls_ocsp_resp_t resp
;
103 unsigned int status
, cert_status
;
104 time_t rtime
, vtime
, ntime
, now
;
105 int check_failed
= 0;
107 now
= gnutls_time(0);
109 ret
= gnutls_ocsp_resp_init (&resp
);
111 return gnutls_assert_val(ret
);
113 ret
= gnutls_ocsp_resp_import (resp
, data
);
116 _gnutls_audit_log (session
, "There was an error parsing the OCSP response: %s.\n", gnutls_strerror(ret
));
117 ret
= gnutls_assert_val(0);
122 ret
= gnutls_ocsp_resp_check_crt(resp
, 0, cert
);
125 ret
= gnutls_assert_val(0);
126 _gnutls_audit_log (session
, "Got OCSP response with an unrelated certificate.\n");
131 ret
= gnutls_ocsp_resp_verify_direct( resp
, issuer
, &status
, 0);
134 ret
= gnutls_assert_val(0);
140 /* do not consider revocation data if response was not verified */
143 ret
= gnutls_assert_val(0);
148 ret
= gnutls_ocsp_resp_get_single(resp
, 0, NULL
, NULL
, NULL
, NULL
,
149 &cert_status
, &vtime
, &ntime
, &rtime
, NULL
);
152 _gnutls_audit_log (session
, "There was an error parsing the OCSP response: %s.\n", gnutls_strerror(ret
));
153 ret
= gnutls_assert_val(0);
158 if (cert_status
== GNUTLS_OCSP_CERT_REVOKED
)
160 _gnutls_audit_log(session
, "The certificate was revoked via OCSP\n");
162 *ostatus
|= GNUTLS_CERT_REVOKED
;
163 ret
= gnutls_assert_val(0);
167 /* Report but do not fail on the following errors. That is
168 * because including the OCSP response in the handshake shouldn't
169 * cause more problems that not including it.
173 if (now
- vtime
> MAX_OCSP_VALIDITY_SECS
)
175 _gnutls_audit_log(session
, "The OCSP response is old\n");
182 /* there is a newer OCSP answer, don't trust this one */
185 _gnutls_audit_log(session
, "There is a newer OCSP response but was not provided by the server\n");
193 if (check_failed
== 0)
194 session
->internals
.ocsp_check_ok
= 1;
196 gnutls_ocsp_resp_deinit (resp
);
202 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
203 if (peer_certificate_list[x]) \
204 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
206 gnutls_free( peer_certificate_list)
209 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
210 * @session: is a gnutls session
212 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
213 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
214 * However you must also check the peer's name in order to check if the verified certificate belongs to the
215 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
218 _gnutls_x509_cert_verify_peers (gnutls_session_t session
,
219 const char* hostname
,
220 unsigned int *status
)
222 cert_auth_info_t info
;
223 gnutls_certificate_credentials_t cred
;
224 gnutls_x509_crt_t
*peer_certificate_list
;
226 int peer_certificate_list_size
, i
, x
, ret
;
227 gnutls_x509_crt_t issuer
;
228 unsigned int ocsp_status
= 0;
229 unsigned int verify_flags
;
231 /* No OCSP check so far */
232 session
->internals
.ocsp_check_ok
= 0;
234 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, GNUTLS_E_INVALID_REQUEST
);
236 info
= _gnutls_get_auth_info (session
);
240 return GNUTLS_E_INVALID_REQUEST
;
243 cred
= (gnutls_certificate_credentials_t
)
244 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
248 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
251 if (info
->raw_certificate_list
== NULL
|| info
->ncerts
== 0)
252 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
254 if (info
->ncerts
> cred
->verify_depth
&& cred
->verify_depth
> 0)
257 return GNUTLS_E_CONSTRAINT_ERROR
;
260 verify_flags
= cred
->verify_flags
| session
->internals
.priorities
.additional_verify_flags
;
261 /* generate a list of gnutls_certs based on the auth info
264 peer_certificate_list_size
= info
->ncerts
;
265 peer_certificate_list
=
266 gnutls_calloc (peer_certificate_list_size
, sizeof (gnutls_x509_crt_t
));
267 if (peer_certificate_list
== NULL
)
270 return GNUTLS_E_MEMORY_ERROR
;
273 for (i
= 0; i
< peer_certificate_list_size
; i
++)
275 ret
= gnutls_x509_crt_init (&peer_certificate_list
[i
]);
284 gnutls_x509_crt_import (peer_certificate_list
[i
],
285 &info
->raw_certificate_list
[i
],
286 GNUTLS_X509_FMT_DER
);
294 ret
= check_bits (session
, peer_certificate_list
[i
], cred
->verify_bits
);
304 /* Use the OCSP extension if any */
305 if (verify_flags
& GNUTLS_VERIFY_DISABLE_CRL_CHECKS
)
308 ret
= gnutls_ocsp_status_request_get(session
, &resp
);
312 if (peer_certificate_list_size
> 1)
313 issuer
= peer_certificate_list
[1];
316 ret
= gnutls_x509_trust_list_get_issuer(cred
->tlist
, peer_certificate_list
[0],
324 ret
= check_ocsp_response(session
, peer_certificate_list
[0], issuer
, &resp
, &ocsp_status
);
328 return gnutls_assert_val(ret
);
332 /* Verify certificate
334 ret
= gnutls_x509_trust_list_verify_crt (cred
->tlist
, peer_certificate_list
,
335 peer_certificate_list_size
,
336 verify_flags
, status
, NULL
);
347 ret
= gnutls_x509_crt_check_hostname( peer_certificate_list
[0], hostname
);
349 *status
|= GNUTLS_CERT_UNEXPECTED_OWNER
;
354 *status
|= ocsp_status
;
359 /* Returns the name of the certificate of a null name
361 static int get_x509_name(gnutls_x509_crt_t crt
, gnutls_str_array_t
*names
)
364 int i
, ret
= 0, ret2
;
367 for (i
= 0; !(ret
< 0); i
++)
369 max_size
= sizeof(name
);
371 ret
= gnutls_x509_crt_get_subject_alt_name(crt
, i
, name
, &max_size
, NULL
);
372 if (ret
== GNUTLS_SAN_DNSNAME
)
374 ret2
= _gnutls_str_array_append(names
, name
, max_size
);
377 _gnutls_str_array_clear(names
);
378 return gnutls_assert_val(ret2
);
383 max_size
= sizeof(name
);
384 ret
= gnutls_x509_crt_get_dn_by_oid (crt
, OID_X520_COMMON_NAME
, 0, 0, name
, &max_size
);
387 ret
= _gnutls_str_array_append(names
, name
, max_size
);
390 _gnutls_str_array_clear(names
);
391 return gnutls_assert_val(ret
);
398 static int get_x509_name_raw(gnutls_datum_t
*raw
, gnutls_x509_crt_fmt_t type
, gnutls_str_array_t
*names
)
401 gnutls_x509_crt_t crt
;
403 ret
= gnutls_x509_crt_init (&crt
);
410 ret
= gnutls_x509_crt_import (crt
, raw
, type
);
414 gnutls_x509_crt_deinit (crt
);
418 ret
= get_x509_name(crt
, names
);
419 gnutls_x509_crt_deinit (crt
);
423 /* Reads a DER encoded certificate list from memory and stores it to a
424 * gnutls_cert structure. Returns the number of certificates parsed.
427 parse_der_cert_mem (gnutls_certificate_credentials_t res
,
428 const void *input_cert
, int input_cert_size
)
431 gnutls_x509_crt_t crt
;
432 gnutls_pcert_st
*ccert
;
434 gnutls_str_array_t names
;
436 _gnutls_str_array_init(&names
);
438 ccert
= gnutls_malloc (sizeof (*ccert
));
442 return GNUTLS_E_MEMORY_ERROR
;
445 ret
= gnutls_x509_crt_init (&crt
);
452 tmp
.data
= (uint8_t *) input_cert
;
453 tmp
.size
= input_cert_size
;
455 ret
= gnutls_x509_crt_import (crt
, &tmp
, GNUTLS_X509_FMT_DER
);
459 gnutls_x509_crt_deinit (crt
);
463 ret
= get_x509_name(crt
, &names
);
467 gnutls_x509_crt_deinit (crt
);
471 ret
= gnutls_pcert_import_x509 (ccert
, crt
, 0);
472 gnutls_x509_crt_deinit (crt
);
480 ret
= certificate_credential_append_crt_list (res
, names
, ccert
, 1);
490 _gnutls_str_array_clear(&names
);
495 /* Reads a base64 encoded certificate list from memory and stores it to
496 * a gnutls_cert structure. Returns the number of certificate parsed.
499 parse_pem_cert_mem (gnutls_certificate_credentials_t res
,
500 const char *input_cert
, int input_cert_size
)
506 gnutls_pcert_st
*certs
= NULL
;
507 gnutls_str_array_t names
;
509 _gnutls_str_array_init(&names
);
511 /* move to the certificate
513 ptr
= memmem (input_cert
, input_cert_size
,
514 PEM_CERT_SEP
, sizeof (PEM_CERT_SEP
) - 1);
516 ptr
= memmem (input_cert
, input_cert_size
,
517 PEM_CERT_SEP2
, sizeof (PEM_CERT_SEP2
) - 1);
522 return GNUTLS_E_BASE64_DECODING_ERROR
;
524 size
= input_cert_size
- (ptr
- input_cert
);
530 certs
= gnutls_realloc_fast (certs
, (count
+ 1) * sizeof (gnutls_pcert_st
));
535 ret
= GNUTLS_E_MEMORY_ERROR
;
539 tmp
.data
= (void*)ptr
;
544 ret
= get_x509_name_raw(&tmp
, GNUTLS_X509_FMT_PEM
, &names
);
552 ret
= gnutls_pcert_import_x509_raw (&certs
[count
], &tmp
, GNUTLS_X509_FMT_PEM
, 0);
559 /* now we move ptr after the pem header
562 /* find the next certificate (if any)
564 size
= input_cert_size
- (ptr
- input_cert
);
570 ptr3
= memmem (ptr
, size
, PEM_CERT_SEP
, sizeof (PEM_CERT_SEP
) - 1);
572 ptr3
= memmem (ptr
, size
, PEM_CERT_SEP2
,
573 sizeof (PEM_CERT_SEP2
) - 1);
585 ret
= certificate_credential_append_crt_list (res
, names
, certs
, count
);
595 _gnutls_str_array_clear(&names
);
596 for (i
=0;i
<count
;i
++)
597 gnutls_pcert_deinit(&certs
[i
]);
604 /* Reads a DER or PEM certificate from memory
607 read_cert_mem (gnutls_certificate_credentials_t res
, const void *cert
,
608 int cert_size
, gnutls_x509_crt_fmt_t type
)
612 if (type
== GNUTLS_X509_FMT_DER
)
613 ret
= parse_der_cert_mem (res
, cert
, cert_size
);
615 ret
= parse_pem_cert_mem (res
, cert
, cert_size
);
626 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
627 * indicates the certificate format. KEY can be NULL, to indicate
628 * that GnuTLS doesn't know the private key.
631 read_key_mem (gnutls_certificate_credentials_t res
,
632 const void *key
, int key_size
, gnutls_x509_crt_fmt_t type
)
636 gnutls_privkey_t privkey
;
640 tmp
.data
= (uint8_t *) key
;
643 ret
= gnutls_privkey_init(&privkey
);
651 gnutls_privkey_set_pin_function(privkey
, res
->pin
.cb
, res
->pin
.data
);
653 ret
= gnutls_privkey_import_x509_raw (privkey
, &tmp
, type
, NULL
, 0);
660 ret
= certificate_credentials_append_pkey (res
, privkey
);
664 gnutls_privkey_deinit (privkey
);
672 return GNUTLS_E_INVALID_REQUEST
;
680 /* Reads a private key from a token.
683 read_key_url (gnutls_certificate_credentials_t res
, const char *url
)
686 gnutls_privkey_t pkey
= NULL
;
688 /* allocate space for the pkey list
690 ret
= gnutls_privkey_init (&pkey
);
698 gnutls_privkey_set_pin_function(pkey
, res
->pin
.cb
, res
->pin
.data
);
700 ret
= gnutls_privkey_import_url (pkey
, url
, 0);
707 ret
= certificate_credentials_append_pkey (res
, pkey
);
718 gnutls_privkey_deinit (pkey
);
724 /* Reads a private key from a token.
727 read_cas_url (gnutls_certificate_credentials_t res
, const char *url
)
730 gnutls_x509_crt_t
*xcrt_list
= NULL
;
731 gnutls_pkcs11_obj_t
*pcrt_list
= NULL
;
732 unsigned int pcrt_list_size
= 0;
734 /* FIXME: should we use login? */
736 gnutls_pkcs11_obj_list_import_url (NULL
, &pcrt_list_size
, url
,
737 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED
, 0);
738 if (ret
< 0 && ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
744 if (pcrt_list_size
== 0)
750 pcrt_list
= gnutls_malloc (sizeof (*pcrt_list
) * pcrt_list_size
);
751 if (pcrt_list
== NULL
)
754 return GNUTLS_E_MEMORY_ERROR
;
758 gnutls_pkcs11_obj_list_import_url (pcrt_list
, &pcrt_list_size
, url
,
759 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED
, 0);
766 xcrt_list
= gnutls_malloc (sizeof (*xcrt_list
) * pcrt_list_size
);
767 if (xcrt_list
== NULL
)
770 ret
= GNUTLS_E_MEMORY_ERROR
;
775 gnutls_x509_crt_list_import_pkcs11 (xcrt_list
, pcrt_list_size
, pcrt_list
,
783 ret
= gnutls_x509_trust_list_add_cas(res
->tlist
, xcrt_list
, pcrt_list_size
, 0);
791 gnutls_free (xcrt_list
);
792 gnutls_free (pcrt_list
);
799 /* Reads a certificate key from a token.
802 read_cert_url (gnutls_certificate_credentials_t res
, const char *url
)
805 gnutls_x509_crt_t crt
;
806 gnutls_pcert_st
*ccert
;
807 gnutls_str_array_t names
;
809 _gnutls_str_array_init(&names
);
811 ccert
= gnutls_malloc (sizeof (*ccert
));
815 return GNUTLS_E_MEMORY_ERROR
;
818 ret
= gnutls_x509_crt_init (&crt
);
826 gnutls_x509_crt_set_pin_function(crt
, res
->pin
.cb
, res
->pin
.data
);
828 ret
= gnutls_x509_crt_import_pkcs11_url (crt
, url
, 0);
829 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
831 gnutls_x509_crt_import_pkcs11_url (crt
, url
,
832 GNUTLS_PKCS11_OBJ_FLAG_LOGIN
);
837 gnutls_x509_crt_deinit (crt
);
841 ret
= get_x509_name(crt
, &names
);
845 gnutls_x509_crt_deinit (crt
);
849 ret
= gnutls_pcert_import_x509 (ccert
, crt
, 0);
850 gnutls_x509_crt_deinit (crt
);
858 ret
= certificate_credential_append_crt_list (res
, names
, ccert
, 1);
868 _gnutls_str_array_clear(&names
);
874 /* Reads a certificate file
877 read_cert_file (gnutls_certificate_credentials_t res
,
878 const char *certfile
, gnutls_x509_crt_fmt_t type
)
885 if (strncmp (certfile
, "pkcs11:", 7) == 0)
887 return read_cert_url (res
, certfile
);
889 #endif /* ENABLE_PKCS11 */
891 data
= read_binary_file (certfile
, &size
);
896 return GNUTLS_E_FILE_ERROR
;
899 ret
= read_cert_mem (res
, data
, size
, type
);
908 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
912 read_key_file (gnutls_certificate_credentials_t res
,
913 const char *keyfile
, gnutls_x509_crt_fmt_t type
)
919 if (gnutls_url_is_supported(keyfile
))
921 return read_key_url (res
, keyfile
);
924 data
= read_binary_file (keyfile
, &size
);
929 return GNUTLS_E_FILE_ERROR
;
932 ret
= read_key_mem (res
, data
, size
, type
);
939 * gnutls_certificate_set_x509_key_mem:
940 * @res: is a #gnutls_certificate_credentials_t structure.
941 * @cert: contains a certificate list (path) for the specified private key
942 * @key: is the private key, or %NULL
943 * @type: is PEM or DER
945 * This function sets a certificate/private key pair in the
946 * gnutls_certificate_credentials_t structure. This function may be called
947 * more than once, in case multiple keys/certificates exist for the
950 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
951 * is supported. This means that certificates intended for signing cannot
952 * be used for ciphersuites that require encryption.
954 * If the certificate and the private key are given in PEM encoding
955 * then the strings that hold their values must be null terminated.
957 * The @key may be %NULL if you are using a sign callback, see
958 * gnutls_sign_callback_set().
960 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
963 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res
,
964 const gnutls_datum_t
* cert
,
965 const gnutls_datum_t
* key
,
966 gnutls_x509_crt_fmt_t type
)
970 /* this should be first
972 if ((ret
= read_key_mem (res
, key
? key
->data
: NULL
,
973 key
? key
->size
: 0, type
)) < 0)
976 if ((ret
= read_cert_mem (res
, cert
->data
, cert
->size
, type
)) < 0)
981 if (key
&& (ret
= _gnutls_check_key_cert_match (res
)) < 0)
990 static int check_if_sorted(gnutls_pcert_st
* crt
, int nr
)
992 gnutls_x509_crt_t x509
;
993 char prev_dn
[MAX_DN
];
995 size_t prev_dn_size
, dn_size
;
998 /* check if the X.509 list is ordered */
999 if (nr
> 1 && crt
[0].type
== GNUTLS_CRT_X509
)
1004 ret
= gnutls_x509_crt_init(&x509
);
1006 return gnutls_assert_val(ret
);
1008 ret
= gnutls_x509_crt_import(x509
, &crt
[i
].cert
, GNUTLS_X509_FMT_DER
);
1011 ret
= gnutls_assert_val(ret
);
1017 dn_size
= sizeof(dn
);
1018 ret
= gnutls_x509_crt_get_dn(x509
, dn
, &dn_size
);
1021 ret
= gnutls_assert_val(ret
);
1025 if (dn_size
!= prev_dn_size
|| memcmp(dn
, prev_dn
, dn_size
) != 0)
1027 ret
= gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED
);
1032 prev_dn_size
= sizeof(prev_dn
);
1033 ret
= gnutls_x509_crt_get_issuer_dn(x509
, prev_dn
, &prev_dn_size
);
1036 ret
= gnutls_assert_val(ret
);
1040 gnutls_x509_crt_deinit(x509
);
1047 gnutls_x509_crt_deinit(x509
);
1052 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res
,
1053 gnutls_str_array_t names
, gnutls_pcert_st
* crt
, int nr
)
1057 ret
= check_if_sorted(crt
, nr
);
1059 return gnutls_assert_val(ret
);
1061 res
->certs
= gnutls_realloc_fast (res
->certs
,
1064 if (res
->certs
== NULL
)
1067 return GNUTLS_E_MEMORY_ERROR
;
1070 res
->certs
[res
->ncerts
].cert_list
= crt
;
1071 res
->certs
[res
->ncerts
].cert_list_length
= nr
;
1072 res
->certs
[res
->ncerts
].names
= names
;
1079 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res
,
1080 gnutls_privkey_t pkey
)
1082 res
->pkey
= gnutls_realloc_fast (res
->pkey
,
1084 sizeof (gnutls_privkey_t
));
1085 if (res
->pkey
== NULL
)
1088 return GNUTLS_E_MEMORY_ERROR
;
1090 res
->pkey
[res
->ncerts
] = pkey
;
1096 * gnutls_certificate_set_x509_key:
1097 * @res: is a #gnutls_certificate_credentials_t structure.
1098 * @cert_list: contains a certificate list (path) for the specified private key
1099 * @cert_list_size: holds the size of the certificate list
1100 * @key: is a #gnutls_x509_privkey_t key
1102 * This function sets a certificate/private key pair in the
1103 * gnutls_certificate_credentials_t structure. This function may be
1104 * called more than once, in case multiple keys/certificates exist for
1105 * the server. For clients that wants to send more than their own end
1106 * entity certificate (e.g., also an intermediate CA cert) then put
1107 * the certificate chain in @cert_list.
1109 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1114 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res
,
1115 gnutls_x509_crt_t
* cert_list
,
1117 gnutls_x509_privkey_t key
)
1120 gnutls_privkey_t pkey
;
1121 gnutls_pcert_st
*pcerts
= NULL
;
1122 gnutls_str_array_t names
;
1124 _gnutls_str_array_init(&names
);
1126 /* this should be first
1128 ret
= gnutls_privkey_init (&pkey
);
1136 gnutls_privkey_set_pin_function(pkey
, res
->pin
.cb
, res
->pin
.data
);
1138 ret
= gnutls_privkey_import_x509 (pkey
, key
, GNUTLS_PRIVKEY_IMPORT_COPY
);
1145 ret
= certificate_credentials_append_pkey (res
, pkey
);
1152 /* load certificates */
1153 pcerts
= gnutls_malloc (sizeof (gnutls_pcert_st
) * cert_list_size
);
1157 return GNUTLS_E_MEMORY_ERROR
;
1160 ret
= get_x509_name(cert_list
[0], &names
);
1162 return gnutls_assert_val(ret
);
1164 for (i
= 0; i
< cert_list_size
; i
++)
1166 ret
= gnutls_pcert_import_x509 (&pcerts
[i
], cert_list
[i
], 0);
1174 ret
= certificate_credential_append_crt_list (res
, names
, pcerts
, cert_list_size
);
1183 if ((ret
= _gnutls_check_key_cert_match (res
)) < 0)
1192 _gnutls_str_array_clear(&names
);
1197 * gnutls_certificate_set_key:
1198 * @res: is a #gnutls_certificate_credentials_t structure.
1199 * @names: is an array of DNS name of the certificate (NULL if none)
1200 * @names_size: holds the size of the names list
1201 * @pcert_list: contains a certificate list (path) for the specified private key
1202 * @pcert_list_size: holds the size of the certificate list
1203 * @key: is a #gnutls_privkey_t key
1205 * This function sets a certificate/private key pair in the
1206 * gnutls_certificate_credentials_t structure. This function may be
1207 * called more than once, in case multiple keys/certificates exist for
1208 * the server. For clients that wants to send more than its own end
1209 * entity certificate (e.g., also an intermediate CA cert) then put
1210 * the certificate chain in @pcert_list. The @pcert_list and @key will
1211 * become part of the credentials structure and must not
1212 * be deallocated. They will be automatically deallocated when @res
1215 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1220 gnutls_certificate_set_key (gnutls_certificate_credentials_t res
,
1223 gnutls_pcert_st
* pcert_list
,
1224 int pcert_list_size
,
1225 gnutls_privkey_t key
)
1228 gnutls_str_array_t str_names
;
1230 _gnutls_str_array_init(&str_names
);
1232 if (names
!= NULL
&& names_size
> 0)
1234 for (i
=0;i
<names_size
;i
++)
1236 ret
= _gnutls_str_array_append(&str_names
, names
[i
], strlen(names
[i
]));
1239 ret
= gnutls_assert_val(ret
);
1246 gnutls_privkey_set_pin_function(key
, res
->pin
.cb
, res
->pin
.data
);
1248 ret
= certificate_credentials_append_pkey (res
, key
);
1255 ret
= certificate_credential_append_crt_list (res
, str_names
, pcert_list
, pcert_list_size
);
1264 if ((ret
= _gnutls_check_key_cert_match (res
)) < 0)
1273 _gnutls_str_array_clear(&str_names
);
1278 * gnutls_certificate_set_x509_key_file:
1279 * @res: is a #gnutls_certificate_credentials_t structure.
1280 * @certfile: is a file that containing the certificate list (path) for
1281 * the specified private key, in PKCS7 format, or a list of certificates
1282 * @keyfile: is a file that contains the private key
1283 * @type: is PEM or DER
1285 * This function sets a certificate/private key pair in the
1286 * gnutls_certificate_credentials_t structure. This function may be
1287 * called more than once, in case multiple keys/certificates exist for
1288 * the server. For clients that need to send more than its own end
1289 * entity certificate, e.g., also an intermediate CA cert, then the
1290 * @certfile must contain the ordered certificate chain.
1292 * This function can also accept URLs at @keyfile and @certfile. In that case it
1293 * will import the private key and certificate indicated by the URLs. Note
1294 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1296 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1299 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res
,
1300 const char *certfile
,
1301 const char *keyfile
,
1302 gnutls_x509_crt_fmt_t type
)
1306 /* this should be first
1308 if ((ret
= read_key_file (res
, keyfile
, type
)) < 0)
1311 if ((ret
= read_cert_file (res
, certfile
, type
)) < 0)
1316 if ((ret
= _gnutls_check_key_cert_match (res
)) < 0)
1326 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res
, gnutls_x509_crt_t
* crts
,
1327 unsigned int crt_size
)
1332 unsigned char *newdata
, *p
;
1335 /* Add DN of the last added CAs to the RDN sequence
1336 * This will be sent to clients when a certificate
1337 * request message is sent.
1340 /* FIXME: in case of a client it is not needed
1341 * to do that. This would save time and memory.
1342 * However we don't have that information available
1344 * Further, this function is now much more efficient,
1345 * so optimizing that is less important.
1348 for (i
= 0; i
< crt_size
; i
++)
1350 if ((ret
= gnutls_x509_crt_get_raw_dn (crts
[i
], &tmp
)) < 0)
1356 newsize
= res
->x509_rdn_sequence
.size
+ 2 + tmp
.size
;
1357 if (newsize
< res
->x509_rdn_sequence
.size
)
1360 _gnutls_free_datum (&tmp
);
1361 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1364 newdata
= gnutls_realloc (res
->x509_rdn_sequence
.data
, newsize
);
1365 if (newdata
== NULL
)
1368 _gnutls_free_datum (&tmp
);
1369 return GNUTLS_E_MEMORY_ERROR
;
1372 p
= newdata
+ res
->x509_rdn_sequence
.size
;
1373 _gnutls_write_uint16 (tmp
.size
, p
);
1374 if (tmp
.data
!= NULL
)
1375 memcpy (p
+2, tmp
.data
, tmp
.size
);
1377 _gnutls_free_datum (&tmp
);
1379 res
->x509_rdn_sequence
.size
= newsize
;
1380 res
->x509_rdn_sequence
.data
= newdata
;
1386 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1387 * certificate (uses the KeyUsage field).
1390 _gnutls_check_key_usage (const gnutls_pcert_st
* cert
, gnutls_kx_algorithm_t alg
)
1392 unsigned int key_usage
= 0;
1398 return GNUTLS_E_INTERNAL_ERROR
;
1401 if (_gnutls_map_kx_get_cred (alg
, 1) == GNUTLS_CRD_CERTIFICATE
||
1402 _gnutls_map_kx_get_cred (alg
, 0) == GNUTLS_CRD_CERTIFICATE
)
1405 gnutls_pubkey_get_key_usage(cert
->pubkey
, &key_usage
);
1407 encipher_type
= _gnutls_kx_encipher_type (alg
);
1409 if (key_usage
!= 0 && encipher_type
!= CIPHER_IGN
)
1411 /* If key_usage has been set in the certificate
1414 if (encipher_type
== CIPHER_ENCRYPT
)
1416 /* If the key exchange method requires an encipher
1417 * type algorithm, and key's usage does not permit
1418 * encipherment, then fail.
1420 if (!(key_usage
& GNUTLS_KEY_KEY_ENCIPHERMENT
))
1423 return GNUTLS_E_KEY_USAGE_VIOLATION
;
1427 if (encipher_type
== CIPHER_SIGN
)
1429 /* The same as above, but for sign only keys
1431 if (!(key_usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
))
1434 return GNUTLS_E_KEY_USAGE_VIOLATION
;
1443 parse_pem_ca_mem (gnutls_certificate_credentials_t res
,
1444 const uint8_t * input_cert
, int input_cert_size
)
1446 gnutls_x509_crt_t
*x509_cert_list
;
1447 unsigned int x509_ncerts
;
1451 tmp
.data
= (void*)input_cert
;
1452 tmp
.size
= input_cert_size
;
1454 ret
= gnutls_x509_crt_list_import2( &x509_cert_list
, &x509_ncerts
, &tmp
,
1455 GNUTLS_X509_FMT_PEM
, 0);
1462 if ((ret
= add_new_crt_to_rdn_seq (res
, x509_cert_list
, x509_ncerts
)) < 0)
1468 ret
= gnutls_x509_trust_list_add_cas(res
->tlist
, x509_cert_list
, x509_ncerts
, 0);
1476 gnutls_free(x509_cert_list
);
1480 /* Reads a DER encoded certificate list from memory and stores it to a
1481 * gnutls_cert structure. Returns the number of certificates parsed.
1484 parse_der_ca_mem (gnutls_certificate_credentials_t res
,
1485 const void *input_cert
, int input_cert_size
)
1487 gnutls_x509_crt_t crt
;
1491 tmp
.data
= (void*)input_cert
;
1492 tmp
.size
= input_cert_size
;
1494 ret
= gnutls_x509_crt_init( &crt
);
1501 ret
= gnutls_x509_crt_import( crt
, &tmp
, GNUTLS_X509_FMT_DER
);
1508 if ((ret
= add_new_crt_to_rdn_seq (res
, &crt
, 1)) < 0)
1514 ret
= gnutls_x509_trust_list_add_cas(res
->tlist
, &crt
, 1, 0);
1524 gnutls_x509_crt_deinit(crt
);
1529 * gnutls_certificate_set_x509_trust_mem:
1530 * @res: is a #gnutls_certificate_credentials_t structure.
1531 * @ca: is a list of trusted CAs or a DER certificate
1532 * @type: is DER or PEM
1534 * This function adds the trusted CAs in order to verify client or
1535 * server certificates. In case of a client this is not required to be
1536 * called if the certificates are not verified using
1537 * gnutls_certificate_verify_peers2(). This function may be called
1540 * In case of a server the CAs set here will be sent to the client if
1541 * a certificate request is sent. This can be disabled using
1542 * gnutls_certificate_send_x509_rdn_sequence().
1544 * Returns: the number of certificates processed or a negative error code
1548 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res
,
1549 const gnutls_datum_t
* ca
,
1550 gnutls_x509_crt_fmt_t type
)
1554 if (type
== GNUTLS_X509_FMT_DER
)
1555 ret
= parse_der_ca_mem (res
,
1556 ca
->data
, ca
->size
);
1558 ret
= parse_pem_ca_mem (res
,
1559 ca
->data
, ca
->size
);
1561 if (ret
== GNUTLS_E_NO_CERTIFICATE_FOUND
)
1568 * gnutls_certificate_set_x509_trust:
1569 * @res: is a #gnutls_certificate_credentials_t structure.
1570 * @ca_list: is a list of trusted CAs
1571 * @ca_list_size: holds the size of the CA list
1573 * This function adds the trusted CAs in order to verify client
1574 * or server certificates. In case of a client this is not required
1575 * to be called if the certificates are not verified using
1576 * gnutls_certificate_verify_peers2().
1577 * This function may be called multiple times.
1579 * In case of a server the CAs set here will be sent to the client if
1580 * a certificate request is sent. This can be disabled using
1581 * gnutls_certificate_send_x509_rdn_sequence().
1583 * Returns: the number of certificates processed or a negative error code
1589 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res
,
1590 gnutls_x509_crt_t
* ca_list
,
1594 gnutls_x509_crt_t new_list
[ca_list_size
];
1596 for (i
= 0; i
< ca_list_size
; i
++)
1598 ret
= gnutls_x509_crt_init (&new_list
[i
]);
1605 ret
= _gnutls_x509_crt_cpy (new_list
[i
], ca_list
[i
]);
1613 if ((ret
= add_new_crt_to_rdn_seq (res
, new_list
, ca_list_size
)) < 0)
1619 ret
= gnutls_x509_trust_list_add_cas(res
->tlist
, new_list
, ca_list_size
, 0);
1630 gnutls_x509_crt_deinit(new_list
[j
]);
1637 * gnutls_certificate_set_x509_trust_file:
1638 * @cred: is a #gnutls_certificate_credentials_t structure.
1639 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1640 * @type: is PEM or DER
1642 * This function adds the trusted CAs in order to verify client or
1643 * server certificates. In case of a client this is not required to
1644 * be called if the certificates are not verified using
1645 * gnutls_certificate_verify_peers2(). This function may be called
1648 * In case of a server the names of the CAs set here will be sent to
1649 * the client if a certificate request is sent. This can be disabled
1650 * using gnutls_certificate_send_x509_rdn_sequence().
1652 * This function can also accept URLs. In that case it
1653 * will import all certificates that are marked as trusted. Note
1654 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1656 * Returns: number of certificates processed, or a negative error code on
1660 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred
,
1662 gnutls_x509_crt_fmt_t type
)
1668 #ifdef ENABLE_PKCS11
1669 if (strncmp (cafile
, "pkcs11:", 7) == 0)
1671 return read_cas_url (cred
, cafile
);
1675 cas
.data
= (void*)read_binary_file (cafile
, &size
);
1676 if (cas
.data
== NULL
)
1679 return GNUTLS_E_FILE_ERROR
;
1684 ret
= gnutls_certificate_set_x509_trust_mem(cred
, &cas
, type
);
1698 * gnutls_certificate_set_x509_system_trust:
1699 * @cred: is a #gnutls_certificate_credentials_t structure.
1701 * This function adds the system's default trusted CAs in order to
1702 * verify client or server certificates.
1704 * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
1707 * Returns: the number of certificates processed or a negative error code
1713 gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred
)
1715 return gnutls_x509_trust_list_add_system_trust(cred
->tlist
, 0, 0);
1719 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist
,
1720 const char * input_crl
, unsigned int input_crl_size
)
1722 gnutls_x509_crl_t
*x509_crl_list
;
1723 unsigned int x509_ncrls
;
1727 tmp
.data
= (void*)input_crl
;
1728 tmp
.size
= input_crl_size
;
1730 ret
= gnutls_x509_crl_list_import2( &x509_crl_list
, &x509_ncrls
, &tmp
,
1731 GNUTLS_X509_FMT_PEM
, 0);
1738 ret
= gnutls_x509_trust_list_add_crls(tlist
, x509_crl_list
, x509_ncrls
, 0, 0);
1746 gnutls_free(x509_crl_list
);
1750 /* Reads a DER encoded certificate list from memory and stores it to a
1751 * gnutls_cert structure. Returns the number of certificates parsed.
1754 parse_der_crl_mem (gnutls_x509_trust_list_t tlist
,
1755 const void *input_crl
, unsigned int input_crl_size
)
1757 gnutls_x509_crl_t crl
;
1761 tmp
.data
= (void*)input_crl
;
1762 tmp
.size
= input_crl_size
;
1764 ret
= gnutls_x509_crl_init( &crl
);
1771 ret
= gnutls_x509_crl_import( crl
, &tmp
, GNUTLS_X509_FMT_DER
);
1778 ret
= gnutls_x509_trust_list_add_crls(tlist
, &crl
, 1, 0, 0);
1788 gnutls_x509_crl_deinit(crl
);
1794 /* Reads a DER or PEM CRL from memory
1797 read_crl_mem (gnutls_certificate_credentials_t res
, const void *crl
,
1798 int crl_size
, gnutls_x509_crt_fmt_t type
)
1802 if (type
== GNUTLS_X509_FMT_DER
)
1803 ret
= parse_der_crl_mem (res
->tlist
, crl
, crl_size
);
1805 ret
= parse_pem_crl_mem (res
->tlist
, crl
, crl_size
);
1816 * gnutls_certificate_set_x509_crl_mem:
1817 * @res: is a #gnutls_certificate_credentials_t structure.
1818 * @CRL: is a list of trusted CRLs. They should have been verified before.
1819 * @type: is DER or PEM
1821 * This function adds the trusted CRLs in order to verify client or
1822 * server certificates. In case of a client this is not required to
1823 * be called if the certificates are not verified using
1824 * gnutls_certificate_verify_peers2(). This function may be called
1827 * Returns: number of CRLs processed, or a negative error code on error.
1830 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res
,
1831 const gnutls_datum_t
* CRL
,
1832 gnutls_x509_crt_fmt_t type
)
1834 return read_crl_mem (res
, CRL
->data
, CRL
->size
, type
);
1838 * gnutls_certificate_set_x509_crl:
1839 * @res: is a #gnutls_certificate_credentials_t structure.
1840 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1841 * @crl_list_size: holds the size of the crl_list
1843 * This function adds the trusted CRLs in order to verify client or
1844 * server certificates. In case of a client this is not required to
1845 * be called if the certificates are not verified using
1846 * gnutls_certificate_verify_peers2(). This function may be called
1849 * Returns: number of CRLs processed, or a negative error code on error.
1854 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res
,
1855 gnutls_x509_crl_t
* crl_list
,
1859 gnutls_x509_crl_t new_crl
[crl_list_size
];
1861 for (i
= 0; i
< crl_list_size
; i
++)
1863 ret
= gnutls_x509_crl_init (&new_crl
[i
]);
1870 ret
= _gnutls_x509_crl_cpy (new_crl
[i
], crl_list
[i
]);
1878 ret
= gnutls_x509_trust_list_add_crls(res
->tlist
, new_crl
, crl_list_size
, 0, 0);
1889 gnutls_x509_crl_deinit(new_crl
[j
]);
1895 * gnutls_certificate_set_x509_crl_file:
1896 * @res: is a #gnutls_certificate_credentials_t structure.
1897 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1898 * @type: is PEM or DER
1900 * This function adds the trusted CRLs in order to verify client or server
1901 * certificates. In case of a client this is not required
1902 * to be called if the certificates are not verified using
1903 * gnutls_certificate_verify_peers2().
1904 * This function may be called multiple times.
1906 * Returns: number of CRLs processed or a negative error code on error.
1909 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res
,
1910 const char *crlfile
,
1911 gnutls_x509_crt_fmt_t type
)
1915 char *data
= (void*)read_binary_file (crlfile
, &size
);
1920 return GNUTLS_E_FILE_ERROR
;
1923 if (type
== GNUTLS_X509_FMT_DER
)
1924 ret
= parse_der_crl_mem (res
->tlist
, data
, size
);
1926 ret
= parse_pem_crl_mem (res
->tlist
, data
, size
);
1939 #include <gnutls/pkcs12.h>
1943 * gnutls_certificate_set_x509_simple_pkcs12_file:
1944 * @res: is a #gnutls_certificate_credentials_t structure.
1945 * @pkcs12file: filename of file containing PKCS#12 blob.
1946 * @type: is PEM or DER of the @pkcs12file.
1947 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1949 * This function sets a certificate/private key pair and/or a CRL in
1950 * the gnutls_certificate_credentials_t structure. This function may
1951 * be called more than once (in case multiple keys/certificates exist
1954 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
1955 * private keys are supported. However,
1956 * only password based security, and the same password for all
1957 * operations, are supported.
1959 * PKCS#12 file may contain many keys and/or certificates, and there
1960 * is no way to identify which key/certificate pair you want. You
1961 * should make sure the PKCS#12 file only contain one key/certificate
1962 * pair and/or one CRL.
1964 * It is believed that the limitations of this function is acceptable
1965 * for most usage, and that any more flexibility would introduce
1966 * complexity that would make it harder to use this functionality at
1969 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1972 gnutls_certificate_set_x509_simple_pkcs12_file
1973 (gnutls_certificate_credentials_t res
, const char *pkcs12file
,
1974 gnutls_x509_crt_fmt_t type
, const char *password
)
1976 gnutls_datum_t p12blob
;
1980 p12blob
.data
= (void*)read_binary_file (pkcs12file
, &size
);
1981 p12blob
.size
= (unsigned int) size
;
1982 if (p12blob
.data
== NULL
)
1985 return GNUTLS_E_FILE_ERROR
;
1989 gnutls_certificate_set_x509_simple_pkcs12_mem (res
, &p12blob
, type
,
1991 free (p12blob
.data
);
1997 * gnutls_certificate_set_x509_simple_pkcs12_mem:
1998 * @res: is a #gnutls_certificate_credentials_t structure.
1999 * @p12blob: the PKCS#12 blob.
2000 * @type: is PEM or DER of the @pkcs12file.
2001 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2003 * This function sets a certificate/private key pair and/or a CRL in
2004 * the gnutls_certificate_credentials_t structure. This function may
2005 * be called more than once (in case multiple keys/certificates exist
2008 * Encrypted PKCS#12 bags and PKCS#8 private keys are supported. However,
2009 * only password based security, and the same password for all
2010 * operations, are supported.
2012 * PKCS#12 file may contain many keys and/or certificates, and there
2013 * is no way to identify which key/certificate pair you want. You
2014 * should make sure the PKCS#12 file only contain one key/certificate
2015 * pair and/or one CRL.
2017 * It is believed that the limitations of this function is acceptable
2018 * for most usage, and that any more flexibility would introduce
2019 * complexity that would make it harder to use this functionality at
2022 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2027 gnutls_certificate_set_x509_simple_pkcs12_mem
2028 (gnutls_certificate_credentials_t res
, const gnutls_datum_t
* p12blob
,
2029 gnutls_x509_crt_fmt_t type
, const char *password
)
2031 gnutls_pkcs12_t p12
;
2032 gnutls_x509_privkey_t key
= NULL
;
2033 gnutls_x509_crt_t
*chain
= NULL
;
2034 gnutls_x509_crl_t crl
= NULL
;
2035 unsigned int chain_size
= 0, i
;
2038 ret
= gnutls_pkcs12_init (&p12
);
2045 ret
= gnutls_pkcs12_import (p12
, p12blob
, type
, 0);
2049 gnutls_pkcs12_deinit (p12
);
2055 ret
= gnutls_pkcs12_verify_mac (p12
, password
);
2059 gnutls_pkcs12_deinit (p12
);
2064 ret
= gnutls_pkcs12_simple_parse (p12
, password
, &key
, &chain
, &chain_size
,
2065 NULL
, NULL
, &crl
, 0);
2066 gnutls_pkcs12_deinit (p12
);
2075 ret
= gnutls_certificate_set_x509_key (res
, chain
, chain_size
, key
);
2085 ret
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2091 ret
= gnutls_certificate_set_x509_crl (res
, &crl
, 1);
2104 for (i
=0;i
<chain_size
;i
++)
2105 gnutls_x509_crt_deinit (chain
[i
]);
2109 gnutls_x509_privkey_deinit (key
);
2111 gnutls_x509_crl_deinit (crl
);
2119 * gnutls_certificate_free_crls:
2120 * @sc: is a #gnutls_certificate_credentials_t structure.
2122 * This function will delete all the CRLs associated
2123 * with the given credentials.
2126 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc
)
2128 /* do nothing for now */
2133 * gnutls_certificate_credentials_t:
2134 * @cred: is a #gnutls_certificate_credentials_t structure.
2135 * @fn: A PIN callback
2136 * @userdata: Data to be passed in the callback
2138 * This function will set a callback function to be used when
2139 * required to access a protected object. This function overrides any other
2140 * global PIN functions.
2142 * Note that this function must be called right after initialization
2147 void gnutls_certificate_set_pin_function (gnutls_certificate_credentials_t cred
,
2148 gnutls_pin_callback_t fn
, void *userdata
)
2151 cred
->pin
.data
= userdata
;