* gpgsm.c (main): Don't print the "go ahead" message for an
[gnupg.git] / sm / sign.c
1 /* sign.c - Sign a message
2  *      Copyright (C) 2001 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 <errno.h>
26 #include <unistd.h> 
27 #include <time.h>
28 #include <assert.h>
29
30 #include <gcrypt.h>
31 #include <ksba.h>
32
33 #include "gpgsm.h"
34 #include "keydb.h"
35 #include "i18n.h"
36
37
38 static void
39 hash_data (int fd, GCRY_MD_HD md)
40 {
41   FILE *fp;
42   char buffer[4096];
43   int nread;
44
45   fp = fdopen ( dup (fd), "rb");
46   if (!fp)
47     {
48       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
49       return;
50     }
51
52   do 
53     {
54       nread = fread (buffer, 1, DIM(buffer), fp);
55       gcry_md_write (md, buffer, nread);
56     }
57   while (nread);
58   if (ferror (fp))
59       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
60   fclose (fp);
61 }
62
63
64 /* Get the default certificate which is defined as the first one our
65    keyDB retruns and has a secret key available */
66 int
67 gpgsm_get_default_cert (KsbaCert *r_cert)
68 {
69   KEYDB_HANDLE hd;
70   KsbaCert cert = NULL;
71   int rc;
72   char *p;
73
74   hd = keydb_new (0);
75   if (!hd)
76     return GNUPG_General_Error;
77   rc = keydb_search_first (hd);
78   if (rc)
79     {
80       keydb_release (hd);
81       return rc;
82     }
83
84   do
85     {
86       rc = keydb_get_cert (hd, &cert);
87       if (rc) 
88         {
89           log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc));
90           keydb_release (hd);
91           return rc;
92         }
93       
94       p = gpgsm_get_keygrip_hexstring (cert);
95       if (p)
96         {
97           if (!gpgsm_agent_havekey (p))
98             {
99               xfree (p);
100               keydb_release (hd);
101               *r_cert = cert;
102               return 0; /* got it */
103             }
104           xfree (p);
105         }
106     
107       ksba_cert_release (cert); 
108       cert = NULL;
109     }
110   while (!(rc = keydb_search_next (hd)));
111   if (rc && rc != -1)
112     log_error ("keydb_search_next failed: %s\n", gnupg_strerror (rc));
113   
114   ksba_cert_release (cert);
115   keydb_release (hd);
116   return rc;
117 }
118
119
120 static KsbaCert
121 get_default_signer (void)
122 {
123   KEYDB_SEARCH_DESC desc;
124   KsbaCert cert = NULL;
125   KEYDB_HANDLE kh = NULL;
126   int rc;
127
128   if (!opt.local_user)
129     {
130       rc = gpgsm_get_default_cert (&cert);
131       if (rc)
132         {
133           if (rc != -1)
134             log_debug ("failed to find default certificate: %s\n",
135                        gnupg_strerror (rc));
136           return NULL;
137         }
138       return cert;
139     }
140
141   rc = keydb_classify_name (opt.local_user, &desc);
142   if (rc)
143     {
144       log_error ("failed to find default signer: %s\n", gnupg_strerror (rc));
145       return NULL;
146     }
147
148   kh = keydb_new (0);
149   if (!kh)
150     return NULL;
151
152   rc = keydb_search (kh, &desc, 1);
153   if (rc)
154     {
155       log_debug ("failed to find default certificate: rc=%d\n", rc);
156     }
157   else 
158     {
159       rc = keydb_get_cert (kh, &cert);
160       if (rc)
161         {
162           log_debug ("failed to get cert: rc=%d\n", rc);
163         }
164     }
165
166   keydb_release (kh);
167   return cert;
168 }
169
170
171
172 /* Depending on the options in CTRL add the certificate CERT as well as
173    other certificate up in the chain to the Root-CA to the CMS
174    object. */
175 static int 
176 add_certificate_list (CTRL ctrl, KsbaCMS cms, KsbaCert cert)
177 {
178   KsbaError err;
179   int rc = 0;
180   KsbaCert next = NULL;
181   int n;
182   int not_root = 0;
183
184   ksba_cert_ref (cert);
185
186   n = ctrl->include_certs;
187   if (n == -2)
188     {
189       not_root = 1;
190       n = -1;
191     }
192   if (n < 0 || n > 50)
193     n = 50; /* We better apply an upper bound */
194
195   if (n)
196     {
197       if (not_root && gpgsm_is_root_cert (cert))
198         err = 0;
199       else
200         err = ksba_cms_add_cert (cms, cert);
201       if (err)
202         goto ksba_failure;
203     }
204   while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) )
205     {
206       if (not_root && gpgsm_is_root_cert (next))
207         err = 0;
208       else
209         err = ksba_cms_add_cert (cms, next);
210       ksba_cert_release (cert);
211       cert = next; next = NULL;
212       if (err)
213         goto ksba_failure;
214     }
215   ksba_cert_release (cert);
216
217   return rc == -1? 0: rc;
218
219  ksba_failure:
220   ksba_cert_release (cert);
221   log_error ("ksba_cms_add_cert failed: %s\n", ksba_strerror (err));
222   return map_ksba_err (err);
223 }
224
225
226
227 \f
228 /* Perform a sign operation.  
229
230    Sign the data received on DATA-FD in embedded mode or in deatched
231    mode when DETACHED is true.  Write the signature to OUT_FP The key
232    used to sign is the default - we will extend the fucntion to take a
233    list of fingerprints in the future. */
234 int
235 gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
236 {
237   int i, rc;
238   KsbaError err;
239   Base64Context b64writer = NULL;
240   KsbaWriter writer;
241   KsbaCMS cms = NULL;
242   KsbaStopReason stopreason;
243   KsbaCert cert = NULL;
244   KEYDB_HANDLE kh = NULL;
245   GCRY_MD_HD data_md = NULL;
246   int signer;
247   const char *algoid;
248   int algo;
249   time_t signed_at;
250
251   if (!detached)
252     {
253        rc = seterr (Not_Implemented);
254        goto leave;
255     }
256
257
258   kh = keydb_new (0);
259   if (!kh)
260     {
261       log_error (_("failed to allocated keyDB handle\n"));
262       rc = GNUPG_General_Error;
263       goto leave;
264     }
265
266   ctrl->pem_name = "SIGNED MESSAGE";
267   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
268   if (rc)
269     {
270       log_error ("can't create writer: %s\n", gnupg_strerror (rc));
271       goto leave;
272     }
273
274   cms = ksba_cms_new ();
275   if (!cms)
276     {
277       rc = seterr (Out_Of_Core);
278       goto leave;
279     }
280
281   err = ksba_cms_set_reader_writer (cms, NULL, writer);
282   if (err)
283     {
284       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
285                  ksba_strerror (err));
286       rc = map_ksba_err (err);
287       goto leave;
288     }
289
290   /* We are going to create signed data with data as encap. content */
291   err = ksba_cms_set_content_type (cms, 0, KSBA_CT_SIGNED_DATA);
292   if (!err)
293     err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
294   if (err)
295     {
296       log_debug ("ksba_cms_set_content_type failed: %s\n",
297                  ksba_strerror (err));
298       rc = map_ksba_err (err);
299       goto leave;
300     }
301
302
303   /* gather certificates of signers  and store in theCMS object */
304   /* fixme: process a list of fingerprints and store the certificate of
305      each given fingerprint */
306   cert = get_default_signer ();
307   if (!cert)
308     {
309       log_error ("no default signer found\n");
310       rc = seterr (General_Error);
311       goto leave;
312     }
313   rc = gpgsm_cert_use_sign_p (cert);
314   if (rc)
315     goto leave;
316
317   err = ksba_cms_add_signer (cms, cert);
318   if (err)
319     {
320       log_error ("ksba_cms_add_signer failed: %s\n",  ksba_strerror (err));
321       rc = map_ksba_err (err);
322       goto leave;
323     }
324   rc = add_certificate_list (ctrl, cms, cert);
325   if (rc)
326     {
327       log_error ("failed to store list of certificates: %s\n",
328                  gnupg_strerror(rc));
329       goto leave;
330     }
331   ksba_cert_release (cert); cert = NULL;
332
333   
334   /* Set the hash algorithm we are going to use */
335   err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/);
336   if (err)
337     {
338       log_debug ("ksba_cms_add_digest_algo failed: %s\n", ksba_strerror (err));
339       rc = map_ksba_err (err);
340       goto leave;
341     }
342
343   /* Prepare hashing (actually we are figuring out what we have set above)*/
344   data_md = gcry_md_open (0, 0);
345   if (!data_md)
346     {
347       rc = map_gcry_err (gcry_errno());
348       log_error ("md_open failed: %s\n", gcry_strerror (-1));
349       goto leave;
350     }
351   if (DBG_HASHING)
352     gcry_md_start_debug (data_md, "sign.data");
353
354   for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
355     {
356       algo = gcry_md_map_name (algoid);
357       if (!algo)
358         {
359           log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
360           rc = GNUPG_Bug;
361           goto leave;
362         }
363       gcry_md_enable (data_md, algo);
364     }
365
366   signer = 0;
367   if (detached)
368     { /* we hash the data right now so that we can store the message
369          digest.  ksba_cms_build() takes this as an flag that detached
370          data is expected. */
371       unsigned char *digest;
372       size_t digest_len;
373       /* Fixme do this for all signers and get the algo to use from
374          the signer's certificate - does not make mich sense, bu we
375          should do this consistent as we have already done it above */
376       algo = GCRY_MD_SHA1; 
377       hash_data (data_fd, data_md);
378       digest = gcry_md_read (data_md, algo);
379       digest_len = gcry_md_get_algo_dlen (algo);
380       if ( !digest || !digest_len)
381         {
382           log_error ("problem getting the hash of the data\n");
383           rc = GNUPG_Bug;
384           goto leave;
385         }
386       err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
387       if (err)
388         {
389           log_error ("ksba_cms_set_message_digest failed: %s\n",
390                      ksba_strerror (err));
391           rc = map_ksba_err (err);
392           goto leave;
393         }
394     }
395
396   signed_at = gnupg_get_time ();
397   err = ksba_cms_set_signing_time (cms, signer, signed_at);
398   if (err)
399     {
400       log_error ("ksba_cms_set_signing_time failed: %s\n",
401                  ksba_strerror (err));
402       rc = map_ksba_err (err);
403       goto leave;
404     }
405
406   do 
407     {
408       err = ksba_cms_build (cms, &stopreason);
409       if (err)
410         {
411           log_debug ("ksba_cms_build failed: %s\n", ksba_strerror (err));
412           rc = map_ksba_err (err);
413           goto leave;
414         }
415
416       if (stopreason == KSBA_SR_BEGIN_DATA)
417         { /* hash the data and store the message digest */
418           assert (!detached);
419         }
420       else if (stopreason == KSBA_SR_NEED_SIG)
421         { /* calculate the signature for all signers */
422           GCRY_MD_HD md;
423
424           algo = GCRY_MD_SHA1;
425           signer = 0;
426           md = gcry_md_open (algo, 0);
427           if (DBG_HASHING)
428             gcry_md_start_debug (md, "sign.attr");
429
430           if (!md)
431             {
432               log_error ("md_open failed: %s\n", gcry_strerror (-1));
433               goto leave;
434             }
435           ksba_cms_set_hash_function (cms, HASH_FNC, md);
436           rc = ksba_cms_hash_signed_attrs (cms, signer);
437           if (rc)
438             {
439               log_debug ("hashing signed attrs failed: %s\n",
440                          ksba_strerror (rc));
441               gcry_md_close (md);
442               goto leave;
443             }
444           
445           { /* This is all an temporary hack */
446             char *sigval;
447             
448             ksba_cert_release (cert); 
449             cert = get_default_signer ();
450             if (!cert)
451               {
452                 log_error ("oops - failed to get cert again\n");
453                 rc = seterr (General_Error);
454                 goto leave;
455               }
456
457             sigval = NULL;
458             rc = gpgsm_create_cms_signature (cert, md, algo, &sigval);
459             if (rc)
460               goto leave;
461
462             err = ksba_cms_set_sig_val (cms, signer, sigval);
463             xfree (sigval);
464             if (err)
465               {
466                 log_error ("failed to store the signature: %s\n",
467                            ksba_strerror (err));
468                 rc = map_ksba_err (err);
469                 goto leave;
470               }
471
472             /* And write a status message */
473             {
474               char *buf, *fpr;
475               
476               fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
477               if (!fpr)
478                 {
479                   rc = seterr (Out_Of_Core);
480                   goto leave;
481                 }
482               rc = asprintf (&buf, "%c %d %d 00 %lu %s",
483                         detached? 'D':'S',
484                         GCRY_PK_RSA,  /* FIXME: get pk algo from cert */
485                         algo, 
486                         (ulong)signed_at,
487                         fpr);
488               xfree (fpr);
489               if (rc < 0)
490                 {
491                   rc = seterr (Out_Of_Core);
492                   goto leave;
493                 }
494               rc = 0;
495               gpgsm_status (ctrl, STATUS_SIG_CREATED, buf );
496               free (buf); /* yes, we must use the regular free() here */
497             }
498
499           }
500         }
501     }
502   while (stopreason != KSBA_SR_READY);   
503
504   rc = gpgsm_finish_writer (b64writer);
505   if (rc) 
506     {
507       log_error ("write failed: %s\n", gnupg_strerror (rc));
508       goto leave;
509     }
510
511   log_info ("signature created\n");
512
513
514  leave:
515   ksba_cert_release (cert); 
516   ksba_cms_release (cms);
517   gpgsm_destroy_writer (b64writer);
518   keydb_release (kh); 
519   gcry_md_close (data_md);
520   return rc;
521 }