summaryrefslogtreecommitdiff
path: root/doc/cha-cert-auth.texi
blob: e379e69a7f19df145d65ecb11dcb1c56d6f1f3b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
@node Certificate authentication
@chapter Certificate authentication
@cindex certificate authentication

The most known authentication method of @acronym{TLS} are certificates.
The PKIX @xcite{PKIX} public key infrastructure is daily used by anyone
using a browser today. @acronym{GnuTLS} supports both 
@acronym{X.509} certificates @xcite{PKIX} and @acronym{OpenPGP}
certificates using a common API.

The key exchange algorithms supported by certificate authentication are
shown in @ref{tab:key-exchange}.

@float Table,tab:key-exchange
@multitable @columnfractions .2 .7

@headitem Key exchange @tab Description

@item RSA @tab
The RSA algorithm is used to encrypt a key and send it to the peer.
The certificate must allow the key to be used for encryption.

@item RSA_@-EXPORT @tab
The RSA algorithm is used to encrypt a key and send it to the peer.
In the EXPORT algorithm, the server signs temporary RSA parameters of
512 bits --- which are considered weak --- and sends them to the
client.

@item DHE_@-RSA @tab
The RSA algorithm is used to sign ephemeral Diffie-Hellman parameters
which are sent to the peer. The key in the certificate must allow the
key to be used for signing. Note that key exchange algorithms which
use ephemeral Diffie-Hellman parameters, offer perfect forward
secrecy. That means that even if the private key used for signing is
compromised, it cannot be used to reveal past session data.

@item ECDHE_@-RSA @tab
The RSA algorithm is used to sign ephemeral elliptic curve Diffie-Hellman 
parameters which are sent to the peer. The key in the certificate must allow 
the key to be used for signing. It also offers perfect forward
secrecy. That means that even if the private key used for signing is
compromised, it cannot be used to reveal past session data.

@item DHE_@-DSS @tab
The DSA algorithm is used to sign ephemeral Diffie-Hellman parameters
which are sent to the peer. The certificate must contain DSA
parameters to use this key exchange algorithm. DSA is the algorithm
of the Digital Signature Standard (DSS).

@item ECDHE_@-ECDSA @tab
The Elliptic curve DSA algorithm is used to sign ephemeral elliptic
curve Diffie-Hellman parameters which are sent to the peer. The 
certificate must contain ECDSA parameters (i.e., EC and marked for signing) 
to use this key exchange algorithm. 

@end multitable
@caption{Supported key exchange algorithms.}
@end float

@menu
* X.509 certificates::
* OpenPGP certificates::
* Advanced certificate verification::
* Digital signatures::
@end menu

@node X.509 certificates
@section @acronym{X.509} certificates
@cindex X.509 certificates

The @acronym{X.509} protocols rely on a hierarchical trust model. In
this trust model Certification Authorities (CAs) are used to certify
entities.  Usually more than one certification authorities exist, and
certification authorities may certify other authorities to issue
certificates as well, following a hierarchical model.

@float Figure,fig:x509
@image{gnutls-x509,7cm}
@caption{An example of the X.509 hierarchical trust model.}
@end float

One needs to trust one or more CAs for his secure communications. In
that case only the certificates issued by the trusted authorities are
acceptable.  The framework is illustrated on @ref{fig:x509}.

@menu
* X.509 certificate structure::
* Importing an X.509 certificate::
* X.509 distinguished names::
* Verifying X.509 certificate paths::
* Verifying a certificate in the context of TLS session::
@end menu

@node X.509 certificate structure
@subsection @acronym{X.509} certificate structure

An @acronym{X.509} certificate usually contains information about the
certificate holder, the signer, a unique serial number, expiration
dates and some other fields @xcite{PKIX} as shown in @ref{tab:x509}.

@float Table,tab:x509
@multitable @columnfractions .2 .7

@headitem Field @tab Description

@item version @tab
The field that indicates the version of the certificate.

@item serialNumber @tab
This field holds a unique serial number per certificate.

@item signature @tab
The issuing authority's signature.

