/* * keygen_args.cpp * * Notes: since argv[] array contains c-style char strings, I chose to use C * functions to work on them instead of dealing with C++ class string * conversions. * */ #include "keygen_args.h" #include "miller_rabin.h" char *pubkey; char *prikey; long prime_p; long prime_q; int random_f; int keygen_args(int argc, char **argv) { /* flags */ int primep_f = 0; int primeq_f = 0; int fname_f = 0; int usage_f = 0; random_f = 0; int primep_args = 0; int primeq_args = 0; int fname_args = 0; int opt_args = 0; int i; for (i = 1; i < argc; i++) { if (argc > 9) { fprintf(stderr, "too many options\n"); usage_f = 1; break; } /* skip non option arguments */ if (!strchr(argv[i], '-')) { opt_args++; if (primep_f) { if (i-1 == primep_f) primep_args++; /* not allowed to have 2 args */ if ((i-2 == primep_f) && argv[i-1][0] != '-') { fprintf(stderr, "too many arguments to \"-p\" option\n"); usage_f = 1; break; } } if (primeq_f) { if (i-1 == primeq_f) primeq_args++; /* not allowed to have 2 args */ if ((i-2 == primeq_f) && argv[i-1][0] != '-') { fprintf(stderr, "too many arguments to \"-q\" option\n"); usage_f = 1; break; } } if (fname_f) { if ((i-1 == fname_f) || (i-2 == fname_f)) fname_args++; if ((i-3 == fname_f)) /* not allowed to have 3 args */ { fprintf(stderr, "too many arguments to \"-o\" option\n"); usage_f = 1; break; } } continue; } else if (strcmp(argv[i], "-p") == 0) primep_f = i; else if (strcmp(argv[i], "-q") == 0) primeq_f = i; else if (strcmp(argv[i], "-o") == 0) fname_f = i; else if (strcmp(argv[i], "-c") == 0) random_f = i; else { fprintf(stderr, "unknown option \"%s\"\n", argv[i]); usage_f = 1; break; } } /* error checking */ if (usage_f || opt_args > 4 || fname_args == 1) { if (fname_args == 1) fprintf(stderr, "too few arguments to \"-o\" option\n"); printf("usage: %s [-p] [-q] [-o pubkey prikey] [-c]\n", argv[0]); exit(EXIT_FAILURE); } ssize_t amount_read = 0; int args_parsed = 0; size_t line_sz = 0; char *line_ptr = NULL; /* handle key filenames */ if (fname_args == 2) { pubkey = strdup(argv[fname_f+1]); prikey = strdup(argv[fname_f+2]); } else if (fname_f) /* fname_args equals 0 here */ { /* ask user for the filenames */ puts("please provide pubkey and prikey filenames separated by a space"); printf("e.g. \"pubkey.xml prikey.xml\": "); pubkey = (char *) malloc(sizeof(char) * 100); prikey = (char *) malloc(sizeof(char) * 100); if (!line_ptr || !pubkey || !prikey) { perror("malloc"); exit(EXIT_FAILURE); } do { fflush(stdin); amount_read = getline(&line_ptr, &line_sz, stdin); args_parsed = sscanf(line_ptr, "%s %s", pubkey, prikey); if (args_parsed != 2) fprintf(stderr, "invalid input, please try again: "); } while (args_parsed != 2); } else { pubkey = strdup("pubkey.xml"); prikey = strdup("prikey.xml"); } if (primep_f) { /* if number was not specified or it's not a prime ask for the number */ if (primep_args == 0) { printf("please provide a value for prime p: "); do { fflush(stdin); amount_read = getline(&line_ptr, &line_sz, stdin); args_parsed = sscanf(line_ptr, "%ld", &prime_p); if (args_parsed != 1) fprintf(stderr, "invalid input, please try again: "); if (!miller_rabin_16(prime_p)) fprintf(stderr, "not a prime number, please try again: "); } while (args_parsed != 1 || !miller_rabin_16(prime_p)); } else { prime_p = atol(argv[primep_f+1]); if (!miller_rabin_16(prime_p)) { fprintf(stderr, "prime p on the command line is not prime\n"); exit(EXIT_FAILURE); } } } if (primeq_f) { /* if number was not specified or it's not a prime ask for the number */ if (primeq_args == 0) { printf("please provide a value for prime q: "); do { fflush(stdin); amount_read = getline(&line_ptr, &line_sz, stdin); args_parsed = sscanf(line_ptr, "%ld", &prime_q); if (args_parsed != 1) fprintf(stderr, "invalid input, please try again: "); if (!miller_rabin_16(prime_q)) fprintf(stderr, "not a prime number, please try again: "); } while (args_parsed != 1 || !miller_rabin_16(prime_q)); } else { prime_q = atol(argv[primeq_f+1]); if (!miller_rabin_16(prime_q)) { fprintf(stderr, "prime q on the command line is not prime\n"); exit(EXIT_FAILURE); } } } if (line_ptr) free(line_ptr); return 0; }