summaryrefslogtreecommitdiff
path: root/doc/signatures.texi
blob: 0d8a4c084f10869f671dcb0b16e9b46a09ed60d1 (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
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 thus not a suitable input to a cryptographic digital
signature algorithm and also for performance reasons 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 @euro{}
to Bad Inc. 

The available digital signature algorithms in @acronym{GnuTLS} are listed below:

@table @code
@item RSA
RSA is public key cryptosystem designed by
Ronald Rivest, Adi Shamir and Leonard Adleman. It can be used with any hash functions.

@item DSA
DSA is the USA's Digital Signature Standard. It uses only the SHA-1 hash algorithm.

@end table

The supported cryptographic hash algorithms are:

@table @code
@item MD2
MD2 is a cryptographic hash algorithm designed by Ron Rivest. It is
optimized for 8-bit processors. Outputs
128 bits of data. There are no known weaknesses of this algorithm but since this
algorithm is rarely used and not really studied it should not be used today.

@item MD5
MD5 is a cryptographic hash algorithm designed by Ron Rivest. Outputs
128 bits of data. It is considered to be broken. 

@item SHA-1
SHA is a cryptographic hash algorithm designed by NSA. Outputs 160
bits of data. It is also considered to be broken, though no practical
attacks have been found.

@item RMD160
RIPEMD is a cryptographic hash algorithm developed in the framework of
the EU project RIPE. Outputs 160 bits of data. 

@end table

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 @mybibcite{WEGER}.

@subsection Trading security for interoperability

If you connect to a server and use GnuTLS' functions to verify the
certificate chain, and get a @ref{GNUTLS_CERT_INSECURE_ALGORITHM}
validation error (@pxref{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 fail when attempting to
verify 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.

First, 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 signed using @code{RSA-MD2} or @code{RSA-MD5}.  The only
attack today is that it is possible to generate certificates with
colliding signatures (collision resistance); you cannot generate a
certificate that has the same signature as an already existing
signature (2nd preimage resistance).

If you are using @ref{gnutls_certificate_verify_peers2} to verify the
certificate chain, you can call
@ref{gnutls_certificate_set_verify_flags} with the
@code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2} or
@code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5} flag, as in:

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

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

If you are using @ref{gnutls_x509_crt_verify} or
@ref{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 @ref{gnutls_certificate_get_peers} to extract
the raw server's certificate chain, then use
@ref{gnutls_x509_crt_import} to parse each of the certificates, and
then use @ref{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.