~ubuntu-branches/ubuntu/vivid/ecryptfs-utils/vivid

« back to all changes in this revision

Viewing changes to src/libecryptfs/netlink_packets.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-04-09 09:54:00 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080409095400-cexrc09wzgqsk9bs
Tags: 43-1
* New upstream release.
* Removing watch file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * Userspace side of netlink communications with eCryptfs kernel
3
 
 * module.
4
 
 *
5
 
 * Copyright (C) 2004-2006 International Business Machines Corp.
6
 
 *   Author(s): Trevor S. Highland <trevor.highland@gmail.com>
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU General Public License as
10
 
 * published by the Free Software Foundation; either version 2 of the
11
 
 * License, or (at your option) any later version.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful, but
14
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program; if not, write to the Free Software
20
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
 
 * 02111-1307, USA.
22
 
 */
23
 
 
24
 
#include <errno.h>
25
 
#ifndef S_SPLINT_S
26
 
#include <syslog.h>
27
 
#include <stdio.h>
28
 
#endif
29
 
#include <string.h>
30
 
#include <gcrypt.h>
31
 
#include <keyutils.h>
32
 
#include <stdlib.h>
33
 
#include "config.h"
34
 
#include "../include/ecryptfs.h"
35
 
 
36
 
#define ECRYPTFS_PACKET_STATUS_GOOD 0
37
 
#define ECRYPTFS_PACKET_STATUS_BAD -1
38
 
 
39
 
/**
40
 
 * write_packet_length
41
 
 * @dest: The byte array target into which to write the
42
 
 *       length. Must have at least 5 bytes allocated.
43
 
 * @size: The length to write.
44
 
 * @packet_size_length: The number of bytes used to encode the
45
 
 *                      packet length is written to this address.
46
 
 *
47
 
 * Returns zero on success; non-zero on error.
48
 
 */
49
 
static int
50
 
write_packet_length(char *dest, size_t size, size_t *packet_size_length)
51
 
{
52
 
        int rc = 0;
53
 
 
54
 
        if (size < 192) {
55
 
                dest[0] = size;
56
 
                (*packet_size_length) = 1;
57
 
        } else if (size < 65536) {
58
 
                dest[0] = (((size - 192) / 256) + 192);
59
 
                dest[1] = ((size - 192) % 256);
60
 
                (*packet_size_length) = 2;
61
 
        } else {
62
 
                rc = -EINVAL;
63
 
                syslog(LOG_ERR, "Unsupported packet size: [%d]\n",
64
 
                       size);
65
 
        }
66
 
        return rc;
67
 
}
68
 
 
69
 
/**
70
 
 * parse_packet_length
71
 
 * @data: Pointer to memory containing length at offset
72
 
 * @size: This function writes the decoded size to this memory
73
 
 *        address; zero on error
74
 
 * @length_size: The number of bytes occupied by the encoded length
75
 
 *
76
 
 * Returns Zero on success
77
 
 */
78
 
static int parse_packet_length(unsigned char *data, size_t *size,
79
 
                               size_t *length_size)
80
 
{
81
 
        int rc = 0;
82
 
 
83
 
        (*length_size) = 0;
84
 
        (*size) = 0;
85
 
        if (data[0] < 192) {
86
 
                /* One-byte length */
87
 
                (*size) = data[0];
88
 
                (*length_size) = 1;
89
 
        } else if (data[0] < 224) {
90
 
                /* Two-byte length */
91
 
                (*size) = ((data[0] - 192) * 256);
92
 
                (*size) += (data[1] + 192);
93
 
                (*length_size) = 2;
94
 
        } else if (data[0] == 255) {
95
 
                /* Five-byte length; we're not supposed to see this */
96
 
                rc = -EINVAL;
97
 
                syslog(LOG_ERR, "Five-byte packet length not "
98
 
                       "supported\n");
99
 
                goto out;
100
 
        } else {
101
 
                rc = -EINVAL;
102
 
                syslog(LOG_ERR, "Error parsing packet length\n");
103
 
                goto out;
104
 
        }
105
 
out:
106
 
        return rc;
107
 
}
108
 
 
109
 
