Sicherung
[gnupg.git] / g10 / sig-check.c
1 /* sig-check.c -  Check a signature
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
6  * GNUPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include "util.h"
27 #include "packet.h"
28 #include "memory.h"
29 #include "mpi.h"
30 #include "keydb.h"
31 #include "cipher.h"
32 #include "main.h"
33 #include "status.h"
34
35
36 static int do_check( PKT_public_cert *pkc, PKT_signature *sig,
37                                                 MD_HANDLE digest );
38
39
40 /****************
41  * Check the signature which is contained in SIG.
42  * The md5handle should be currently open, so that this function
43  * is able to append some data, before finalizing the digest.
44  */
45 int
46 signature_check( PKT_signature *sig, MD_HANDLE digest )
47 {
48     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
49     int rc=0;
50
51
52   #ifndef HAVE_RSA_CIPHER
53     if( is_RSA(sig->pubkey_algo) )
54         write_status(STATUS_RSA_OR_IDEA);
55   #endif
56
57     if( get_pubkey( pkc, sig->keyid ) )
58         rc = G10ERR_NO_PUBKEY;
59     else
60         rc = do_check( pkc, sig, digest );
61
62     free_public_cert( pkc );
63     return rc;
64 }
65
66
67 static int
68 do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
69 {
70     MPI result = NULL;
71     int rc=0;
72
73     if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
74         log_info("this is a PGP generated "
75                  "ElGamal key which is NOT secure for signatures!\n");
76         return G10ERR_PUBKEY_ALGO;
77     }
78
79     if( pkc->timestamp > sig->timestamp )
80         return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */
81
82     if( is_ELGAMAL(pkc->pubkey_algo) ) {
83         if( (rc=check_digest_algo(sig->digest_algo)) )
84             goto leave;
85         /* make sure the digest algo is enabled (in case of a detached
86          * signature */
87         md_enable( digest, sig->digest_algo );
88         /* complete the digest */
89         md_putc( digest, sig->sig_class );
90         {   u32 a = sig->timestamp;
91             md_putc( digest, (a >> 24) & 0xff );
92             md_putc( digest, (a >> 16) & 0xff );
93             md_putc( digest, (a >>  8) & 0xff );
94             md_putc( digest,  a        & 0xff );
95         }
96         md_final( digest );
97         result = encode_md_value( digest, sig->digest_algo,
98                                           mpi_get_nbits(pkc->d.elg.p));
99         if( DBG_CIPHER )
100             log_mpidump("calc sig frame (elg): ", result);
101         if( !elg_verify( sig->d.elg.a, sig->d.elg.b, result, &pkc->d.elg ) )
102             rc = G10ERR_BAD_SIGN;
103     }
104     else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
105         if( (rc=check_digest_algo(sig->digest_algo)) )
106             goto leave;
107         /* make sure the digest algo is enabled (in case of a detached
108          * signature */
109         md_enable( digest, sig->digest_algo );
110
111         /* complete the digest */
112         if( sig->version >= 4 )
113             md_putc( digest, sig->version );
114         md_putc( digest, sig->sig_class );
115         if( sig->version < 4 ) {
116             u32 a = sig->timestamp;
117             md_putc( digest, (a >> 24) & 0xff );
118             md_putc( digest, (a >> 16) & 0xff );
119             md_putc( digest, (a >>  8) & 0xff );
120             md_putc( digest,  a        & 0xff );
121         }
122         else {
123             byte buf[6];
124             size_t n;
125             md_putc( digest, sig->pubkey_algo );
126             md_putc( digest, sig->digest_algo );
127             if( sig->hashed_data ) {
128                 n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
129                 md_write( digest, sig->hashed_data, n+2 );
130                 n += 6;
131             }
132             else
133                 n = 6;
134             /* add some magic */
135             buf[0] = sig->version;
136             buf[1] = 0xff;
137             buf[2] = n >> 24;
138             buf[3] = n >> 16;
139             buf[4] = n >>  8;
140             buf[5] = n;
141             md_write( digest, buf, 6 );
142         }
143         md_final( digest );
144
145         result = mpi_alloc( (md_digest_length(sig->digest_algo)
146                              +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
147         mpi_set_buffer( result, md_read(digest, sig->digest_algo),
148                                 md_digest_length(sig->digest_algo), 0 );
149         if( DBG_CIPHER )
150             log_mpidump("calc sig frame: ", result);
151         if( !dsa_verify( sig->d.dsa.r, sig->d.dsa.s, result, &pkc->d.dsa ) )
152             rc = G10ERR_BAD_SIGN;
153     }
154  #ifdef HAVE_RSA_CIPHER
155     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA
156              || pkc->pubkey_algo == PUBKEY_ALGO_RSA_S ) {
157         int i, j, c, old_enc;
158         byte *dp;
159         const byte *asn;
160         size_t mdlen, asnlen;
161
162         result = mpi_alloc(40);
163         rsa_public( result, sig->d.rsa.rsa_integer, &pkc->d.rsa );
164
165         old_enc = 0;
166         for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
167             if( !j ) {
168                 if( !i && c != 1 )
169                     break;
170                 else if( i && c == 0xff )
171                     ; /* skip the padding */
172                 else if( i && !c )
173                     j++;
174                 else
175                     break;
176             }
177             else if( ++j == 18 && c != 1 )
178                 break;
179             else if( j == 19 && c == 0 ) {
180                 old_enc++;
181                 break;
182             }
183         }
184         if( old_enc ) {
185             log_error("old encoding scheme is not supported\n");
186             rc = G10ERR_GENERAL;
187             goto leave;
188         }
189
190         if( (rc=check_digest_algo(sig->digest_algo)) )
191             goto leave; /* unsupported algo */
192         md_enable( digest, sig->digest_algo );
193         asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
194
195         for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
196                                                                i++, j-- )
197             if( asn[j] != c )
198                 break;
199         if( j != -1 || mpi_getbyte(result, i) ) { /* ASN is wrong */
200             rc = G10ERR_BAD_PUBKEY;
201             goto leave;
202         }
203         for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
204             if( c != 0xff  )
205                 break;
206         i++;
207         if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
208             /* Padding or leading bytes in signature is wrong */
209             rc = G10ERR_BAD_PUBKEY;
210             goto leave;
211         }
212         if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
213             || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
214             /* Wrong key used to check the signature */
215             rc = G10ERR_BAD_PUBKEY;
216             goto leave;
217         }
218
219         /* complete the digest */
220         md_putc( digest, sig->sig_class );
221         {   u32 a = sig->timestamp;
222             md_putc( digest, (a >> 24) & 0xff );
223             md_putc( digest, (a >> 16) & 0xff );
224             md_putc( digest, (a >>  8) & 0xff );
225             md_putc( digest,  a        & 0xff );
226         }
227         md_final( digest );
228         dp = md_read( digest, sig->digest_algo );
229         for(i=mdlen-1; i >= 0; i--, dp++ ) {
230             if( mpi_getbyte( result, i ) != *dp ) {
231                 rc = G10ERR_BAD_SIGN;
232                 goto leave;
233             }
234         }
235     }
236   #endif/*HAVE_RSA_CIPHER*/
237     else {
238         /*log_debug("signature_check: unsupported pubkey algo %d\n",
239                         pkc->pubkey_algo );*/
240         rc = G10ERR_PUBKEY_ALGO;
241         goto leave;
242     }
243
244
245   leave:
246     mpi_free( result );
247     return rc;
248 }
249
250
251 static void
252 hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
253 {
254     PKT_user_id *uid = unode->pkt->pkt.user_id;
255
256     assert( unode->pkt->pkttype == PKT_USER_ID );
257     if( sig->version >=4 ) {
258         byte buf[5];
259         buf[0] = 0xb4; /* indicates a userid packet */
260         buf[1] = uid->len >> 24;  /* always use 4 length bytes */
261         buf[2] = uid->len >> 16;
262         buf[3] = uid->len >>  8;
263         buf[4] = uid->len;
264         md_write( md, buf, 5 );
265     }
266     md_write( md, uid->name, uid->len );
267 }
268
269 /****************
270  * check the signature pointed to by NODE. This is a key signature.
271  * If the function detects a self-signature, it uses the PKC from
272  * NODE and does not read any public key.
273  */
274 int
275 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
276 {
277     MD_HANDLE md;
278     PKT_public_cert *pkc;
279     PKT_signature *sig;
280     int algo;
281     int rc;
282
283     if( is_selfsig )
284         *is_selfsig = 0;
285     assert( node->pkt->pkttype == PKT_SIGNATURE );
286     assert( root->pkt->pkttype == PKT_PUBLIC_CERT );
287
288     pkc = root->pkt->pkt.public_cert;
289     sig = node->pkt->pkt.signature;
290     algo = sig->digest_algo;
291     if( (rc=check_digest_algo(algo)) )
292         return rc;
293
294     if( sig->sig_class == 0x20 ) {
295         md = md_open( algo, 0 );
296         hash_public_cert( md, pkc );
297         rc = do_check( pkc, sig, md );
298         md_close(md);
299     }
300     else if( sig->sig_class == 0x18 ) {
301         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBKEY_SUBCERT );
302
303         if( snode ) {
304             if( is_selfsig ) {
305                 u32 keyid[2];
306
307                 keyid_from_pkc( pkc, keyid );
308                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
309                     *is_selfsig = 1;
310             }
311             md = md_open( algo, 0 );
312             hash_public_cert( md, pkc );
313             hash_public_cert( md, snode->pkt->pkt.public_cert );
314             rc = do_check( pkc, sig, md );
315             md_close(md);
316         }
317         else {
318             log_error("no subkey for key signature packet\n");
319             rc = G10ERR_SIG_CLASS;
320         }
321     }
322     else {
323         KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
324
325         if( unode ) {
326             u32 keyid[2];
327
328             keyid_from_pkc( pkc, keyid );
329             md = md_open( algo, 0 );
330             /*md_start_debug(md, "check");*/
331             hash_public_cert( md, pkc );
332             hash_uid_node( unode, md, sig );
333             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
334                 if( is_selfsig )
335                     *is_selfsig = 1;
336                 rc = do_check( pkc, sig, md );
337             }
338             else
339                 rc = signature_check( sig, md );
340             md_close(md);
341         }
342         else {
343             log_error("no user id for key signature packet\n");
344             rc = G10ERR_SIG_CLASS;
345         }
346     }
347
348     return rc;
349 }
350
351