1 @node More on certificate authentication
2 @chapter More on Certificate Authentication
3 @anchor{Certificate Authentication}
4 @cindex Certificate authentication
7 * The X.509 trust model::
8 * The OpenPGP trust model::
10 * Abstract data types::
11 * Digital signatures::
14 @node The X.509 trust model
15 @section The @acronym{X.509} Trust Model
16 @cindex @acronym{X.509} certificates
18 The @acronym{X.509} protocols rely on a hierarchical trust model. In
19 this trust model Certification Authorities (CAs) are used to certify
20 entities. Usually more than one certification authorities exist, and
21 certification authorities may certify other authorities to issue
22 certificates as well, following a hierarchical model.
24 @image{gnutls-x509,7cm,9.5cm}
26 One needs to trust one or more CAs for his secure communications. In
27 that case only the certificates issued by the trusted authorities are
28 acceptable. See the figure above for a typical example. The API for
29 handling @acronym{X.509} certificates is described at section
30 @ref{sec:x509api}. Some examples are listed below.
33 * X.509 certificates::
34 * Verifying X.509 certificate paths::
35 * PKCS #10 certificate requests::
36 * PKCS #12 structures::
39 @node X.509 certificates
40 @subsection @acronym{X.509} Certificates
42 An @acronym{X.509} certificate usually contains information about the
43 certificate holder, the signer, a unique serial number, expiration
44 dates and some other fields @xcite{PKIX} as shown in the table below.
49 The field that indicates the version of the certificate.
52 This field holds a unique serial number per certificate.
55 Holds the issuer's distinguished name.
58 The activation and expiration dates.
61 The subject's distinguished name of the certificate.
64 The extensions are fields only present in version 3 certificates.
68 The certificate's @emph{subject or issuer name} is not just a single
69 string. It is a Distinguished name and in the @acronym{ASN.1}
70 notation is a sequence of several object IDs with their corresponding
71 values. Some of available OIDs to be used in an @acronym{X.509}
72 distinguished name are defined in @file{gnutls/x509.h}.
74 The @emph{Version} field in a certificate has values either 1 or 3 for
75 version 3 certificates. Version 1 certificates do not support the
76 extensions field so it is not possible to distinguish a CA from a
77 person, thus their usage should be avoided.
79 The @emph{validity} dates are there to indicate the date that the
80 specific certificate was activated and the date the certificate's key
81 would be considered invalid.
83 Certificate @emph{extensions} are there to include information about
84 the certificate's subject that did not fit in the typical certificate
85 fields. Those may be e-mail addresses, flags that indicate whether the
86 belongs to a CA etc. All the supported @acronym{X.509} version 3
87 extensions are shown in the table below.
91 @item subject key id (2.5.29.14):
92 An identifier of the key of the subject.
94 @item authority key id (2.5.29.35):
95 An identifier of the authority's key used to sign the certificate.
97 @item subject alternative name (2.5.29.17):
98 Alternative names to subject's distinguished name.
100 @item key usage (2.5.29.15):
101 Constraints the key's usage of the certificate.
103 @item extended key usage (2.5.29.37):
104 Constraints the purpose of the certificate.
106 @item basic constraints (2.5.29.19):
107 Indicates whether this is a CA certificate or not, and specify the
108 maximum path lengths of certificate chains.
110 @item CRL distribution points (2.5.29.31):
111 This extension is set by the CA, in order to inform about the issued
114 @item Proxy Certification Information (1.3.6.1.5.5.7.1.14):
115 Proxy Certificates includes this extension that contains the OID of
116 the proxy policy language used, and can specify limits on the maximum
117 lengths of proxy chains. Proxy Certificates are specified in
122 In @acronym{GnuTLS} the @acronym{X.509} certificate structures are
123 handled using the @code{gnutls_x509_crt_t} type and the corresponding
124 private keys with the @code{gnutls_x509_privkey_t} type. All the
125 available functions for @acronym{X.509} certificate handling have
126 their prototypes in @file{gnutls/x509.h}. An example program to
127 demonstrate the @acronym{X.509} parsing capabilities can be found at
128 section @ref{ex:x509-info}.
130 @node Verifying X.509 certificate paths
131 @subsection Verifying @acronym{X.509} Certificate Paths
132 @cindex Verifying certificate paths
134 Verifying certificate paths is important in @acronym{X.509}
135 authentication. For this purpose the function
136 @ref{gnutls_x509_crt_verify} is provided. The output of this function
137 is the bitwise OR of the elements of the
138 @code{gnutls_certificate_status_t} enumeration. A detailed
139 description of these elements can be found in figure below. The
140 function @ref{gnutls_certificate_verify_peers2} is equivalent to the
141 previous one, and will verify the peer's certificate in a TLS session.
145 @item GNUTLS_CERT_INVALID:
146 The certificate is not signed by one of the known authorities, or
147 the signature is invalid.
149 @item GNUTLS_CERT_REVOKED:
150 The certificate has been revoked by its CA.
152 @item GNUTLS_CERT_SIGNER_NOT_FOUND:
153 The certificate's issuer is not known. This is the case when the
154 issuer is not in the trusted certificates list.
156 @item GNUTLS_CERT_SIGNER_NOT_CA:
157 The certificate's signer was not a CA. This may happen if
158 this was a version 1 certificate, which is common with some CAs, or
159 a version 3 certificate without the basic constrains extension.
161 @anchor{GNUTLS_CERT_INSECURE_ALGORITHM}
162 @item GNUTLS_CERT_INSECURE_ALGORITHM:
163 The certificate was signed using an insecure algorithm such as MD2 or
164 MD5. These algorithms have been broken and should not be trusted.
168 There is also to possibility to pass some input to the verification
169 functions in the form of flags. For @ref{gnutls_x509_crt_verify} the
170 flags are passed straightforward, but
171 @ref{gnutls_certificate_verify_peers2} depends on the flags set by
172 calling @ref{gnutls_certificate_set_verify_flags}. All the available
173 flags are part of the enumeration
174 @ref{gnutls_certificate_verify_flags} and are explained in the table
177 @anchor{gnutls_certificate_verify_flags}
178 @tindex gnutls_certificate_verify_flags
180 @item GNUTLS_VERIFY_DISABLE_CA_SIGN:
181 If set a signer does not have to be a certificate authority. This
182 flag should normaly be disabled, unless you know what this means.
184 @item GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT:
185 Allow only trusted CA certificates that have version 1. This is
186 safer than GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT, and should be
187 used instead. That way only signers in your trusted list will be
188 allowed to have certificates of version 1.
190 @item GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT:
191 Allow CA certificates that have version 1 (both root and
192 intermediate). This is dangerous since those haven't the
193 basicConstraints extension. Must be used in combination with
194 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT.
196 @item GNUTLS_VERIFY_DO_NOT_ALLOW_SAME:
197 If a certificate is not signed by anyone trusted but exists in
198 the trusted CA list do not treat it as trusted.
200 @item GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2:
201 Allow certificates to be signed using the old MD2 algorithm.
203 @item GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5:
204 Allow certificates to be signed using the broken MD5 algorithm.
207 Although the verification of a certificate path indicates that the
208 certificate is signed by trusted authority, does not reveal anything
209 about the peer's identity. It is required to verify if the
210 certificate's owner is the one you expect. For more information
211 consult @xcite{RFC2818} and section @ref{ex:verify} for an example.
213 @node PKCS #10 certificate requests
214 @subsection @acronym{PKCS} #10 Certificate Requests
215 @cindex Certificate requests
216 @cindex @acronym{PKCS} #10
218 A certificate request is a structure, which contain information about
219 an applicant of a certificate service. It usually contains a private
220 key, a distinguished name and secondary data such as a challenge
221 password. @acronym{GnuTLS} supports the requests defined in
222 @acronym{PKCS} #10 @xcite{RFC2986}. Other certificate request's format
223 such as PKIX's @xcite{RFC4211} are not currently supported.
225 In @acronym{GnuTLS} the @acronym{PKCS} #10 structures are handled
226 using the @code{gnutls_x509_crq_t} type. An example of a certificate
227 request generation can be found at section @ref{ex:crq}.
229 @node PKCS #12 structures
230 @subsection @acronym{PKCS} #12 Structures
231 @cindex @acronym{PKCS} #12
233 A @acronym{PKCS} #12 structure @xcite{PKCS12} usually contains a user's
234 private keys and certificates. It is commonly used in browsers to
235 export and import the user's identities.
237 In @acronym{GnuTLS} the @acronym{PKCS} #12 structures are handled
238 using the @code{gnutls_pkcs12_t} type. This is an abstract type that
239 may hold several @code{gnutls_pkcs12_bag_t} types. The Bag types are
240 the holders of the actual data, which may be certificates, private
241 keys or encrypted data. An Bag of type encrypted should be decrypted
242 in order for its data to be accessed.
244 An example of a @acronym{PKCS} #12 structure generation can be found
245 at section @ref{ex:pkcs12}.
247 @node The OpenPGP trust model
248 @section The @acronym{OpenPGP} Trust Model
249 @cindex @acronym{OpenPGP} Keys
251 The @acronym{OpenPGP} key authentication relies on a distributed trust
252 model, called the ``web of trust''. The ``web of trust'' uses a
253 decentralized system of trusted introducers, which are the same as a
254 CA. @acronym{OpenPGP} allows anyone to sign anyone's else public
255 key. When Alice signs Bob's key, she is introducing Bob's key to
256 anyone who trusts Alice. If someone trusts Alice to introduce keys,
257 then Alice is a trusted introducer in the mind of that observer.
259 @image{gnutls-pgp,11cm,9cm}
261 For example: If David trusts Alice to be an introducer, and Alice
262 signed Bob's key, Dave also trusts Bob's key to be the real one.
264 There are some key points that are important in that model. In the
265 example Alice has to sign Bob's key, only if she is sure that the key
266 belongs to Bob. Otherwise she may also make Dave falsely believe that
267 this is Bob's key. Dave has also the responsibility to know who to
268 trust. This model is similar to real life relations.
270 Just see how Charlie behaves in the previous example. Although he has
271 signed Bob's key - because he knows, somehow, that it belongs to Bob -
272 he does not trust Bob to be an introducer. Charlie decided to trust
273 only Kevin, for some reason. A reason could be that Bob is lazy
274 enough, and signs other people's keys without being sure that they
275 belong to the actual owner.
277 @subsection @acronym{OpenPGP} Keys
279 In @acronym{GnuTLS} the @acronym{OpenPGP} key structures
280 @xcite{RFC2440} are handled using the @code{gnutls_openpgp_crt_t} type
281 and the corresponding private keys with the
282 @code{gnutls_openpgp_privkey_t} type. All the prototypes for the key
283 handling functions can be found at @file{gnutls/openpgp.h}.
285 @subsection Verifying an @acronym{OpenPGP} Key
287 The verification functions of @acronym{OpenPGP} keys, included in
288 @acronym{GnuTLS}, are simple ones, and do not use the features of the
289 ``web of trust''. For that reason, if the verification needs are
290 complex, the assistance of external tools like @acronym{GnuPG} and
291 GPGME (@url{http://www.gnupg.org/related_software/gpgme/}) is
294 There is one verification function in @acronym{GnuTLS}, the
295 @ref{gnutls_openpgp_crt_verify_ring}. This checks an
296 @acronym{OpenPGP} key against a given set of public keys (keyring) and
297 returns the key status. The key verification status is the same as in
298 @acronym{X.509} certificates, although the meaning and interpretation
299 are different. For example an @acronym{OpenPGP} key may be valid, if
300 the self signature is ok, even if no signers were found. The meaning
301 of verification status is shown in the figure below.
306 A signature on the key is invalid. That means that the key was
307 modified by somebody, or corrupted during transport.
310 The key has been revoked by its owner.
312 @item CERT_SIGNER_NOT_FOUND:
313 The key was not signed by a known signer.
315 @item GNUTLS_CERT_INSECURE_ALGORITHM:
316 The certificate was signed using an insecure algorithm such as MD2 or
317 MD5. These algorithms have been broken and should not be trusted.
322 @node PKCS #11 tokens
323 @section @acronym{PKCS #11} tokens
325 @cindex @acronym{PKCS #11} tokens
327 @subsection Introduction
328 This section copes with the @acronym{PKCS #11} @xcite{PKCS11} support in @acronym{GnuTLS}.
329 @acronym{PKCS #11} is plugin API allowing applications to access cryptographic
330 operations on a token, as well as to objects residing on the token. A token can
331 be a real hardware token such as a smart card, or it can be a software component
332 such as @acronym{Gnome Keyring}. The objects residing on such token can be
333 certificates, public keys, private keys or even plain data or secret keys. Of those
334 certificates and public/private key pairs can be used with @acronym{GnuTLS}. Its
335 main advantage is that it allows operations on private key objects such as decryption
336 and signing without accessing the key itself.
338 Moreover it can be used to allow all applications in the same operating system to access
339 shared cryptographic keys and certificates in a uniform way, as in the following picture.
341 @image{pkcs11-vision}
343 @subsection Initialization
344 To allow all the @acronym{GnuTLS} applications to access @acronym{PKCS} #11 tokens
345 you can use a configuration per module, such as @code{/etc/pkcs11/modules/mymodule.conf}.
346 This file has the following format:
349 module: /usr/lib/opensc-pkcs11.so
352 If you use this file, then there is no need for other initialization in
353 @acronym{GnuTLS}, except for the PIN and token functions. Those allow retrieving a PIN
354 when accessing a protected object, such as a private key, as well as probe
355 the user to insert the token. All the initialization functions are below.
359 @item @ref{gnutls_pkcs11_init}: Global initialization
361 @item @ref{gnutls_pkcs11_deinit}: Global deinitialization
363 @item @ref{gnutls_pkcs11_set_token_function}: Sets the token insertion function
365 @item @ref{gnutls_pkcs11_set_pin_function}: Sets the PIN request function
367 @item @ref{gnutls_pkcs11_add_provider}: Adds an additional @acronym{PKCS #11} provider
371 Note that due to limitations of @acronym{PKCS #11} there might be issues when multiple libraries
372 are sharing a module. If this is the case we suggest to use p11-kit@footnote{http://p11-glue.freedesktop.org/}
373 that provides an intermediate module to control access to resources over the
376 @subsection Reading Objects
378 All @acronym{PKCS #11} objects are referenced by @acronym{GnuTLS} functions by
379 URLs as described in @code{draft-pechanec-pkcs11uri-03}. For example a public
380 key on a smart card may be referenced as:
383 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
384 manufacturer=EnterSafe;object=test1;objecttype=public;\
385 id=32:f1:53:f3:e3:79:90:b0:86:24:14:10:77:ca:5d:ec:2d:15:fa:ed
388 while the smart card itself can be referenced as:
390 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe
394 Objects can be accessed with the following functions
397 @item @ref{gnutls_pkcs11_obj_init}: Initializes an object
399 @item @ref{gnutls_pkcs11_obj_import_url}: To import an object from a url
401 @item @ref{gnutls_pkcs11_obj_export_url}: To export the URL of the object
403 @item @ref{gnutls_pkcs11_obj_deinit}: To deinitialize an object
405 @item @ref{gnutls_pkcs11_obj_export}: To export data associated with object
407 @item @ref{gnutls_pkcs11_obj_get_info}: To obtain information about an object
409 @item @ref{gnutls_pkcs11_obj_list_import_url}: To mass load of objects
411 @item @ref{gnutls_x509_crt_import_pkcs11}: Import a certificate object
413 @item @ref{gnutls_x509_crt_import_pkcs11_url}: Helper function to directly import a URL into a certificate
415 @item @ref{gnutls_x509_crt_list_import_pkcs11}: Mass import of certificates
420 Functions that relate to token handling are shown below
423 @item @ref{gnutls_pkcs11_token_init}: Initializes a token
425 @item @ref{gnutls_pkcs11_token_set_pin}: Sets the token user's PIN
427 @item @ref{gnutls_pkcs11_token_get_url}: Returns the URL of a token
429 @item @ref{gnutls_pkcs11_token_get_info}: Obtain information about a token
431 @item @ref{gnutls_pkcs11_token_get_flags}: Returns flags about a token (i.e. hardware or software)
435 The following example will list all tokens.
440 gnutls_global_init();
443 ret = gnutls_pkcs11_token_get_url(i, &url);
444 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
450 fprintf(stdout, "Token[%d]: URL: %s\n", i, url);
453 gnutls_global_deinit();
457 The next one will list all certificates in a token, that have a corresponding
460 gnutls_pkcs11_obj_t *obj_list;
461 unsigned int obj_list_size = 0;
462 gnutls_datum_t cinfo;
466 ret = gnutls_pkcs11_obj_list_import_url( obj_list, NULL, url, \
467 GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY);
468 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
471 /* no error checking from now on */
472 obj_list = malloc(sizeof(*obj_list)*obj_list_size);
474 gnutls_pkcs11_obj_list_import_url( obj_list, &obj_list_size, url, flags);
476 /* now all certificates are in obj_list */
477 for (i=0;i<obj_list_size;i++) {
479 gnutls_x509_crt_init(&xcrt);
481 gnutls_x509_crt_import_pkcs11(xcrt, obj_list[i]);
483 gnutls_x509_crt_print (xcrt, GNUTLS_CRT_PRINT_FULL, &cinfo);
485 fprintf(stdout, "cert[%d]:\n %s\n\n", cinfo.data);
487 gnutls_free(cinfo.data);
488 gnutls_x509_crt_deinit(&xcrt);
493 @subsection Writing Objects
495 With @acronym{GnuTLS} you can copy existing private keys and certificates
496 to a token. This can be achieved with the following functions
500 @item @ref{gnutls_pkcs11_delete_url}: To delete an object
502 @item @ref{gnutls_pkcs11_copy_x509_privkey}: To copy a private key to a token
504 @item @ref{gnutls_pkcs11_copy_x509_crt}: To copy a certificate to a token
509 @subsection Using a @acronym{PKCS #11} token with TLS
511 It is possible to use a @acronym{PKCS #11} token to a TLS
512 session, as shown in @ref{ex:pkcs11-client}. In addition
513 the following functions can be used to load PKCS #11 key and
518 @item @ref{gnutls_certificate_set_x509_trust_file}: If given a PKCS #11 URL will load the trusted certificates from it.
520 @item @ref{gnutls_certificate_set_x509_key_file}: Will also load PKCS #11 URLs for keys and certificates.
525 @node Abstract data types
526 @section Abstract data types
527 @anchor{sec:abstract}
528 @cindex Abstract types
530 Since there are many forms of a public or private keys supported by @acronym{GnuTLS} such as
531 @acronym{X.509}, @acronym{OpenPGP}, or @acronym{PKCS #11} it is desirable to allow common operations
532 on them. For these reasons the abstract @code{gnutls_privkey_t} and @code{gnutls_pubkey_t} were
533 introduced in @code{gnutls/abstract.h} header. Those types are initialized using a specific type of key and then can be used to
534 perform operations in an abstract way. For example in order for someone to sign an X.509 certificate
535 with a key that resides in a smart he has to follow the steps below:
538 #inlude <gnutls/abstract.h>
539 #inlude <gnutls/pkcs11.h>
541 void sign_cert( gnutls_x509_crt_t to_be_signed)
543 gnutls_pkcs11_privkey_t ca_key;
544 gnutls_x509_crt_t ca_cert;
545 gnutls_privkey_t abs_key;
547 /* load the PKCS #11 key and certificates */
548 gnutls_pkcs11_privkey_init(&ca_key);
549 gnutls_pkcs11_privkey_import_url(ca_key, key_url);
551 gnutls_x509_crt_init(&ca_cert);
552 gnutls_x509_crt_import_pkcs11_url(&ca_cert, cert_url);
554 /* initialize the abstract key */
555 gnutls_privkey_init(&abs_key);
556 gnutls_privkey_import_pkcs11(abs_key, ca_key);
558 /* sign the certificate to be signed */
559 gnutls_x509_crt_privkey_sign(to_be_signed, ca_cert, ca_key, GNUTLS_DIG_SHA1, 0);
564 @node Digital signatures
565 @section Digital Signatures
566 @cindex Digital signatures
568 In this section we will provide some information about digital
569 signatures, how they work, and give the rationale for disabling some
570 of the algorithms used.
572 Digital signatures work by using somebody's secret key to sign some
573 arbitrary data. Then anybody else could use the public key of that
574 person to verify the signature. Since the data may be arbitrary it is
575 not suitable input to a cryptographic digital signature algorithm. For
576 this reason and also for performance cryptographic hash algorithms are
577 used to preprocess the input to the signature algorithm. This works as
578 long as it is difficult enough to generate two different messages with
579 the same hash algorithm output. In that case the same signature could
580 be used as a proof for both messages. Nobody wants to sign an innocent
581 message of donating 1 euro to Greenpeace and find out that he
582 donated 1.000.000 euros to Bad Inc.
584 For a hash algorithm to be called cryptographic the following three
585 requirements must hold:
588 @item Preimage resistance.
589 That means the algorithm must be one way and given the output of the
590 hash function @math{H(x)}, it is impossible to calculate @math{x}.
592 @item 2nd preimage resistance.
593 That means that given a pair @math{x,y} with @math{y=H(x)} it is
594 impossible to calculate an @math{x'} such that @math{y=H(x')}.
596 @item Collision resistance.
597 That means that it is impossible to calculate random @math{x} and
598 @math{x'} such @math{H(x')=H(x)}.
601 The last two requirements in the list are the most important in
602 digital signatures. These protect against somebody who would like to
603 generate two messages with the same hash output. When an algorithm is
604 considered broken usually it means that the Collision resistance of
605 the algorithm is less than brute force. Using the birthday paradox the
606 brute force attack takes
608 @math{2^{(\rm{hash\ size}) / 2}}
611 @math{2^{((hash size) / 2)}}
613 operations. Today colliding certificates using the MD5 hash algorithm
614 have been generated as shown in @xcite{WEGER}.
616 There has been cryptographic results for the SHA-1 hash algorithms as
617 well, although they are not yet critical. Before 2004, MD5 had a
618 presumed collision strength of @math{2^{64}}, but it has been showed
619 to have a collision strength well under @math{2^{50}}. As of November
620 2005, it is believed that SHA-1's collision strength is around
621 @math{2^{63}}. We consider this sufficiently hard so that we still
622 support SHA-1. We anticipate that SHA-256/386/512 will be used in
623 publicly-distributed certificates in the future. When @math{2^{63}}
624 can be considered too weak compared to the computer power available
625 sometime in the future, SHA-1 will be disabled as well. The collision
626 attacks on SHA-1 may also get better, given the new interest in tools
629 @subsection Trading Security for Interoperability
631 If you connect to a server and use GnuTLS' functions to verify the
632 certificate chain, and get a @ref{GNUTLS_CERT_INSECURE_ALGORITHM}
633 validation error (@pxref{Verifying X.509 certificate paths}), it means
634 that somewhere in the certificate chain there is a certificate signed
635 using @code{RSA-MD2} or @code{RSA-MD5}. These two digital signature
636 algorithms are considered broken, so GnuTLS fail when attempting to
637 verify the certificate. In some situations, it may be useful to be
638 able to verify the certificate chain anyway, assuming an attacker did
639 not utilize the fact that these signatures algorithms are broken.
640 This section will give help on how to achieve that.
642 First, it is important to know that you do not have to enable any of
643 the flags discussed here to be able to use trusted root CA
644 certificates signed using @code{RSA-MD2} or @code{RSA-MD5}. The only
645 attack today is that it is possible to generate certificates with
646 colliding signatures (collision resistance); you cannot generate a
647 certificate that has the same signature as an already existing
648 signature (2nd preimage resistance).
650 If you are using @ref{gnutls_certificate_verify_peers2} to verify the
651 certificate chain, you can call
652 @ref{gnutls_certificate_set_verify_flags} with the
653 @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2} or
654 @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5} flag, as in:
657 gnutls_certificate_set_verify_flags (x509cred,
658 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
661 This will tell the verifier algorithm to enable @code{RSA-MD5} when
662 verifying the certificates.
664 If you are using @ref{gnutls_x509_crt_verify} or
665 @ref{gnutls_x509_crt_list_verify}, you can pass the
666 @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5} parameter directly in the
667 @code{flags} parameter.
669 If you are using these flags, it may also be a good idea to warn the
670 user when verification failure occur for this reason. The simplest is
671 to not use the flags by default, and only fall back to using them
672 after warning the user. If you wish to inspect the certificate chain
673 yourself, you can use @ref{gnutls_certificate_get_peers} to extract
674 the raw server's certificate chain, then use
675 @ref{gnutls_x509_crt_import} to parse each of the certificates, and
676 then use @ref{gnutls_x509_crt_get_signature_algorithm} to find out the
677 signing algorithm used for each certificate. If any of the
678 intermediary certificates are using @code{GNUTLS_SIGN_RSA_MD2} or
679 @code{GNUTLS_SIGN_RSA_MD5}, you could present a warning.