/**
110
 
 * key_mod_encrypt
111
 
 * @encrypted_key: This function will allocate this memory and encrypt
112
 
 *                 the key into it
113
 
 * @encrypted_key_size: The size of the encrypted key; note that the
114
 
 *                      actual amount of memory allocated by this
115
 
 *                      function may be more than this
116
 
 * @ctx:
117
 
 * @auth_tok: The authentication token structure in the user session
118
 
 *            keyring; this contains the key module state blob
119
 
 * @decrypted_key:
120
 
 * @decrypted_key_size:
121
 
 *
122
 
 *
123
 
 *
124
 
 * Called from parse_packet()
125
 
 */
126
 
static int
127
 
key_mod_encrypt(char **encrypted_key, size_t *encrypted_key_size,
128
 
                struct ecryptfs_ctx *ctx, struct ecryptfs_auth_tok *auth_tok,
129
 
                char *decrypted_key, size_t decrypted_key_size)
130
 
{
131
 
        struct ecryptfs_key_mod *key_mod;
132
 
        int rc;
133
 
 
134
 
        if (ecryptfs_find_key_mod(&key_mod, ctx,
135
 
                                  auth_tok->token.private_key.key_mod_alias)) {
136
 
                rc = -EINVAL;
137
 
                syslog(LOG_ERR, "Failed to locate desired key module\n");
138
 
                goto out;
139
 
        }
140
 
        /* TODO: Include support for a hint rather than just a blob */
141
 
        if ((rc = key_mod->ops->encrypt(NULL, encrypted_key_size, decrypted_key,
142
 
                                        decrypted_key_size,
143
 
                                        auth_tok->token.private_key.data,
144
 
                                        ECRYPTFS_BLOB_TYPE_BLOB))) {
145
 
                syslog(LOG_ERR, "Error attempting to get encrypted key size "
146
 
                       "from key module; rc = [%d]\n", rc);
147
 
                goto out;
148
 
        }
149
 
        if ((*encrypted_key_size) == 0) {
150
 
                rc = -EINVAL;
151
 
                syslog(LOG_ERR, "Encrypted key size reported by key module "
152
 
                       "encrypt function is 0\n");
153
 
                goto out;
154
 
        }
155
 
        /* The first call just told us how much memory to
156
 
         * allocate. The actual key size may be less, so we don't
157
 
         * worry about ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES until the
158
 
         * second call. */
159
 
        if (((*encrypted_key) = malloc(*encrypted_key_size)) == NULL) {
160
 
                rc = -errno;
161
 
                syslog(LOG_ERR, "Failed to allocate memory: [%s]\n",
162
 
                       strerror(errno));
163
 
                goto out;
164
 
        }
165
 
        if ((rc = key_mod->ops->encrypt((*encrypted_key), encrypted_key_size,
166
 
                                        decrypted_key, decrypted_key_size,
167
 
                                        auth_tok->token.private_key.data,
168
 
                                        ECRYPTFS_BLOB_TYPE_BLOB))) {
169
 
                syslog(LOG_ERR, "Failed to encrypt key; rc = [%d]\n", rc);
170
 
                goto out;
171
 
        }
172
 
        if ((*encrypted_key_size) > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
173
 
                rc = -EINVAL;
174
 
                syslog(LOG_ERR, "Encrypted key size reported by key module "
175
 
                       "encrypt function is [%d]; max is [%d]\n",
176
 
                       (*encrypted_key_size), ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES);
177
 
                free(*encrypted_key);
178
 
                (*encrypted_key_size) = 0;
179
 
                goto out;
180
 
        }
181
 
out:
182
 
        return rc;
183
 
}
184
 
 
185
 
static int
186
 
