source: creddy/creddy.c @ 2a20fa0

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 2a20fa0 was 9d767d1, checked in by Mike Ryan <mikeryan@…>, 14 years ago

init libstrongswan inside the library

  • Property mode set to 100644
File size: 8.3 KB
Line 
1#include <assert.h>
2#include <getopt.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "creddy_common.h"
8
9#define OPT_CN              1
10#define OPT_VALIDITY        2
11#define OPT_CERT            3
12#define OPT_ISSUER          4
13#define OPT_KEY             5
14#define OPT_ROLE            6
15#define OPT_SUBJECT_CERT    7
16#define OPT_SUBJECT_ROLE    8
17#define OPT_OUT             9 // the world oughta be opt-in only :(
18#define OPT_ATTRCERT        10
19#define OPT_SUBJECT_ID      11
20
21subject_t *subjects = NULL;
22int num_subjects = 0;
23int subjects_size = 0;
24
25char **roles = NULL;
26int num_roles = 0;
27int roles_size = 0;
28
29void subject(char *subject, int cert) {
30    if (num_subjects == subjects_size) {
31        subjects_size *= 2;
32        subjects = xrealloc(subjects, sizeof(subject_t) * subjects_size);
33    }
34
35    int i = num_subjects++;
36    subjects[i].id = NULL;
37    subjects[i].cert = NULL;
38    subjects[i].role = NULL;
39
40    if (cert)
41        subjects[i].cert = subject;
42    else
43        subjects[i].id = subject;
44}
45
46void role(char *role) {
47    if (num_roles == roles_size) {
48        roles_size *= 2;
49        roles = xrealloc(roles, sizeof(char *) * roles_size);
50    }
51
52    int i = num_roles++;
53    roles[i] = role;
54}
55
56int main(int argc, char **argv) {
57    int ret;
58    options_t options = { 0, };
59
60    subjects = xmalloc(sizeof(subject_t) * 2);
61    subjects_size = 2;
62
63    roles = xmalloc(sizeof(char *) * 2);
64    roles_size = 2;
65
66    struct option getopts[] = {
67        { "help",       0, &options.help, 1 },
68        { "generate",   0, &options.mode, MODE_GENERATE },
69        { "verify",     0, &options.mode, MODE_VERIFY },
70        { "keyid",      0, &options.mode, MODE_KEYID },
71        { "attribute",  0, &options.mode, MODE_ATTRIBUTE },
72        { "roles",      0, &options.mode, MODE_ROLES },
73        { "version",    0, &options.mode, MODE_VERSION },
74
75        { "cert",       1, 0, OPT_CERT },
76
77        // generate options
78        { "cn",         1, 0, OPT_CN },
79        { "validity",   1, 0, OPT_VALIDITY },
80
81        // attribute options
82        { "issuer",     1, 0, OPT_ISSUER },
83        { "key",        1, 0, OPT_KEY },
84        { "role",       1, 0, OPT_ROLE },
85        { "subject-cert", 1, 0, OPT_SUBJECT_CERT },
86        { "subject-id", 1, 0, OPT_SUBJECT_ID },
87        { "subject-role", 1, 0, OPT_SUBJECT_ROLE },
88        { "out",          1, 0, OPT_OUT },
89
90        // verify option
91        { "attrcert",   1, 0, OPT_ATTRCERT },
92
93        { NULL },
94    };
95
96    for ( ; ; ) {
97        int c = getopt_long(argc, argv, "", getopts, NULL);
98        if (c < 0)
99            break;
100
101        switch (c) {
102            // set the option from the value in the getopts struct
103            case 0:
104                continue;
105
106            case OPT_CERT:
107                options.cert = xstrdup(optarg);
108                break;
109
110            // generate options
111            case OPT_CN:
112                options.cn = xstrdup(optarg);
113                break;
114            case OPT_VALIDITY: // also an attribute option
115                options.validity = atoi(optarg);
116                break;
117
118            // attribute options
119            case OPT_ISSUER:
120                options.issuer = xstrdup(optarg);
121                break;
122            case OPT_KEY:
123                options.key = xstrdup(optarg);
124                break;
125            case OPT_ROLE:
126                options.role = xstrdup(optarg);
127                break;
128            case OPT_SUBJECT_CERT:
129                subject(xstrdup(optarg), 1);
130                break;
131            case OPT_SUBJECT_ID:
132                subject(xstrdup(optarg), 0);
133                break;
134            case OPT_SUBJECT_ROLE:
135                role(xstrdup(optarg));
136                break;
137            case OPT_OUT:
138                options.out = xstrdup(optarg);
139                break;
140
141            // verify options
142            case OPT_ATTRCERT:
143                options.attrcert = xstrdup(optarg);
144                break;
145
146            case '?':
147                break;
148
149            default:
150                printf("wat\n");
151                return 45;
152        }
153    }
154
155    if (options.help || optind < argc) {
156        if (optind > 0 && optind < argc)
157            printf("I don't understand %s\n", argv[optind]);
158        usage(&options);
159    }
160
161    if (options.mode == MODE_ATTRIBUTE) {
162        int i;
163
164        // have to do error checking on subjects here
165        if (
166                (num_subjects == 0) ||
167                (num_subjects != num_roles && num_subjects != 1 && num_roles != 0)
168           ) {
169            printf(
170                "You have %d subject%s and %d role%s, which is invalid\n",
171                num_subjects, num_subjects == 1 ? "" : "s",
172                num_roles, num_roles == 1 ? "" : "s"
173            );
174            usage(&options);
175        }
176
177        for (i = 0; i < num_roles; ++i)
178            subjects[i].role = roles[i];
179        free(roles);
180
181        options.subjects = subjects;
182        options.num_subjects = num_subjects;
183    }
184
185    // launch the sub command
186    switch (options.mode) {
187        case MODE_GENERATE:
188            if (options.validity == 0) options.validity = 1080;
189            generate_main(&options);
190            break;
191
192        case MODE_KEYID:
193            keyid_main(&options);
194            break;
195
196        case MODE_ATTRIBUTE:
197            if (options.validity == 0) options.validity = 365;
198            attribute_main(&options);
199            break;
200
201        case MODE_ROLES:
202            roles_main(&options);
203            break;
204
205        case MODE_VERIFY:
206            verify_main(&options);
207            break;
208
209        case MODE_VERSION:
210            printf("ABAC/creddy " ABAC_VERSION "\n");
211            break;
212
213        default:
214            usage(&options);
215    }
216
217    return 0;
218}
219
220void usage(options_t *opts) {
221    if (opts->mode == MODE_GENERATE)
222        printf(
223            "Usage: creddy --generate --cn <name> [ --validity <days> ]\n"
224            "    cert will be in ${name}_ID.der, private key in ${name}_private.pem\n"
225            "    default validity: 1080 days\n"
226        );
227
228    else if (opts->mode == MODE_VERIFY)
229        printf(
230            "Usage: identity --verify --cert <cert> [ --attrcert <cert> ]\n"
231            "    if attrcert is provided, verify that it was issued by cert\n"
232        );
233
234    else if (opts->mode == MODE_KEYID)
235        printf(
236            "Usage: identity --keyid --cert <cert>\n"
237        );
238
239    else if (opts->mode == MODE_ATTRIBUTE)
240        printf(
241            "Usage: identity --attribute \\\n"
242            "                --issuer <cert> --key <key> --role <role> \\\n"
243            "                [ --subject-cert <cert> | --subject-id <sha1> \\\n"
244            "                    [ --subject-role <role> ]  ... ] \\\n"
245            "                [ --validity <days> ] --out <file>\n"
246            "    default validity: 365 days\n"
247            "    provide exactly one of --subject-cert / --subject-id\n"
248            "    give multiple --subject-{cert,id} / --subject-role pairs for intersection\n"
249        );
250
251    else if (opts->mode == MODE_ROLES)
252        printf(
253            "Usage: identity --roles --cert <cert>\n"
254        );
255
256    else
257        printf(
258            "Usage: creddy [ --<mode> ] [ --help ]\n"
259            "    --generate:  generate X.509 identity cert and private key\n"
260            "    --verify:    check validity of X.509 ID or attribute cert\n"
261            "    --keyid:     get fingerprint from X.509 ID cert\n"
262            "    --attribute: generate an X.509 attribute cert\n"
263            "    --roles:     list roles from an X.509 attribute cert\n"
264            "    --version:   display ABAC version\n"
265        );
266
267
268    exit(1);
269}
270
271void *xmalloc(size_t len) {
272    void *ret = malloc(len);
273    if (ret == NULL)
274        err(1, "couldn't malloc %d bytes\n", len);
275    return ret;
276}
277
278void *xrealloc(void *ptr, size_t size) {
279    void *ret = realloc(ptr, size);
280    if (ret == NULL)
281        err(1, "couldn't realloc %d bytes\n", size);
282    return ret;
283}
284
285char *xstrdup(char *string) {
286    char *dup = strdup(string);
287    if (dup == NULL)
288        err(1, "Can't dup %s", string);
289    return dup;
290}
291
292certificate_t *attr_cert_from_file(char *filename) {
293    certificate_t *cert = lib->creds->create(lib->creds,
294        CRED_CERTIFICATE, CERT_X509_AC,
295        BUILD_FROM_FILE, filename,
296        BUILD_END
297    );
298    if (cert == NULL)
299        errx(1, "Couldn't load attribute cert %s", filename);
300
301    return cert;
302}
Note: See TracBrowser for help on using the repository browser.