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