@item issuer @tab
Holds the issuer's distinguished name.

@item validity @tab
The activation and expiration dates.

@item subject @tab
The subject's distinguished name of the certificate.

@item extensions @tab
The extensions are fields only present in version 3 certificates.

@end multitable
@caption{X.509 certificate fields.}
@end float

The certificate's @emph{subject or issuer name} is not just a single
string.  It is a Distinguished name and in the @acronym{ASN.1}
notation is a sequence of several object identifiers with their corresponding
values. Some of available OIDs to be used in an @acronym{X.509}
distinguished name are defined in @file{gnutls/x509.h}.

The @emph{Version} field in a certificate has values either 1 or 3 for
version 3 certificates.  Version 1 certificates do not support the
extensions field so it is not possible to distinguish a CA from a
person, thus their usage should be avoided.

The @emph{validity} dates are there to indicate the date that the
specific certificate was activated and the date the certificate's key
would be considered invalid.

Certificate @emph{extensions} are there to include information about
the certificate's subject that did not fit in the typical certificate
fields. Those may be e-mail addresses, flags that indicate whether the
belongs to a CA etc.  All the supported @acronym{X.509} version 3
extensions are shown in @ref{tab:x509-ext}.

@float Table,tab:x509-ext
@multitable @columnfractions .3 .2 .4

@headitem Extension @tab OID @tab Description

@item Subject key id @tab 2.5.29.14 @tab
An identifier of the key of the subject.

@item Authority key id @tab 2.5.29.35 @tab
An identifier of the authority's key used to sign the certificate.

@item Subject alternative name @tab 2.5.29.17 @tab
Alternative names to subject's distinguished name.

@item Key usage @tab 2.5.29.15 @tab
Constraints the key's usage of the certificate.

@item Extended key usage @tab 2.5.29.37 @tab
Constraints the purpose of the certificate.

@item Basic constraints @tab 2.5.29.19 @tab
Indicates whether this is a CA certificate or not, and specify the
maximum path lengths of certificate chains.

@item CRL distribution points @tab 2.5.29.31 @tab
This extension is set by the CA, in order to inform about the issued
CRLs.

@item Proxy Certification Information @tab 1.3.6.1.5.5.7.1.14 @tab
Proxy Certificates includes this extension that contains the OID of
the proxy policy language used, and can specify limits on the maximum
lengths of proxy chains.  Proxy Certificates are specified in
@xcite{RFC3820}.

@end multitable
@caption{X.509 certificate extensions.}
@end float

In @acronym{GnuTLS} the @acronym{X.509} certificate structures are
handled using the @code{gnutls_x509_crt_t} type and the corresponding
private keys with the @code{gnutls_x509_privkey_t} type.  All the
available functions for @acronym{X.509} certificate handling have
their prototypes in @file{gnutls/x509.h}. An example program to
demonstrate the @acronym{X.509} parsing capabilities can be found in
@ref{ex:x509-info}.

@node Importing an X.509 certificate
@subsection Importing an X.509 certificate

The certificate structure should be initialized using @funcref{gnutls_x509_crt_init}, and 
a certificate structure can be imported using @funcref{gnutls_x509_crt_import}. 

@showfuncC{gnutls_x509_crt_init,gnutls_x509_crt_import,gnutls_x509_crt_deinit}

In several functions an array of certificates is required. To assist in initialization
and import the following two functions are provided.

@showfuncB{gnutls_x509_crt_list_import,gnutls_x509_crt_list_import2}

In all cases after use a certificate must be deinitialized using @funcref{gnutls_x509_crt_deinit}.
Note that although the functions above apply to @code{gnutls_x509_crt_t} structure, similar functions
exist for the CRL structure @code{gnutls_x509_crl_t}.

@node X.509 distinguished names
@subsection X.509 distinguished names
@cindex X.509 distinguished name

The ``subject'' of an X.509 certificate is not described by
a single name, but rather with a distinguished name. This in
X.509 terminology is a list of strings each associated an object
identifier. To make things simple GnuTLS provides @funcref{gnutls_x509_crt_get_dn}
which follows the rules in @xcite{RFC4514} and returns a single
string. Access to each string by individual object identifiers
can be accessed using @funcref{gnutls_x509_crt_get_dn_by_oid}.

