#include #include #include #include #include #include "creddy.h" #define OPT_CN 1 #define OPT_VALIDITY 2 #define OPT_CERT 3 #define OPT_ISSUER 4 #define OPT_KEY 5 #define OPT_ROLE 6 #define OPT_SUBJECT 7 #define OPT_SUBJECT_ROLE 8 #define OPT_OUT 9 // the world oughta be opt-in only :( int main(int argc, char **argv) { int ret; options_t options = { 0, }; struct option getopts[] = { { "help", 0, &options.help, 1 }, { "generate", 0, &options.mode, MODE_GENERATE }, { "verify", 0, &options.mode, MODE_VERIFY }, { "keyid", 0, &options.mode, MODE_KEYID }, { "attribute", 0, &options.mode, MODE_ATTRIBUTE }, { "roles", 0, &options.mode, MODE_ROLES }, { "cert", 1, 0, OPT_CERT }, // generate options { "cn", 1, 0, OPT_CN }, { "validity", 1, 0, OPT_VALIDITY }, // attribute options { "issuer", 1, 0, OPT_ISSUER }, { "key", 1, 0, OPT_KEY }, { "role", 1, 0, OPT_ROLE }, { "subject", 1, 0, OPT_SUBJECT }, { "subject_role", 1, 0, OPT_SUBJECT_ROLE }, { "out", 1, 0, OPT_OUT }, { NULL }, }; for ( ; ; ) { int c = getopt_long(argc, argv, "", getopts, NULL); if (c < 0) break; switch (c) { // set the option from the value in the getopts struct case 0: continue; case OPT_CERT: options.cert = xstrdup(optarg); break; // generate options case OPT_CN: options.cn = xstrdup(optarg); break; case OPT_VALIDITY: // also an attribute option options.validity = atoi(optarg); break; // attribute options case OPT_ISSUER: options.issuer = xstrdup(optarg); break; case OPT_KEY: options.key = xstrdup(optarg); break; case OPT_ROLE: options.role = xstrdup(optarg); break; case OPT_SUBJECT: options.subject = xstrdup(optarg); break; case OPT_SUBJECT_ROLE: options.subject_role = xstrdup(optarg); break; case OPT_OUT: options.out = xstrdup(optarg); break; case '?': break; default: printf("wat\n"); return 45; } } if (options.help || optind < argc) { if (optind > 0 && optind < argc) printf("I don't understand %s\n", argv[optind]); usage(&options); } // init libstrongswan atexit(library_deinit); dbg_default_set_level(-1); ret = library_init(NULL); if (!ret) exit(SS_RC_LIBSTRONGSWAN_INTEGRITY); ret = lib->plugins->load( lib->plugins, NULL, lib->settings->get_str(lib->settings, "", PLUGINS) ); if (!ret) exit(SS_RC_LIBSTRONGSWAN_INTEGRITY); switch (options.mode) { case MODE_GENERATE: if (options.validity == 0) options.validity = 1080; generate_main(&options); break; case MODE_KEYID: keyid_main(&options); break; case MODE_ATTRIBUTE: if (options.validity == 0) options.validity = 365; attribute_main(&options); break; default: usage(&options); } return 0; } void usage(options_t *opts) { if (opts->mode == MODE_GENERATE) printf( "Usage: creddy --generate --cn [ --validity ]\n" " cert will be in ${name}_ID.der, private key in ${name}_private.der\n" " default validity: 1080 days\n" ); else if (opts->mode == MODE_VERIFY) printf( "Usage: identity --verify --cert [ --attrcert ]\n" " if attrcert is provided, verify that it was issued by cert\n" ); else if (opts->mode == MODE_KEYID) printf( "Usage: identity --keyid --cert \n" ); else if (opts->mode == MODE_ATTRIBUTE) printf( "Usage: identity --attribute \\\n" " --issuer --key --role \\\n" " --subject [ --subject-role ] \\\n" " [ --validity ] --out \n" " default validity: 365 days\n" ); else if (opts->mode == MODE_ROLES) printf( "Usage: identity --roles --cert \n" ); else printf( "Usage: creddy [--] [--help]\n" " --generate: generate X.509 identity cert and private key\n" " --verify: check validity of X.509 ID or attribute cert\n" " --keyid: get fingerprint from X.509 ID cert\n" " --attribute: generate an X.509 attribute cert\n" " --roles: list roles from an X.509 attribute cert\n" ); exit(1); } void *xmalloc(size_t len) { void *ret = malloc(len); if (ret == NULL) err(1, "couldn't malloc %d bytes\n", len); return ret; } char *xstrdup(char *string) { char *dup = strdup(string); if (dup == NULL) err(1, "Can't dup %s", string); return dup; } int clean_name(char *string) { int i; assert(string != NULL); // must start with a letter if (!isalpha(string[0])) return 0; // rest must be alphanumeric or _ for (i = 1; string[i] != '\0'; ++i) if (!isalnum(string[i]) && string[i] != '_') return 0; return 1; } // load an ID cert from file certificate_t *cert_from_file(char *filename) { certificate_t *cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, filename, BUILD_X509_FLAG, X509_AA, BUILD_END ); if (cert == NULL) errx(1, "Can't open cert from %s", filename); return cert; }