key_mod_decrypt(char **decrypted_key, size_t *decrypted_key_size,
187
 
                struct ecryptfs_ctx *ctx, struct ecryptfs_auth_tok *auth_tok,
188
 
                char *encrypted_key, size_t encrypted_key_size)
189
 
{
190
 
        struct ecryptfs_key_mod *key_mod;
191
 
        int rc;
192
 
 
193
 
        if (ecryptfs_find_key_mod(&key_mod, ctx,
194
 
                                  auth_tok->token.private_key.key_mod_alias)) {
195
 
                rc = -EINVAL;
196
 
                syslog(LOG_ERR, "Failed to locate desired key module\n");
197
 
                goto out;
198
 
        }
199
 
        if ((rc = key_mod->ops->decrypt(NULL, decrypted_key_size,
200
 
                                        encrypted_key, encrypted_key_size,
201
 
                                        auth_tok->token.private_key.data,
202
 
                                        ECRYPTFS_BLOB_TYPE_BLOB))) {
203
 
                syslog(LOG_ERR, "Failed to get size for decrypted key\n");
204
 
                goto out;
205
 
        }
206
 
        if ((*decrypted_key_size) == 0) {
207
 
                rc = -EINVAL;
208
 
                syslog(LOG_ERR, "Decrypted key size reported by key module "
209
 
                       "decrypt function is 0\n");
210
 
                goto out;
211
 
        }
212
 
        /* The first call just told us how much memory to
213
 
         * allocate. The actual key size may be less, so we don't
214
 
         * worry about ECRYPTFS_MAX_KEY_BYTES until the second
215
 
         * call. */
216
 
        if (((*decrypted_key) = malloc(*decrypted_key_size)) == NULL) {
217
 
                rc = -ENOMEM;
218
 
                syslog(LOG_ERR, "Failed to allocate memory\n");
219
 
                goto out;
220
 
        }
221
 
        if ((rc = key_mod->ops->decrypt(*decrypted_key, decrypted_key_size,
222
 
                                        encrypted_key, encrypted_key_size,
223
 
                                        auth_tok->token.private_key.data,
224
 
                                        ECRYPTFS_BLOB_TYPE_BLOB))) {
225
 
                syslog(LOG_ERR, "Failed to decrypt key\n");
226
 
                goto out;
227
 
        }
228
 
        if ((*decrypted_key_size) > ECRYPTFS_MAX_KEY_BYTES) {
229
 
                rc = -EINVAL;
230
 
                syslog(LOG_ERR, "Decrypted key size reported by key module "
231
 
                       "decrypt function is [%d]; max is [%d]\n",
232
 
                       (*decrypted_key_size), ECRYPTFS_MAX_KEY_BYTES);
233
 
                free(*decrypted_key);
234
 
                (*decrypted_key_size) = 0;
235
 
                goto out;
236
 
        }
237
 
out:
238
 
        return rc;
239
 
}
240
 
 
241
 
static int write_failure_packet(size_t tag,
242
 
                                struct ecryptfs_netlink_message **reply)
243
 
{
244
 
        unsigned char *data;
245
 
        size_t i = 0;
246
 
        int rc = 0;
247
 
 
248
 
        *reply = malloc(sizeof(struct ecryptfs_netlink_message) + 2);
249
 
        if (!*reply) {
250
 
                rc = -errno;
251
 
                syslog(LOG_ERR, "Failed to allocate memory: %s\n",
252
 
                       strerror(errno));
253
 
                goto out;
254
 
        }
255
 
        data = (*reply)->data;
256
 
        data[i++] = tag;
257
 
        data[i++] = ECRYPTFS_PACKET_STATUS_BAD;
258
 
        (*reply)->data_len = i;
259
 
out:
260
 
        return rc;
261
 
}
262
 
 
263
 
static int write_tag_65_packet(unsigned char *key, size_t key_size,
264
 
                               struct ecryptfs_netlink_message **reply)