@showfuncdesc{gnutls_x509_crt_get_dn}
@showfuncdesc{gnutls_x509_crt_get_dn_by_oid}
@showfuncdesc{gnutls_x509_crt_get_dn_oid}

The more powerful @funcref{gnutls_x509_crt_get_subject} and 
@funcref{gnutls_x509_dn_get_rdn_ava} provide efficient access
to the contents of the distinguished name structure.

@showfuncdesc{gnutls_x509_crt_get_subject}
@showfuncdesc{gnutls_x509_dn_get_rdn_ava}

Similar functions exist to access the distinguished name
of the issuer of the certificate.

@showfuncD{gnutls_x509_crt_get_issuer_dn,gnutls_x509_crt_get_issuer_dn_by_oid,gnutls_x509_crt_get_issuer_dn_oid,gnutls_x509_crt_get_issuer}

@node Verifying X.509 certificate paths
@subsection Verifying @acronym{X.509} certificate paths
@cindex verifying certificate paths

Verifying certificate paths is important in @acronym{X.509}
authentication. For this purpose the following functions are
provided.

@showfuncdesc{gnutls_x509_trust_list_add_cas}
@showfuncdesc{gnutls_x509_trust_list_add_named_crt}
@showfuncdesc{gnutls_x509_trust_list_add_crls}
@showfuncdesc{gnutls_x509_trust_list_verify_crt}
@showfuncdesc{gnutls_x509_trust_list_verify_named_crt}

@showfuncdesc{gnutls_x509_trust_list_add_trust_file}
@showfuncdesc{gnutls_x509_trust_list_add_trust_mem}
@showfuncdesc{gnutls_x509_trust_list_add_system_trust}

The verification function will verify a given certificate chain against a list of certificate
authorities and certificate revocation lists, and output
a bit-wise OR of elements of the @code{gnutls_@-certificate_@-status_t} 
enumeration shown in @ref{gnutls_certificate_status_t}. The @code{GNUTLS_@-CERT_@-INVALID} flag
is always set on a verification error and more detailed flags will also be set when appropriate.

@showenumdesc{gnutls_certificate_status_t,The @code{gnutls_@-certificate_@-status_t} enumeration.}

An example of certificate verification is shown in @ref{ex:verify2}.
It is also possible to have a set of certificates that
are trusted for a particular server but not to authorize other certificates.
This purpose is served by the functions @funcref{gnutls_x509_trust_list_add_named_crt} and @funcref{gnutls_x509_trust_list_verify_named_crt}.

@node Verifying a certificate in the context of TLS session
@subsection Verifying a certificate in the context of TLS session
@cindex verifying certificate paths
@tindex gnutls_certificate_verify_flags

When operating in the context of a TLS session, the trusted certificate
authority list may also be set using:
@showfuncC{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_crl_file,gnutls_certificate_set_x509_system_trust}

Then it is not required to setup a trusted list as above.
The function @funcref{gnutls_certificate_verify_peers3} 
may then be used to verify the peer's certificate chain and identity. The flags
are set similarly to the verification functions in the previous section.

There is also the possibility to pass some input to the verification
functions in the form of flags. For @funcref{gnutls_x509_trust_list_verify_crt} the
flags are passed straightforward, but
@funcref{gnutls_certificate_verify_peers3} depends on the flags set by
calling @funcref{gnutls_certificate_set_verify_flags}.  All the available
flags are part of the enumeration
@code{gnutls_@-certificate_@-verify_@-flags} shown in @ref{gnutls_certificate_verify_flags}.

@showenumdesc{gnutls_certificate_verify_flags,The @code{gnutls_@-certificate_@-verify_@-flags} enumeration.}


@node OpenPGP certificates
@section @acronym{OpenPGP} certificates
@cindex OpenPGP certificates

