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