265
 
{
266
 
        unsigned char *data;
267
 
        size_t data_len;
268
 
        size_t length_size;
269
 
        size_t i = 0;
270
 
        int rc = 0;
271
 
 
272
 
        data_len = key_size + 4;
273
 
        *reply = malloc(sizeof(struct ecryptfs_netlink_message) + data_len);
274
 
        if (!*reply) {
275
 
                rc = -errno;
276
 
                syslog(LOG_ERR, "Failed to allocate memory: %s\n",
277
 
                       strerror(errno));
278
 
                goto out;
279
 
        }
280
 
        data = (*reply)->data;
281
 
        data[i++] = ECRYPTFS_TAG_65_PACKET;
282
 
        data[i++] = ECRYPTFS_PACKET_STATUS_GOOD;
283
 
        rc = write_packet_length(&data[i], key_size, &length_size);
284
 
        if (rc) {
285
 
                syslog(LOG_ERR, "Invalid packet format\n");
286
 
                goto out;
287
 
        }
288
 
        i += length_size;
289
 
        memcpy(&data[i], key, key_size);
290
 
        i += key_size;
291
 
        (*reply)->data_len = i;
292
 
out:
293
 
        return rc;
294
 
}
295
 
 
296
 
static int
297
 
write_tag_67_packet(char *key, size_t key_size,
298
 
                    struct ecryptfs_netlink_message **reply)
299
 
{
300
 
        unsigned char *data;
301
 
        size_t data_len;
302
 
        size_t length_size;
303
 
        size_t i = 0;
304
 
        int rc = 0;
305
 
 
306
 
        data_len = key_size + 4;
307
 
        *reply = malloc(sizeof(struct ecryptfs_netlink_message) + data_len);
308
 
        if (!*reply) {
309
 
                rc = -errno;
310
 
                syslog(LOG_ERR, "Failed to allocate memory: %s\n",
311
 
                       strerror(errno));
312
 
                goto out;
313
 
        }
314
 
        data = (*reply)->data;
315
 
        data[i++] = ECRYPTFS_TAG_67_PACKET;
316
 
        data[i++] = ECRYPTFS_PACKET_STATUS_GOOD;
317
 
        rc = write_packet_length(&data[i], key_size, &length_size);
318
 
        if (rc) {
319
 
                syslog(LOG_ERR, "Invalid packet format\n");
320
 
                goto out;
321
 
        }
322
 
        i += length_size;
323
 
        memcpy(&data[i], key, key_size);
324
 
        i += key_size;
325
 
        (*reply)->data_len = data_len;
326
 
out:
327
 
        return rc;
328
 
}
329
 
 
330
 
int parse_packet(struct ecryptfs_ctx *ctx,
331
 
                 struct ecryptfs_netlink_message *emsg,
332
 
                 struct ecryptfs_netlink_message **reply)
333
 