The @acronym{OpenPGP} key authentication relies on a distributed trust
model, called the ``web of trust''. The ``web of trust'' uses a
decentralized system of trusted introducers, which are the same as a
CA. @acronym{OpenPGP} allows anyone to sign anyone else's public
key. When Alice signs Bob's key, she is introducing Bob's key to
anyone who trusts Alice. If someone trusts Alice to introduce keys,
then Alice is a trusted introducer in the mind of that observer.
For example in @ref{fig:openpgp}, David trusts Alice to be an introducer and Alice
signed Bob's key thus Dave trusts Bob's key to be the real one.

@float Figure,fig:openpgp
@image{gnutls-pgp,8cm}
@caption{An example of the OpenPGP trust model.}
@end float

There are some key points that are important in that model. In the
example Alice has to sign Bob's key, only if she is sure that the key
belongs to Bob. Otherwise she may also make Dave falsely believe that
this is Bob's key. Dave has also the responsibility to know who to
trust.  This model is similar to real life relations.

Just see how Charlie behaves in the previous example. Although he has
signed Bob's key - because he knows, somehow, that it belongs to Bob -
he does not trust Bob to be an introducer. Charlie decided to trust
only Kevin, for some reason. A reason could be that Bob is lazy
enough, and signs other people's keys without being sure that they
belong to the actual owner.

@float Table,tab:openpgp-certificate
@multitable @columnfractions .2 .7

@headitem Field @tab Description

@item version @tab
The field that indicates the version of the OpenPGP structure.

@item user ID @tab
An RFC 2822 string that identifies the owner of the key. There may be
multiple user identifiers in a key.

@item public key @tab
The main public key of the certificate.

@item expiration @tab
The expiration time of the main public key.

@item public subkey @tab
An additional public key of the certificate. There may be multiple subkeys
in a certificate.

@item public subkey expiration @tab
The expiration time of the subkey.

@end multitable
@caption{OpenPGP certificate fields.}
@end float


@subsection @acronym{OpenPGP} certificate structure

In @acronym{GnuTLS} the @acronym{OpenPGP} certificate structures
@xcite{RFC2440} are handled using the @code{gnutls_openpgp_crt_t} type.
A typical certificate contains the user ID, which is an RFC 2822
mail and name address, a public key, possibly a number of additional
public keys (called subkeys), and a number of signatures. The various
fields are shown in @ref{tab:openpgp-certificate}.

The additional subkeys may provide key for various different purposes,
e.g. one key to encrypt mail, and another to sign a TLS key exchange.
Each subkey is identified by a unique key ID.
The keys that are to be used in a TLS key exchange that requires
signatures are called authentication keys in the OpenPGP jargon.
The mapping of TLS key exchange methods to public keys is shown in
@ref{tab:openpgp-key-exchange}.

@float Table,tab:openpgp-key-exchange
@multitable @columnfractions .2 .7

@headitem Key exchange @tab Public key requirements

@item RSA @tab
An RSA public key that allows encryption.

@item DHE_@-RSA @tab
An RSA public key that is marked for authentication.

@item ECDHE_@-RSA @tab
An RSA public key that is marked for authentication.

@item DHE_@-DSS @tab
A DSA public key that is marked for authentication.

@end multitable
@caption{The types of (sub)keys required for the various TLS key exchange methods.}
@end float

The corresponding private keys are stored in the
@code{gnutls_openpgp_privkey_t} type. All the prototypes for the key
handling functions can be found in @file{gnutls/openpgp.h}.

@subsection Verifying an @acronym{OpenPGP} certificate

