~ecryptfs/ecryptfs/trunk

« back to all changes in this revision

Viewing changes to src/key_mod/ecryptfs_key_mod_gpg.c

  • Committer: mhalcrow@us.ibm.com
  • Date: 2007-11-06 22:56:01 UTC
  • Revision ID: git-v1:f8357de9d554b274497b5cce9db4347254b7e7eb
Initial import of eCryptfs filesystem userspace utilities (mount helper, daemon component,
etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright (C) 2007 International Business Machines Corp.
 
3
 * Author(s): Mike Halcrow <mhalcrow@us.ibm.com>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License as
 
7
 * published by the Free Software Foundation; either version 2 of the
 
8
 * License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but
 
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
18
 * 02111-1307, USA.
 
19
 */
 
20
 
 
21
#include <fcntl.h>
 
22
#include <pwd.h>
 
23
#include <stdio.h>
 
24
#include <string.h>
 
25
#include <syslog.h>
 
26
#include <errno.h>
 
27
#include <stdlib.h>
 
28
#include <unistd.h>
 
29
#include <gpgme.h>
 
30
#include <sys/types.h>
 
31
#include <sys/stat.h>
 
32
#include "config.h"
 
33
#include "../include/ecryptfs.h"
 
34
#include "../include/decision_graph.h"
 
35
 
 
36
struct key_mod_gpg {
 
37
#define KEY_MOD_DATA_SET 0x00000001
 
38
        uint32_t flags;
 
39
        gpgme_ctx_t ctx;
 
40
        unsigned int keylist_idx;
 
41
        char *gpgsig;
 
42
        char *sig;
 
43
};
 
44
 
 
45
void destroy_key_mod_gpg(struct key_mod_gpg *key_mod_gpg)
 
46
{
 
47
        if (key_mod_gpg->sig)
 
48
                free(key_mod_gpg->sig);
 
49
        memset(key_mod_gpg, 0, sizeof(struct key_mod_gpg));
 
50
}
 
51
 
 
52
static int serialize_key_module_data(unsigned char *blob,
 
53
                                     struct key_mod_gpg *key_mod_data)
 
54
{
 
55
        int rc = 0;
 
56
 
 
57
out:
 
58
        return rc;
 
59
}
 
60
 
 
61
static int deserialize_key_module_data(struct key_mod_gpg *key_mod_data,
 
62
                                       unsigned char *blob)
 
63
{
 
64
        int rc = 0;
 
65
 
 
66
out:
 
67
        return rc;
 
68
}
 
69
 
 
70
static int
 
71
ecryptfs_gpg_initialize_key_module_state(unsigned char *blob,
 
72
                                         struct ecryptfs_name_val_pair *pair)
 
73
                            
 
74
{
 
75
        struct key_mod_gpg key_mod_gpg; 
 
76
        char *gpgsig = NULL;
 
77
        unsigned int gpgsig_len;
 
78
        int i = 0;
 
79
        int rc = 0;
 
80
 
 
81
        while (pair) {
 
82
                if (!pair->name)
 
83
                        ;
 
84
                else if (!strcmp(pair->name, "gpgsig"))
 
85
                        gpgsig = pair->value;
 
86
                pair = pair->next;
 
87
        }
 
88
        if (gpgsig) {
 
89
                gpgsig_len = strlen(gpgsig) + 1;
 
90
                blob[i++] = gpgsig_len % 256;
 
91
                blob[i++] = gpgsig_len >> 8;
 
92
                memcpy(&blob[i], gpgsig, gpgsig_len);
 
93
                i += gpgsig_len;
 
94
        } else {
 
95
                rc = -EINVAL;
 
96
                goto out;
 
97
        }
 
98
        /* TODO: Get the gpg key */
 
99
        key_mod_gpg.flags = KEY_MOD_DATA_SET;
 
100
        serialize_key_module_data(blob, &key_mod_gpg);
 
101
out:
 
102
        return rc;
 
103
}
 
104
 
 
105
static int
 
106
ecryptfs_gpg_get_key_metadata(char *sig, int *length, unsigned char *blob)
 
107
{
 
108
        struct key_mod_gpg key_mod_gpg;
 
109
        int rc = 0;
 
110
 
 
111
        sig[0] = '\0';
 
112
        (*length) = 0;
 
113
        memset(&key_mod_gpg, 0, sizeof(struct key_mod_gpg));
 
114
        if ((rc = deserialize_key_module_data(&key_mod_gpg, blob))) {
 
115
                goto out;
 
116
        }
 
117
        memcpy(sig, key_mod_gpg.sig, ECRYPTFS_SIG_SIZE_HEX + 1);
 
118
        (*length) = 0; /* TODO */
 
119
out:
 
120
        destroy_key_mod_gpg(&key_mod_gpg);
 
121
        return rc;
 
122
}
 
123
 
 
124
int ecryptfs_gpg_generate_key(char *filename)
 
125
{
 
126
        int rc = 0;
 
127
 
 
128
out:
 
129
        return rc;
 
130
}
 
131
 
 
132
int ecryptfs_gpg_encrypt(char *to, int size, char *from, unsigned char *blob)
 
133
{
 
134
        int rc;
 
135
 
 
136
/*      gpg_op_encrypt(...); */
 
137
out:
 
138
        return rc;
 
139
}
 
140
 
 
141
int ecryptfs_gpg_decrypt(char *to, size_t *decrypted_key_size, char *from, 
 
142
                         unsigned char *blob)
 
143
{
 
144
/*      gpgme_key_t key;
 
145
        int rc;
 
146
 
 
147
.       gpgme_get_key(ctx, &key);
 
148
        if (rc) {
 
149
                rc = -(int)ERR_get_error();
 
150
                syslog(LOG_ERR, "Error attempting to read RSA key from file;"
 
151
                       " rc = [%d]\n", rc);
 
152
                goto out;
 
153
        }
 
154
        gpgme_decrypt(...);
 
155
        if (rc == -1) {
 
156
                rc = -(int)ERR_get_error();
 
157
                syslog(LOG_ERR, "Error attempting to perform RSA public key "
 
158
                       "decryption; rc = [%d]\n", rc);
 
159
        } else {
 
160
                *decrypted_key_size = rc;
 
161
                rc = 0;
 
162
        }
 
163
out:
 
164
.       free? */
 
165
        return 0;
 
166
}
 
167
 
 
168
struct pki_nvp_map_elem {
 
169
        char *name;
 
170
        uint32_t flags;
 
171
};
 
172
 
 
173
static struct pki_nvp_map_elem pki_nvp_map[] = {
 
174
        {"gpgsig", (ECRYPTFS_PARAM_FLAG_ECHO_INPUT
 
175
                    | ECRYPTFS_DEFAULT_VALUE_SET)},
 
176
        {NULL, 0}
 
177
};
 
178
 
 
179
/*
 
180
 
 
181
static int ssl_sig(struct ecryptfs_pki_elem *pki, struct val_node **head)
 
182
{
 
183
        struct ecryptfs_name_val_pair *openssl_nvp;
 
184
        char *sig;
 
185
        char *param;
 
186
        int rc;
 
187
 
 
188
        sig = malloc(ECRYPTFS_SIG_SIZE_HEX + 1);
 
189
        if (!sig) {
 
190
                rc = -ENOMEM;
 
191
                goto out;
 
192
        }
 
193
        rc = ecryptfs_add_key_module_key_to_keyring(sig, pki);
 
194
        if (rc < 0)
 
195
                goto out;
 
196
        else
 
197
                rc = 0;
 
198
        asprintf(&param, "ecryptfs_sig=%s", sig);
 
199
        free(sig);
 
200
        stack_push(head, param);
 
201
out:
 
202
        if (rc)
 
203
                return MOUNT_ERROR;
 
204
        return DEFAULT_TOK;
 
205
}
 
206
 
 
207
static int tf_ssl_file(struct ecryptfs_ctx *ctx, struct param_node *node,
 
208
                       struct val_node **head, void **foo)
 
209
{
 
210
        stack_push(head, node->val);
 
211
        node->val = NULL;
 
212
        return DEFAULT_TOK;
 
213
}
 
214
 
 
215
*/
 
216
 
 
217
static int tf_gpg_keysig(struct ecryptfs_ctx *ctx, struct param_node *node,
 
218
                         struct val_node **head, void **foo);
 
219
 
 
220
/* TODO: Create a param node for each block of keysigs in the gpg
 
221
 * keyring. Make one option point to the previous node and another to
 
222
 * the next node. */
 
223
 
 
224
#define GPG_TOK 0
 
225
static struct param_node gpg_param_nodes[] = {
 
226
        {.num_mnt_opt_names = 1,
 
227
         .mnt_opt_names = {"keysig"},
 
228
         .prompt = "Key signature",
 
229
         .val_type = VAL_STR,
 
230
         .val = NULL,
 
231
         .display_opts = NULL,
 
232
         .default_val = NULL,
 
233
         .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
 
234
         .num_transitions = 1,
 
235
         .tl = {{.flags = 0,
 
236
                 .val = NULL,
 
237
                 .pretty_val = NULL,
 
238
                 .next_token = NULL,
 
239
                 .trans_func = tf_gpg_keysig}}},
 
240
};
 
241
 
 
242
/**
 
243
 * tf_gpg_keysig
 
244
 * @ctx: 
 
245
 * @node: 
 
246
 * @head: The value node list for this key module
 
247
 * @foo: 
 
248
 *
 
249
 */
 
250
static int tf_gpg_keysig(struct ecryptfs_ctx *ctx, struct param_node *node,
 
251
                         struct val_node **head, void **foo)
 
252
{
 
253
        struct key_mod_gpg *key_mod_gpg = (struct key_mod_gpg *)(*foo);
 
254
        int i;
 
255
        gpgme_error_t err;
 
256
        int rc = 0;
 
257
        gpgme_key_t key;
 
258
 
 
259
        while ((err = gpgme_op_keylist_next(key_mod_gpg->ctx, &key)) == 0) {
 
260
                gpgme_subkey_t subkey = key->subkeys;
 
261
 
 
262
                while (subkey) {
 
263
                        if ((rc = asprintf(&gpg_param_nodes[0].tl[i].val,
 
264
                                           "%s", subkey->keyid)) == -1) {
 
265
                                rc = -ENOMEM;
 
266
                                goto out;
 
267
                        }
 
268
                        subkey = subkey->next;
 
269
                }
 
270
        }
 
271
out:
 
272
        return rc;
 
273
}
 
274
 
 
275
int validate_keysig(char *keysig)
 
276
{
 
277
        int rc = 0;
 
278
 
 
279
out:
 
280
        return rc;
 
281
}
 
282
 
 
283
static int generate_name_val_list(struct ecryptfs_name_val_pair *head)
 
284
{
 
285
        struct stat buf;
 
286
        int i = 0;
 
287
        uid_t id = getuid();
 
288
        struct passwd *pw = getpwuid(id);
 
289
        int rc = 0;
 
290
 
 
291
        head->next = NULL;
 
292
out:
 
293
        return rc;
 
294
}
 
295
 
 
296
static int tf_gpg_exit(struct ecryptfs_ctx *ctx, struct param_node *node,
 
297
                       struct val_node **head, void **foo)
 
298
{
 
299
        struct key_mod_gpg *key_mod_gpg;
 
300
 
 
301
        key_mod_gpg = (struct key_mod_gpg *)(*foo);
 
302
        if (key_mod_gpg) {
 
303
                destroy_key_mod_gpg(key_mod_gpg);
 
304
                free(key_mod_gpg);
 
305
        }
 
306
}
 
307
 
 
308
 
 
309
static int tf_gpg_enter(struct ecryptfs_ctx *ctx, struct param_node *node,
 
310
                            struct val_node **head, void **foo)
 
311
{
 
312
        struct key_mod_gpg *key_mod_gpg;
 
313
        gpgme_error_t err;
 
314
        gpgme_keylist_result_t keylist_res;
 
315
        int rc = 0;
 
316
 
 
317
        (*foo) = NULL;
 
318
        if ((key_mod_gpg = malloc(sizeof(struct key_mod_gpg))) == NULL) {
 
319
                rc = -ENOMEM;
 
320
                goto out;
 
321
        }
 
322
        if ((err = gpgme_new(&key_mod_gpg->ctx))) {
 
323
                printf("Error attempting to initialize new GPGME ctx\n");
 
324
                rc = -EINVAL;
 
325
                free(key_mod_gpg);
 
326
                goto out;
 
327
        }
 
328
        if ((err = gpgme_op_keylist_start(key_mod_gpg->ctx, "", 0))) {
 
329
                printf("Error attempting to start keylist\n");
 
330
                rc = -EINVAL;
 
331
                gpgme_release(ctx);
 
332
                free(key_mod_gpg);
 
333
                goto out;
 
334
        }
 
335
        key_mod_gpg->keylist_idx = 0;
 
336
        (*foo) = (void *)key_mod_gpg;
 
337
out:
 
338
        return rc;
 
339
}
 
340
 
 
341
struct transition_node gpg_transition = {
 
342
        .val = "gpg",
 
343
        .pretty_val = "GnuPG Module",
 
344
        .next_token = &(gpg_param_nodes[0]),
 
345
        .trans_func = tf_gpg_enter
 
346
};
 
347
 
 
348
static int
 
349
ecryptfs_gpg_get_param_subgraph_trans_node(struct transition_node **trans,
 
350
                                           uint32_t version)
 
351
{
 
352
        if ((version & ECRYPTFS_VERSIONING_PUBKEY) == 0)
 
353
                return -1;
 
354
        *trans = &gpg_transition;
 
355
        return 0;
 
356
}
 
357
 
 
358
int destruct_pki(void)
 
359
{
 
360
        return 0;
 
361
}
 
362
 
 
363
int fill_in_sig_transitions(void)
 
364
{
 
365
        int rc = 0;
 
366
 
 
367
/*      gpg_param_nodes[0].tl */
 
368
out:
 
369
        return rc;
 
370
}
 
371
 
 
372
static int ecryptfs_gpg_init(char **alias)
 
373
{
 
374
        uid_t id;
 
375
        struct passwd *pw;
 
376
        int rc = 0;
 
377
 
 
378
        if (asprintf(alias, "gpgme") == -1) {
 
379
                rc = -ENOMEM;
 
380
                syslog(LOG_ERR, "Out of memory\n");
 
381
                goto out;
 
382
        }
 
383
        id = getuid();
 
384
        pw = getpwuid(id);
 
385
        rc = -EINVAL; /* Disable for now */
 
386
out:
 
387
        return rc;
 
388
}
 
389
 
 
390
int ecryptfs_gpg_finalize(void)
 
391
{
 
392
        return 0;
 
393
}
 
394
 
 
395
static struct ecryptfs_key_mod_ops ecryptfs_gpg_ops = {
 
396
        &ecryptfs_gpg_init,
 
397
        NULL,
 
398
        NULL,
 
399
        NULL,
 
400
        NULL,
 
401
        NULL,
 
402
        NULL,
 
403
        NULL,
 
404
        NULL,
 
405
        NULL,
 
406
        NULL,
 
407
        NULL,
 
408
        &ecryptfs_gpg_finalize
 
409
};
 
410
 
 
411
struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
 
412
{
 
413
        return &ecryptfs_gpg_ops;
 
414
}