2
* Copyright (C) 2007 International Business Machines Corp.
3
* Author(s): Mike Halcrow <mhalcrow@us.ibm.com>
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.
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.
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
30
#include <sys/types.h>
33
#include "../include/ecryptfs.h"
34
#include "../include/decision_graph.h"
37
#define KEY_MOD_DATA_SET 0x00000001
40
unsigned int keylist_idx;
45
void destroy_key_mod_gpg(struct key_mod_gpg *key_mod_gpg)
48
free(key_mod_gpg->sig);
49
memset(key_mod_gpg, 0, sizeof(struct key_mod_gpg));
52
static int serialize_key_module_data(unsigned char *blob,
53
struct key_mod_gpg *key_mod_data)
61
static int deserialize_key_module_data(struct key_mod_gpg *key_mod_data,
71
ecryptfs_gpg_initialize_key_module_state(unsigned char *blob,
72
struct ecryptfs_name_val_pair *pair)
75
struct key_mod_gpg key_mod_gpg;
77
unsigned int gpgsig_len;
84
else if (!strcmp(pair->name, "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);
98
/* TODO: Get the gpg key */
99
key_mod_gpg.flags = KEY_MOD_DATA_SET;
100
serialize_key_module_data(blob, &key_mod_gpg);
106
ecryptfs_gpg_get_key_metadata(char *sig, int *length, unsigned char *blob)
108
struct key_mod_gpg key_mod_gpg;
113
memset(&key_mod_gpg, 0, sizeof(struct key_mod_gpg));
114
if ((rc = deserialize_key_module_data(&key_mod_gpg, blob))) {
117
memcpy(sig, key_mod_gpg.sig, ECRYPTFS_SIG_SIZE_HEX + 1);
118
(*length) = 0; /* TODO */
120
destroy_key_mod_gpg(&key_mod_gpg);
124
int ecryptfs_gpg_generate_key(char *filename)
132
int ecryptfs_gpg_encrypt(char *to, int size, char *from, unsigned char *blob)
136
/* gpg_op_encrypt(...); */
141
int ecryptfs_gpg_decrypt(char *to, size_t *decrypted_key_size, char *from,
147
. gpgme_get_key(ctx, &key);
149
rc = -(int)ERR_get_error();
150
syslog(LOG_ERR, "Error attempting to read RSA key from file;"
156
rc = -(int)ERR_get_error();
157
syslog(LOG_ERR, "Error attempting to perform RSA public key "
158
"decryption; rc = [%d]\n", rc);
160
*decrypted_key_size = rc;
168
struct pki_nvp_map_elem {
173
static struct pki_nvp_map_elem pki_nvp_map[] = {
174
{"gpgsig", (ECRYPTFS_PARAM_FLAG_ECHO_INPUT
175
| ECRYPTFS_DEFAULT_VALUE_SET)},
181
static int ssl_sig(struct ecryptfs_pki_elem *pki, struct val_node **head)
183
struct ecryptfs_name_val_pair *openssl_nvp;
188
sig = malloc(ECRYPTFS_SIG_SIZE_HEX + 1);
193
rc = ecryptfs_add_key_module_key_to_keyring(sig, pki);
198
asprintf(¶m, "ecryptfs_sig=%s", sig);
200
stack_push(head, param);
207
static int tf_ssl_file(struct ecryptfs_ctx *ctx, struct param_node *node,
208
struct val_node **head, void **foo)
210
stack_push(head, node->val);
217
static int tf_gpg_keysig(struct ecryptfs_ctx *ctx, struct param_node *node,
218
struct val_node **head, void **foo);
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
225
static struct param_node gpg_param_nodes[] = {
226
{.num_mnt_opt_names = 1,
227
.mnt_opt_names = {"keysig"},
228
.prompt = "Key signature",
231
.display_opts = NULL,
233
.flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
234
.num_transitions = 1,
239
.trans_func = tf_gpg_keysig}}},
246
* @head: The value node list for this key module
250
static int tf_gpg_keysig(struct ecryptfs_ctx *ctx, struct param_node *node,
251
struct val_node **head, void **foo)
253
struct key_mod_gpg *key_mod_gpg = (struct key_mod_gpg *)(*foo);
259
while ((err = gpgme_op_keylist_next(key_mod_gpg->ctx, &key)) == 0) {
260
gpgme_subkey_t subkey = key->subkeys;
263
if ((rc = asprintf(&gpg_param_nodes[0].tl[i].val,
264
"%s", subkey->keyid)) == -1) {
268
subkey = subkey->next;
275
int validate_keysig(char *keysig)
283
static int generate_name_val_list(struct ecryptfs_name_val_pair *head)
288
struct passwd *pw = getpwuid(id);
296
static int tf_gpg_exit(struct ecryptfs_ctx *ctx, struct param_node *node,
297
struct val_node **head, void **foo)
299
struct key_mod_gpg *key_mod_gpg;
301
key_mod_gpg = (struct key_mod_gpg *)(*foo);
303
destroy_key_mod_gpg(key_mod_gpg);
309
static int tf_gpg_enter(struct ecryptfs_ctx *ctx, struct param_node *node,
310
struct val_node **head, void **foo)
312
struct key_mod_gpg *key_mod_gpg;
314
gpgme_keylist_result_t keylist_res;
318
if ((key_mod_gpg = malloc(sizeof(struct key_mod_gpg))) == NULL) {
322
if ((err = gpgme_new(&key_mod_gpg->ctx))) {
323
printf("Error attempting to initialize new GPGME ctx\n");
328
if ((err = gpgme_op_keylist_start(key_mod_gpg->ctx, "", 0))) {
329
printf("Error attempting to start keylist\n");
335
key_mod_gpg->keylist_idx = 0;
336
(*foo) = (void *)key_mod_gpg;
341
struct transition_node gpg_transition = {
343
.pretty_val = "GnuPG Module",
344
.next_token = &(gpg_param_nodes[0]),
345
.trans_func = tf_gpg_enter
349
ecryptfs_gpg_get_param_subgraph_trans_node(struct transition_node **trans,
352
if ((version & ECRYPTFS_VERSIONING_PUBKEY) == 0)
354
*trans = &gpg_transition;
358
int destruct_pki(void)
363
int fill_in_sig_transitions(void)
367
/* gpg_param_nodes[0].tl */
372
static int ecryptfs_gpg_init(char **alias)
378
if (asprintf(alias, "gpgme") == -1) {
380
syslog(LOG_ERR, "Out of memory\n");
385
rc = -EINVAL; /* Disable for now */
390
int ecryptfs_gpg_finalize(void)
395
static struct ecryptfs_key_mod_ops ecryptfs_gpg_ops = {
408
&ecryptfs_gpg_finalize
411
struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
413
return &ecryptfs_gpg_ops;