The verification functions of @acronym{OpenPGP} keys, included in
@acronym{GnuTLS}, are simple ones, and do not use the features of the
``web of trust''.  For that reason, if the verification needs are
complex, the assistance of external tools like @acronym{GnuPG} and
GPGME@footnote{@url{http://www.gnupg.org/related_software/gpgme/}} is
recommended.

In GnuTLS there is a verification function for OpenPGP certificates,
the @funcref{gnutls_openpgp_crt_verify_ring}.  This checks an
@acronym{OpenPGP} key against a given set of public keys (keyring) and
returns the key status. The key verification status is the same as in
@acronym{X.509} certificates, although the meaning and interpretation
are different. For example an @acronym{OpenPGP} key may be valid, if
the self signature is ok, even if no signers were found.  The meaning
of verification status flags is the same as in the @acronym{X.509} certificates
(see @ref{gnutls_certificate_verify_flags}).

@showfuncdesc{gnutls_openpgp_crt_verify_ring}

@showfuncdesc{gnutls_openpgp_crt_verify_self}

@subsection Verifying a certificate in the context of a TLS session

Similarly with X.509 certificates, one needs to specify
the OpenPGP keyring file in the credentials structure. The certificates
in this file will be  used by @funcref{gnutls_certificate_verify_peers3}
to verify the signatures in the certificate sent by the peer.

@showfuncdesc{gnutls_certificate_set_openpgp_keyring_file}

@node Advanced certificate verification
@section Advanced certificate verification
@cindex Certificate verification

The verification of X.509 certificates in the HTTPS and other Internet protocols is typically 
done by loading a trusted list of commercial Certificate Authorities
(see @funcref{gnutls_certificate_set_x509_system_trust}), and using them as trusted anchors.
However, there are several examples (eg. the Diginotar incident) where one of these
authorities was compromised. This risk can be mitigated by using in addition to CA certificate verification,
other verification methods. In this section we list the available in GnuTLS methods.

@menu
* Verifying a certificate using trust on first use authentication::
* Verifying a certificate using DANE (DNSSEC)::
@end menu

@node Verifying a certificate using trust on first use authentication
@subsection Verifying a certificate using trust on first use authentication
@cindex verifying certificate paths
@cindex SSH-style authentication
@cindex Trust on first use
@cindex Key pinning

It is possible to use a trust on first use (TOFU) authentication 
method in GnuTLS. That is the concept used by the SSH programs, where the 
public key of the peer is not verified, or verified in an out-of-bound way,
but subsequent connections to the same peer require the public key to 
remain the same.  Such a system in combination with the typical CA 
verification of a certificate, and OCSP revocation checks,
can help to provide multiple factor verification, where a single point of
failure is not enough to compromise the system. For example a server compromise
may be detected using OCSP, and a CA compromise can be detected using
the trust on first use method.
Such a hybrid system with X.509 and trust on first use authentication is 
shown in @ref{Simple client example with SSH-style certificate verification}.

See @ref{Certificate verification} on how to use the available functionality.

@node Verifying a certificate using DANE (DNSSEC)
@subsection Verifying a certificate using DANE (DNSSEC)
@cindex verifying certificate paths
@cindex DANE
@cindex DNSSEC

The DANE protocol is a protocol that can be used to verify TLS certificates
using the DNS (or better DNSSEC) protocols. The DNS security extensions (DNSSEC)
provide an alternative public key infrastructure to the commercial CAs that
are typically used to sign TLS certificates. The DANE protocol takes advantage
of the DNSSEC infrastructure to verify TLS certificates. This can be 
in addition to the verification by CA infrastructure or 
could even replace it where DNSSEC is deployed.

The DANE functionality is provided by the @code{libgnutls-dane} library that is shipped
with GnuTLS and the function prototypes are in @code{gnutls/dane.h}. 
See @ref{Certificate verification} for information on how to use the library.

@node Digital signatures
@section Digital signatures
@cindex digital signatures

In this section we will provide some information about digital
signatures, how they work, and give the rationale for disabling some
of the algorithms used.

Digital signatures work by using somebody's secret key to sign some
arbitrary data.  Then anybody else could use the public key of that
person to verify the signature.  Since the data may be arbitrary it is
not suitable input to a cryptographic digital signature algorithm. For
this reason and also for performance cryptographic hash algorithms are
used to preprocess the input to the signature algorithm. This works as
long as it is difficult enough to generate two different messages with
the same hash algorithm output. In that case the same signature could
be used as a proof for both messages. Nobody wants to sign an innocent
message of donating 1 euro to Greenpeace and find out that he
donated 1.000.000 euros to Bad Inc.

For a hash algorithm to be called cryptographic the following three
requirements must hold:

@enumerate
@item Preimage resistance.
That means the algorithm must be one way and given the output of the
hash function @math{H(x)}, it is impossible to calculate @math{x}.

@item 2nd preimage resistance.
That means that given a pair @math{x,y} with @math{y=H(x)} it is
impossible to calculate an @math{x'} such that @math{y=H(x')}.

@item Collision resistance.
That means that it is impossible to calculate random @math{x} and
@math{x'} such @math{H(x')=H(x)}.
@end enumerate

