1 /* 2 * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <string.h> 11 12 #include "apps.h" 13 #include "progs.h" 14 #include <openssl/bn.h> 15 16 typedef enum OPTION_choice { 17 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 18 OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS 19 } OPTION_CHOICE; 20 21 const OPTIONS prime_options[] = { 22 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, 23 {OPT_HELP_STR, 1, '-', 24 " number Number to check for primality\n"}, 25 {"help", OPT_HELP, '-', "Display this summary"}, 26 {"hex", OPT_HEX, '-', "Hex output"}, 27 {"generate", OPT_GENERATE, '-', "Generate a prime"}, 28 {"bits", OPT_BITS, 'p', "Size of number in bits"}, 29 {"safe", OPT_SAFE, '-', 30 "When used with -generate, generate a safe prime"}, 31 {"checks", OPT_CHECKS, 'p', "Number of checks"}, 32 {NULL} 33 }; 34 35 int prime_main(int argc, char **argv) 36 { 37 BIGNUM *bn = NULL; 38 int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1; 39 char *prog; 40 OPTION_CHOICE o; 41 42 prog = opt_init(argc, argv, prime_options); 43 while ((o = opt_next()) != OPT_EOF) { 44 switch (o) { 45 case OPT_EOF: 46 case OPT_ERR: 47 opthelp: 48 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 49 goto end; 50 case OPT_HELP: 51 opt_help(prime_options); 52 ret = 0; 53 goto end; 54 case OPT_HEX: 55 hex = 1; 56 break; 57 case OPT_GENERATE: 58 generate = 1; 59 break; 60 case OPT_BITS: 61 bits = atoi(opt_arg()); 62 break; 63 case OPT_SAFE: 64 safe = 1; 65 break; 66 case OPT_CHECKS: 67 checks = atoi(opt_arg()); 68 break; 69 } 70 } 71 argc = opt_num_rest(); 72 argv = opt_rest(); 73 74 if (generate) { 75 if (argc != 0) { 76 BIO_printf(bio_err, "Extra arguments given.\n"); 77 goto opthelp; 78 } 79 } else if (argc == 0) { 80 BIO_printf(bio_err, "%s: No prime specified\n", prog); 81 goto opthelp; 82 } 83 84 if (generate) { 85 char *s; 86 87 if (!bits) { 88 BIO_printf(bio_err, "Specify the number of bits.\n"); 89 goto end; 90 } 91 bn = BN_new(); 92 if (bn == NULL) { 93 BIO_printf(bio_err, "Out of memory.\n"); 94 goto end; 95 } 96 if (!BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL)) { 97 BIO_printf(bio_err, "Failed to generate prime.\n"); 98 goto end; 99 } 100 s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 101 if (s == NULL) { 102 BIO_printf(bio_err, "Out of memory.\n"); 103 goto end; 104 } 105 BIO_printf(bio_out, "%s\n", s); 106 OPENSSL_free(s); 107 } else { 108 for ( ; *argv; argv++) { 109 int r; 110 111 if (hex) 112 r = BN_hex2bn(&bn, argv[0]); 113 else 114 r = BN_dec2bn(&bn, argv[0]); 115 116 if (!r) { 117 BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]); 118 goto end; 119 } 120 121 BN_print(bio_out, bn); 122 BIO_printf(bio_out, " (%s) %s prime\n", 123 argv[0], 124 BN_is_prime_ex(bn, checks, NULL, NULL) 125 ? "is" : "is not"); 126 } 127 } 128 129 ret = 0; 130 end: 131 BN_free(bn); 132 return ret; 133 } 134