{
334
 
        struct ecryptfs_auth_tok *auth_tok = NULL;
335
 
        size_t i = 0;
336
 
        size_t data_size;
337
 
        size_t key_size;
338
 
        size_t length_size;
339
 
        size_t key_out_size;
340
 
        unsigned char *signature;
341
 
        unsigned char packet_type;
342
 
        char *key = NULL;
343
 
        char *key_out = NULL;
344
 
        key_serial_t key_sub;
345
 
        int rc;
346
 
 
347
 
        packet_type = emsg->data[i++];
348
 
        if ((rc = parse_packet_length(&emsg->data[i], &data_size,
349
 
                                      &length_size))) {
350
 
                syslog(LOG_ERR, "Invalid packet format\n");
351
 
                goto write_failure;
352
 
        }
353
 
        i += length_size;
354
 
        signature = malloc(data_size + 1);
355
 
        if (!signature) {
356
 
                rc = -errno;
357
 
                syslog(LOG_ERR, "Failed to allocate memory: %s\n",
358
 
                       strerror(errno));
359
 
                goto write_failure;
360
 
        }
361
 
        memcpy(signature, &emsg->data[i], data_size);
362
 
        signature[data_size] = '\0';
363
 
        i += data_size;
364
 
        rc = parse_packet_length(&emsg->data[i], &key_size, &length_size);
365
 
        if (rc) {
366
 
                syslog(LOG_ERR, "Invalid packet format\n");
367
 
                goto write_failure;
368
 
        }
369
 
        i += length_size;
370
 
        if ((key = malloc(key_size)) == NULL) {
371
 
                rc = -ENOMEM;
372
 
                syslog(LOG_ERR, "Failed to allocate memory\n");
373
 
                goto write_failure;
374
 
        }
375
 
        memcpy(key, &emsg->data[i], key_size);
376
 
        i += key_size;
377
 
        key_sub = request_key("user", signature, NULL, KEY_SPEC_USER_KEYRING);
378
 
        if (key_sub < 0) {
379
 
                syslog(LOG_ERR, "Could not find key with signature: "
380
 
                       "[%s]\n", signature);
381
 
                rc = -EINVAL;
382
 
                goto write_failure;
383
 
        }
384
 
        rc = keyctl_read_alloc(key_sub, (void **)(&auth_tok));
385
 
        switch (packet_type) {
386
 
        case ECRYPTFS_TAG_64_PACKET:
387
 
                if ((rc = key_mod_decrypt(&key_out, &key_out_size, ctx,
388
 
                                          auth_tok, key, key_size))) {
389
 
                        syslog(LOG_ERR, "Failed to decrypt key; rc = [%d]\n",
390
 
                               rc);
391
 
                        rc = write_failure_packet(ECRYPTFS_TAG_65_PACKET,reply);
392
 
                        goto write_failure;
393
 
                }
394
 
                if ((rc = write_tag_65_packet(key_out, key_out_size, reply))) {
395
 
                        syslog(LOG_ERR, "Failed to write decrypted "
396
 
                               "key via tag 65 packet\n");
397
 
                        goto write_failure;
398
 
                }
399
 
                break;
400
 
        case ECRYPTFS_TAG_66_PACKET:
401
 
                rc = key_mod_encrypt(&key_out, &key_out_size, ctx, auth_tok,
402
 
                                     key, key_size);
403
 
                if (rc) {
404
 
                        syslog(LOG_ERR, "Failed to encrypt public "
405
 
                               "key\n");
406
 
                        goto write_failure;
407
 
                }
408
 
                rc = write_tag_67_packet(key_out, key_out_size, reply);
409
 
                if (rc) {
410
 
                        syslog(LOG_ERR, "Failed to write encrypted "
411
 
                               "key to tag 67 packet\n");
412
 
                        goto write_failure;
413
 
                }
414
 
                break;
415
 
        default:
416
 
                syslog(LOG_ERR, "Unrecognized packet type: [%d]\n",
417
 
                       packet_type);
418
 
                rc = -EINVAL;
419
 
                break;
420
 
        }
421
 
        free(key);
422
 
        free(signature);
423
 
        free(key_out);
424
 
        memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok)
425
 
                             + auth_tok->token.private_key.data_len));
426
 
        free(auth_tok);
427
 
        return rc;
428
 
write_failure:
429
 
        if(packet_type == ECRYPTFS_TAG_66_PACKET)
430
 
                rc = write_failure_packet(ECRYPTFS_TAG_67_PACKET, reply);
431
 
        else
432
 
                rc = write_failure_packet(ECRYPTFS_TAG_65_PACKET, reply);
433
 
        free(key);
434
 
        free(signature);
435
 
        free(key_out);
436
 
        if (auth_tok) {
437
 
                memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok)
438
 
                                     + auth_tok->token.private_key.data_len));
439
 
                free(auth_tok);
440
 
        }
441
 
        return rc;
442
 
}