The last two requirements in the list are the most important in
digital signatures. These protect against somebody who would like to
generate two messages with the same hash output. When an algorithm is
considered broken usually it means that the Collision resistance of
the algorithm is less than brute force. Using the birthday paradox the
brute force attack takes
@iftex
@math{2^{(\rm{hash\ size}) / 2}}
@end iftex
@ifnottex
@math{2^{((hash size) / 2)}}
@end ifnottex
operations. Today colliding certificates using the MD5 hash algorithm
have been generated as shown in @xcite{WEGER}.

There has been cryptographic results for the SHA-1 hash algorithms as
well, although they are not yet critical.  Before 2004, MD5 had a
presumed collision strength of @math{2^{64}}, but it has been showed
to have a collision strength well under @math{2^{50}}.  As of November
2005, it is believed that SHA-1's collision strength is around
@math{2^{63}}.  We consider this sufficiently hard so that we still
support SHA-1.  We anticipate that SHA-256/386/512 will be used in
publicly-distributed certificates in the future.  When @math{2^{63}}
can be considered too weak compared to the computer power available
sometime in the future, SHA-1 will be disabled as well.  The collision
attacks on SHA-1 may also get better, given the new interest in tools
for creating them.

@subsection Trading security for interoperability

If you connect to a server and use GnuTLS' functions to verify the
certificate chain, and get a @code{GNUTLS_CERT_INSECURE_ALGORITHM}
validation error (see @ref{Verifying X.509 certificate paths}), it means
that somewhere in the certificate chain there is a certificate signed
using @code{RSA-MD2} or @code{RSA-MD5}.  These two digital signature
algorithms are considered broken, so GnuTLS fails verifying
the certificate.  In some situations, it may be useful to be
able to verify the certificate chain anyway, assuming an attacker did
not utilize the fact that these signatures algorithms are broken.
This section will give help on how to achieve that.

It is important to know that you do not have to enable any of
the flags discussed here to be able to use trusted root CA
certificates self-signed using @code{RSA-MD2} or @code{RSA-MD5}. The
certificates in the trusted list are considered trusted irrespective
of the signature.

If you are using @funcref{gnutls_certificate_verify_peers3} to verify the
certificate chain, you can call
@funcref{gnutls_certificate_set_verify_flags} with the flags:
@itemize
@item @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2}
@item @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5}
@end itemize
as in the following example:

@example
  gnutls_certificate_set_verify_flags (x509cred,
                                       GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
@end example

This will signal the verifier algorithm to enable @code{RSA-MD5} when
verifying the certificates.

If you are using @funcref{gnutls_x509_crt_verify} or
@funcref{gnutls_x509_crt_list_verify}, you can pass the
@code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5} parameter directly in the
@code{flags} parameter.

If you are using these flags, it may also be a good idea to warn the
user when verification failure occur for this reason.  The simplest is
to not use the flags by default, and only fall back to using them
after warning the user.  If you wish to inspect the certificate chain
yourself, you can use @funcref{gnutls_certificate_get_peers} to extract
the raw server's certificate chain, @funcref{gnutls_x509_crt_list_import} to parse each of the certificates, and
then @funcref{gnutls_x509_crt_get_signature_algorithm} to find out the
signing algorithm used for each certificate.  If any of the
intermediary certificates are using @code{GNUTLS_SIGN_RSA_MD2} or
@code{GNUTLS_SIGN_RSA_MD5}, you could present a warning.