source: libabac/abac_key.c @ d0efdec

mei_rt2
Last change on this file since d0efdec was d0efdec, checked in by Mei <mei@…>, 11 years ago

1) less bsd compiler complaints

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/**
2**  abac_key.c
3**  holding a private_key
4**/
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8#include <fcntl.h>
9#include <sys/mman.h>
10
11#include <credentials/keys/private_key.h>
12#include <credentials/sets/mem_cred.h>
13
14#include "abac_defines.h"
15#include "abac_util.h"
16
17static int debug=0;
18
19// abac_key object
20// keyblob and potato are 'cleaned' explicitly
21struct _abac_key_t {
22    chunk_t keyblob;
23    char* filename;
24    chunk_t potato; // you know what, just as a hint
25};
26
27/* from abac_util */
28extern chunk_t abac_get_potato_cb(int, char*);
29
30/****************************************************************/
31//
32// Helper functions below
33//
34void print_abac_key(char *msg, abac_key_t *ptr)
35{
36    printf("===============\n");
37    if(ptr->keyblob.len !=0) {
38        printf("[%s]ptr:loc(l%d)\n",msg,(long) ptr->keyblob.ptr);
39        printf("[%s]len:(%d)\n",msg,ptr->keyblob.len);
40        printf("[%s]strlen:(%d)\n",msg,strlen(ptr->keyblob.ptr));
41        if(strlen(ptr->keyblob.ptr) != ptr->keyblob.len) 
42            printf("BAD, did not match\b\n");
43    }
44    if(ptr->filename)
45        printf("[%s]filename:(%s)\n",msg,ptr->filename);
46    if(ptr->potato.len !=0) {
47        printf("[%s]pptr:loc(%ld)\n",msg,(long)ptr->potato.ptr);
48        printf("[%s]plen:(%d)\n",msg,ptr->potato.len);
49        printf("[%s]pstrlen:(%d)\n",msg,strlen(ptr->potato.ptr));
50    }
51    printf("===============\n");
52}
53
54static private_key_t *_load_privkey_chunk(chunk_t chunk)
55{
56    DEBUG_PRINTF("_load_privkey_chunk, ptr loc(%d):(%d)\n",
57                                   (int) chunk.ptr, chunk.len);
58    private_key_t *key = lib->creds->create(lib->creds,
59        CRED_PRIVATE_KEY, KEY_RSA,
60        BUILD_BLOB_PEM, chunk,
61        BUILD_END
62    );
63    return key;
64}
65
66static private_key_t *_load_enc_privkey_chunk(chunk_t chunk, chunk_t potato)
67{
68    DEBUG_PRINTF("_load_enc_privkey_chunk, ptr loc(%d):(%d)\n",
69                                      (int) chunk.ptr, chunk.len);
70    mem_cred_t *mem;
71    shared_key_t *shared;
72
73    mem = mem_cred_create();
74    lib->credmgr->add_set(lib->credmgr, &mem->set);
75    shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, chunk_clone(potato));
76    mem->add_shared(mem, shared, NULL);
77
78    // load signer key
79    private_key_t *key =_load_privkey_chunk(chunk);
80
81    lib->credmgr->remove_set(lib->credmgr, &mem->set);
82    mem->destroy(mem);
83
84    return key;
85}
86
87private_key_t *abac_key_private_key(abac_key_t *ptr)
88{
89    private_key_t *prv=NULL;
90    if(ptr->potato.len !=0) {
91        prv=_load_enc_privkey_chunk(ptr->keyblob, ptr->potato);
92        } else  {
93            if(debug)
94                print_abac_key("abac_key_private_key",ptr);
95            prv=_load_privkey_chunk(ptr->keyblob);
96/* try to use callback to retrieve the potato token */
97            if(prv == NULL && ptr->filename) {
98               chunk_t pp=abac_get_potato_cb(2, ptr->filename);
99               if(pp.len != 0) {
100                   prv=_load_enc_privkey_chunk(ptr->keyblob, pp);
101                   ptr->potato=pp;
102               }
103            }
104    }
105
106    return prv;
107}
108
109chunk_t abac_key_load_privkey_file(char *filename)
110{
111    chunk_t blob=chunk_empty;
112    struct stat sb;
113    void *addr;
114    int fd;
115
116    if(!file_exist(filename)) 
117        return chunk_empty;
118
119    fd = open(filename, O_RDONLY);
120    if (fd == -1) {
121        printf("warning, can not open the %s\n",filename);
122        return blob;
123    }   
124
125    if (fstat(fd, &sb) == -1) {
126        printf("warning, key file(%s) is empty\n",filename);
127        close(fd);
128        return blob;
129    }
130
131    addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
132    if (addr == MAP_FAILED) {
133        printf("warning, mapping '%s' failed\n", filename);
134        close(fd);
135        return blob;
136    }
137
138    blob.ptr=strndup(addr, sb.st_size);
139    blob.len=sb.st_size;
140
141    munmap(addr, sb.st_size);
142    close(fd);
143    return blob;
144}
145
146/**
147 * Generate a private key.
148 */
149static chunk_t _generate_keyblob(void) {
150    private_key_t *key=NULL;
151    chunk_t encoding=chunk_empty;
152    libabac_init();
153
154    // generate the key
155    key = lib->creds->create(
156        lib->creds,
157        CRED_PRIVATE_KEY, KEY_RSA,
158        BUILD_KEY_SIZE, 2048,
159        BUILD_END
160    );
161    if (key == NULL)
162        errx(1, "Key generation failed");
163
164    int ret = key->get_encoding(key, PRIVKEY_PEM, &encoding);
165    if (!ret) {
166        DESTROY_IF(key);
167        errx(1, "Couldn't encode private key");
168    }
169    /* HACK.. it seems encoding ptr's string is often longer than
170       encoding len */
171    char *new_ptr=strndup(encoding.ptr,encoding.len);
172    free(encoding.ptr);
173    encoding.ptr=new_ptr;
174    DESTROY_IF(key);
175    return encoding;
176}
177
178/**
179 * Write the private key to a file.
180 * Returns false if there's no private key loaded
181 */
182int abac_key_write_privkey(abac_key_t *key, FILE *out) {
183
184    fwrite(key->keyblob.ptr, key->keyblob.len, 1, out);
185    return 1;
186}
187
188/**
189 * Get a PEM-encoded chunk representing the private key
190 */
191chunk_t abac_key_chunk(abac_key_t *ptr) {
192    return ptr->keyblob;
193}
194
195/*****************************************************************/
196/*  load with a filename                                         */
197/*  load with a filename and potato                               */
198/*  load with a chunk blob                                       */
199/*  load with a chunk blob and a potato                           */
200/*****************************************************************/
201abac_key_t *abac_key_file_new(char *filename, chunk_t potato)
202{
203    abac_key_t *ptr = abac_xmalloc(sizeof(abac_key_t));
204    if(potato.len != 0)
205        ptr->potato=potato;
206        else ptr->potato=chunk_empty;
207    ptr->keyblob=abac_key_load_privkey_file(filename);
208    ptr->filename=abac_xstrdup(filename);
209    return ptr;
210}
211
212/* just use the keyblob, did not reallocate */
213abac_key_t *abac_key_chunk_new(chunk_t keyblob, chunk_t potato)
214{
215    abac_key_t *ptr = abac_xmalloc(sizeof(abac_key_t));
216    if(potato.len != 0)
217        ptr->potato=potato;
218        else ptr->potato=chunk_empty;
219    ptr->keyblob=keyblob;
220    ptr->filename=NULL;
221    return ptr;
222}
223
224abac_key_t *abac_key_generate()
225{
226    abac_key_t *ptr = abac_xmalloc(sizeof(abac_key_t));
227    ptr->potato=chunk_empty;
228    ptr->filename=NULL;
229    ptr->keyblob=_generate_keyblob();
230    return ptr;
231}
232
233static chunk_t _copy(chunk_t ptr)
234{
235    chunk_t blob=chunk_empty;
236    blob.ptr=strndup(ptr.ptr, ptr.len);
237    blob.len=ptr.len;
238    return blob;
239}
240
241
242abac_key_t *abac_key_copy(abac_key_t *ptr)
243{
244    abac_key_t *nptr = abac_xmalloc(sizeof(abac_key_t));
245
246    if(ptr->potato.len==0)
247        nptr->potato=chunk_empty;
248        else nptr->potato=_copy(ptr->potato);
249
250    if(ptr->filename!=NULL)
251        nptr->filename=abac_xstrdup(ptr->filename);
252        else nptr->filename=NULL;
253
254    if(ptr->keyblob.len==0)
255        nptr->keyblob=chunk_empty;
256        else nptr->keyblob=_copy(ptr->keyblob);
257    return nptr;
258}
259
260void abac_key_free(abac_key_t *ptr)
261{
262    if(ptr->potato.len != 0) {
263        chunk_clear(&ptr->potato);
264    }
265    if(ptr->keyblob.len !=0) {
266        chunk_clear(&ptr->keyblob);
267    }
268    if(ptr->filename!=NULL)
269        free(ptr->filename);
270    free(ptr);
271}
Note: See TracBrowser for help on using the repository browser.