chiark / gitweb /
dirmngr: Drop useless housekeeping.
[gnupg2.git] / g13 / create.c
1 /* create.c - Create a new crypto container
2  * Copyright (C) 2009 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 3 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, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <assert.h>
28
29 #include "g13.h"
30 #include "i18n.h"
31 #include "create.h"
32
33 #include "keyblob.h"
34 #include "backend.h"
35 #include "g13tuple.h"
36 #include "../common/call-gpg.h"
37
38 /* Create a new blob with all the session keys and other meta
39    information which are to be stored encrypted in the crypto
40    container header.  On success the malloced blob is stored at R_BLOB
41    and its length at R_BLOBLEN.  On error an error code is returned
42    and (R_BLOB,R_BLOBLEN) are set to (NULL,0).
43
44    The format of this blob is a sequence of tag-length-value tuples.
45    All tuples have this format:
46
47      2 byte TAG           Big endian unsigned integer (0..65535)
48                           described by the KEYBLOB_TAG_ constants.
49      2 byte LENGTH        Big endian unsigned integer (0..65535)
50                           giving the length of the value.
51      length bytes VALUE   The value described by the tag.
52
53    The first tag in a keyblob must be a BLOBVERSION.  The other tags
54    depend on the type of the container as described by the CONTTYPE
55    tag.  See keyblob.h for details.  */
56 static gpg_error_t
57 create_new_keyblob (ctrl_t ctrl, int is_detached,
58                     void **r_blob, size_t *r_bloblen)
59 {
60   gpg_error_t err;
61   unsigned char twobyte[2];
62   membuf_t mb;
63
64   *r_blob = NULL;
65   *r_bloblen = 0;
66
67   init_membuf_secure (&mb, 512);
68
69   append_tuple (&mb, KEYBLOB_TAG_BLOBVERSION, "\x01", 1);
70
71   twobyte[0] = (ctrl->conttype >> 8);
72   twobyte[1] = (ctrl->conttype);
73   append_tuple (&mb, KEYBLOB_TAG_CONTTYPE, twobyte, 2);
74   if (is_detached)
75     append_tuple (&mb, KEYBLOB_TAG_DETACHED, NULL, 0);
76
77   err = be_create_new_keys (ctrl->conttype, &mb);
78   if (err)
79     goto leave;
80
81   /* Just for testing.  */
82   append_tuple (&mb, KEYBLOB_TAG_FILLER, "filler", 6);
83
84   *r_blob = get_membuf (&mb, r_bloblen);
85   if (!*r_blob)
86     {
87       err = gpg_error_from_syserror ();
88       *r_bloblen = 0;
89     }
90   else
91     log_debug ("used keyblob size is %zu\n", *r_bloblen);
92
93  leave:
94   xfree (get_membuf (&mb, NULL));
95   return err;
96 }
97
98
99
100 /* Encrypt the keyblob (KEYBLOB,KEYBLOBLEN) and store the result at
101    (R_ENCBLOB, R_ENCBLOBLEN).  Returns 0 on success or an error code.
102    On error R_EKYBLOB is set to NULL.  Depending on the keys set in
103    CTRL the result is a single OpenPGP binary message, a single
104    special OpenPGP packet encapsulating a CMS message or a
105    concatenation of both with the CMS packet being the last.  */
106 gpg_error_t
107 g13_encrypt_keyblob (ctrl_t ctrl, void *keyblob, size_t keybloblen,
108                      void **r_encblob, size_t *r_encbloblen)
109 {
110   gpg_error_t err;
111
112   /* FIXME:  For now we only implement OpenPGP.  */
113   err = gpg_encrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments,
114                           keyblob, keybloblen,
115                           ctrl->recipients,
116                           r_encblob, r_encbloblen);
117
118   return err;
119 }
120
121
122 /* Write a new file under the name FILENAME with the keyblob and an
123    appropriate header.  This function is called with a lock file in
124    place and after checking that the filename does not exists.  */
125 static gpg_error_t
126 write_keyblob (const char *filename,
127                const void *keyblob, size_t keybloblen)
128 {
129   gpg_error_t err;
130   estream_t fp;
131   unsigned char packet[32];
132   size_t headerlen, paddinglen;
133
134   fp = es_fopen (filename, "wbx");
135   if (!fp)
136     {
137       err = gpg_error_from_syserror ();
138       log_error ("error creating new container '%s': %s\n",
139                  filename, gpg_strerror (err));
140       return err;
141     }
142
143   /* Allow for an least 8 times larger keyblob to accommodate for
144      future key changes.  Round it up to 4096 byte. */
145   headerlen = ((32 + 8 * keybloblen + 16) + 4095) / 4096 * 4096;
146   paddinglen = headerlen - 32 - keybloblen;
147   assert (paddinglen >= 16);
148
149   packet[0] = (0xc0|61); /* CTB for the private packet type 0x61.  */
150   packet[1] = 0xff;      /* 5 byte length packet, value 20.  */
151   packet[2] = 0;
152   packet[3] = 0;
153   packet[4] = 0;
154   packet[5] = 26;
155   memcpy (packet+6, "GnuPG/G13", 10); /* Packet subtype.  */
156   packet[16] = 1;   /* G13 packet format version.  */
157   packet[17] = 0;   /* Reserved.  */
158   packet[18] = 0;   /* Reserved.  */
159   packet[19] = 0;   /* OS Flag.  */
160   packet[20] = (headerlen >> 24);  /* Total length of header.  */
161   packet[21] = (headerlen >> 16);
162   packet[22] = (headerlen >> 8);
163   packet[23] = (headerlen);
164   packet[24] = 1;   /* Number of header copies.  */
165   packet[25] = 0;   /* Number of header copies at the end.  */
166   packet[26] = 0;   /* Reserved.  */
167   packet[27] = 0;   /* Reserved.  */
168   packet[28] = 0;   /* Reserved.  */
169   packet[29] = 0;   /* Reserved.  */
170   packet[30] = 0;   /* Reserved.  */
171   packet[31] = 0;   /* Reserved.  */
172
173   if (es_fwrite (packet, 32, 1, fp) != 1)
174     goto writeerr;
175
176   if (es_fwrite (keyblob, keybloblen, 1, fp) != 1)
177     goto writeerr;
178
179   /* Write the padding.  */
180   packet[0] = (0xc0|61); /* CTB for Private packet type 0x61.  */
181   packet[1] = 0xff;      /* 5 byte length packet, value 20.  */
182   packet[2] = (paddinglen-6) >> 24;
183   packet[3] = (paddinglen-6) >> 16;
184   packet[4] = (paddinglen-6) >> 8;
185   packet[5] = (paddinglen-6);
186   memcpy (packet+6, "GnuPG/PAD", 10); /* Packet subtype.  */
187   if (es_fwrite (packet, 16, 1, fp) != 1)
188     goto writeerr;
189   memset (packet, 0, 32);
190   for (paddinglen-=16; paddinglen >= 32; paddinglen -= 32)
191     if (es_fwrite (packet, 32, 1, fp) != 1)
192       goto writeerr;
193   if (paddinglen)
194     if (es_fwrite (packet, paddinglen, 1, fp) != 1)
195       goto writeerr;
196
197   if (es_fclose (fp))
198     {
199       err = gpg_error_from_syserror ();
200       log_error ("error closing '%s': %s\n",
201                  filename, gpg_strerror (err));
202       remove (filename);
203       return err;
204     }
205
206   return 0;
207
208
209  writeerr:
210   err = gpg_error_from_syserror ();
211   log_error ("error writing header to '%s': %s\n",
212              filename, gpg_strerror (err));
213   es_fclose (fp);
214   remove (filename);
215   return err;
216 }
217
218
219
220 /* Create a new container under the name FILENAME and intialize it
221    using the current settings.  If the file already exists an error is
222    returned.  */
223 gpg_error_t
224 g13_create_container (ctrl_t ctrl, const char *filename)
225 {
226   gpg_error_t err;
227   dotlock_t lock;
228   void *keyblob = NULL;
229   size_t keybloblen;
230   void *enckeyblob = NULL;
231   size_t enckeybloblen;
232   char *detachedname = NULL;
233   int detachedisdir;
234   tupledesc_t tuples = NULL;
235   unsigned int dummy_rid;
236
237   if (!ctrl->recipients)
238     return gpg_error (GPG_ERR_NO_PUBKEY);
239
240   err = be_take_lock_for_create (ctrl, filename, &lock);
241   if (err)
242     goto leave;
243
244   /* And a possible detached file or directory may not exist either.  */
245   err = be_get_detached_name (ctrl->conttype, filename,
246                               &detachedname, &detachedisdir);
247   if (err)
248     goto leave;
249   if (detachedname)
250     {
251       struct stat sb;
252
253       if (!stat (detachedname, &sb))
254         {
255           err = gpg_error (GPG_ERR_EEXIST);
256           goto leave;
257         }
258     }
259
260   if (ctrl->conttype != CONTTYPE_DM_CRYPT)
261     {
262       /* Create a new keyblob.  */
263       err = create_new_keyblob (ctrl, !!detachedname, &keyblob, &keybloblen);
264       if (err)
265         goto leave;
266
267       /* Encrypt that keyblob.  */
268       err = g13_encrypt_keyblob (ctrl, keyblob, keybloblen,
269                                  &enckeyblob, &enckeybloblen);
270       if (err)
271         goto leave;
272
273       /* Put a copy of the keyblob into a tuple structure.  */
274       err = create_tupledesc (&tuples, keyblob, keybloblen);
275       if (err)
276         goto leave;
277       keyblob = NULL;
278       /* if (opt.verbose) */
279       /*   dump_keyblob (tuples); */
280
281       /* Write out the header, the encrypted keyblob and some padding. */
282       err = write_keyblob (filename, enckeyblob, enckeybloblen);
283       if (err)
284         goto leave;
285     }
286
287   /* Create and append the container.  FIXME: We should pass the
288      estream object in addition to the filename, so that the backend
289      can append the container to the g13 file.  */
290   err = be_create_container (ctrl, ctrl->conttype, filename, -1, tuples,
291                              &dummy_rid);
292
293
294  leave:
295   destroy_tupledesc (tuples);
296   xfree (detachedname);
297   xfree (enckeyblob);
298   xfree (keyblob);
299   dotlock_destroy (lock);
300
301   return err;
302 }