From: zriback Date: Fri, 4 Apr 2025 09:47:24 +0000 (-0400) Subject: Update to use BIO_get_line() with support for multiple primes per in file X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6dc0f1cacd4a21a0de5b58d0ec4139629c66b7a;p=thirdparty%2Fopenssl.git Update to use BIO_get_line() with support for multiple primes per in file Reviewed-by: Paul Dale Reviewed-by: Viktor Dukhovni (Merged from https://github.com/openssl/openssl/pull/26549) --- diff --git a/apps/prime.c b/apps/prime.c index 92c04569a64..c582de98a5b 100644 --- a/apps/prime.c +++ b/apps/prime.c @@ -13,7 +13,8 @@ #include "progs.h" #include -#define BUFSIZE 256 +/* Consistent with RSA modulus size limit and the size of plausible individual primes */ +#define BUFSIZE 4098 typedef enum OPTION_choice { OPT_COMMON, @@ -39,6 +40,30 @@ static int check_num(const char *s, const int is_hex) return s[i] == 0; } +static void process_num(const char *s, const int is_hex, BIGNUM *bn) +{ + int r; + + r = check_num(s, is_hex); + + if (r) + r = is_hex ? BN_hex2bn(&bn, s) : BN_dec2bn(&bn, s); + + if (!r) { + BIO_printf(bio_err, "Failed to process value (%s)\n", s); + return; + } + + BN_print(bio_out, bn); + r = BN_check_prime(bn, NULL, NULL); + if (r < 0) { + BIO_printf(bio_err, "Error checking prime\n"); + return; + } + + BIO_printf(bio_out, " (%s) %s prime\n", s, r == 1 ? "is" : "is not"); +} + const OPTIONS prime_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, @@ -68,7 +93,7 @@ int prime_main(int argc, char **argv) int hex = 0, generate = 0, bits = 0, safe = 0, ret = 1, in_file = 0; char *prog; OPTION_CHOICE o; - char *file_read_buf = NULL; + char file_read_buf[BUFSIZE] = { 0 }; BIO *in = NULL; prog = opt_init(argc, argv, prime_options); @@ -144,75 +169,39 @@ opthelp: OPENSSL_free(s); } else { for ( ; *argv; argv++) { - char *check_val; int bytes_read = 0; - int total_read = 0; - int r; + int valid_digits_length = 0; if (!in_file) { - check_val = argv[0]; + process_num(argv[0], hex, bn); } else { in = bio_open_default_quiet(argv[0], 'r', 0); if (in == NULL) { BIO_printf(bio_err, "Error opening file %s\n", argv[0]); - goto end; + continue; } - file_read_buf = (char *)app_malloc(BUFSIZE, "File read buffer"); - while (BIO_pending(in) || !BIO_eof(in)) { - bytes_read = BIO_read(in, (char *)(file_read_buf + total_read), BUFSIZE); - if (bytes_read < 0) { - BIO_printf(bio_err, "Read error in %s\n", argv[0]); - goto end; + while ((bytes_read = BIO_get_line(in, file_read_buf, BUFSIZE)) > 0) { + /* Number is too long. Discard remainder of the line */ + if (bytes_read == BUFSIZE - 1 && file_read_buf[BUFSIZE - 2] != '\n') { + BIO_printf(bio_err, "Value in %s is over the maximum size (%d digits)\n", + argv[0], BUFSIZE - 2); + while (BIO_get_line(in, file_read_buf, BUFSIZE) == BUFSIZE - 1); + continue; } - if (bytes_read == 0) - break; - total_read += bytes_read; - if (bytes_read == BUFSIZE) - file_read_buf = (char *)realloc(file_read_buf, BUFSIZE + total_read); - } - /* Deal with the case of an empty file */ - if (total_read == 0) { - BIO_printf(bio_err, "Cannot process empty file\n"); - goto end; - } + valid_digits_length = strspn(file_read_buf, "1234567890abcdefABCDEF"); + file_read_buf[valid_digits_length] = '\0'; - /* Deal with Unix and Windows line endings */ - if (total_read >= 2 && file_read_buf[total_read - 2] == '\r') - file_read_buf[total_read - 2] = '\0'; - else if (total_read >= 1 && file_read_buf[total_read - 1] == '\n') - file_read_buf[total_read - 1] = '\0'; - - check_val = file_read_buf; - - } - - r = check_num(check_val, hex); - - if (r) - r = hex ? BN_hex2bn(&bn, check_val) : BN_dec2bn(&bn, check_val); - - if (!r) { - BIO_printf(bio_err, "Failed to process value (%s)\n", check_val); - goto end; - } + process_num(file_read_buf, hex, bn); + } - BN_print(bio_out, bn); - r = BN_check_prime(bn, NULL, NULL); - if (r < 0) { - BIO_printf(bio_err, "Error checking prime\n"); - goto end; - } - BIO_printf(bio_out, " (%s) %s prime\n", - check_val, - r == 1 ? "is" : "is not"); + if (bytes_read < 0) + BIO_printf(bio_err, "Read error in %s\n", argv[0]); - if (in_file) { - BIO_free(in); - OPENSSL_free(file_read_buf); + if (in != NULL) + BIO_free(in); in = NULL; - file_read_buf = NULL; } } } @@ -222,7 +211,5 @@ opthelp: BN_free(bn); if (in != NULL) BIO_free(in); - if (file_read_buf != NULL) - OPENSSL_free(file_read_buf); return ret; } diff --git a/test/recipes/20-test_prime.t b/test/recipes/20-test_prime.t index 16e69eb6526..a44cdf0862a 100644 --- a/test/recipes/20-test_prime.t +++ b/test/recipes/20-test_prime.t @@ -22,7 +22,7 @@ my $long_number_file = data_file("long_number.txt"); my $short_number_file = data_file("short_number.txt"); my $non_number_file = data_file("non_number.txt"); my $hex_number_file = data_file("hex_number.txt"); -my $bad_format_file = data_file("bad_format.txt"); +my $multiple_lines_file = data_file("multiple_lines.txt"); my $empty_file = data_file("empty.txt"); @@ -38,20 +38,20 @@ ok(run(app(["openssl", "prime", "-in", $long_number_file])), ok(run(app(["openssl", "prime", "-in", $short_number_file])), "Run openssl prime with a short number -in file"); -ok(!run(app(["openssl", "prime", "-in", $non_number_file])), +ok(run(app(["openssl", "prime", "-in", $non_number_file])), "Run openssl prime with non number -in file"); ok(run(app(["openssl", "prime", "-in", "-hex", $hex_number_file])), "Run openssl prime with hex number -in file"); -ok(!run(app(["openssl", "prime", "-in", $bad_format_file])), - "Run openssl prime with bad format -in file"); +ok(run(app(["openssl", "prime", "-in", $multiple_lines_file])), + "Run openssl prime with -in file with multiple lines"); -ok(!run(app(["openssl", "prime", "-in", $empty_file])), +ok(run(app(["openssl", "prime", "-in", $empty_file])), "Run openssl prime with an empty -in file"); -ok(run(app(["openssl", "prime", "-in", $prime_file, $composite_file, $long_number_file])), +ok(run(app(["openssl", "prime", "-in", $prime_file, $composite_file, $long_number_file, $multiple_lines_file])), "Run openssl prime with multiple -in files"); -ok(!run(app(["openssl", "prime", "-in", "does_not_exist.txt"])), +ok(run(app(["openssl", "prime", "-in", "does_not_exist.txt"])), "Run openssl prime with -in file that does not exist"); \ No newline at end of file diff --git a/test/recipes/20-test_prime_data/bad_format.txt b/test/recipes/20-test_prime_data/multiple_lines.txt similarity index 66% rename from test/recipes/20-test_prime_data/bad_format.txt rename to test/recipes/20-test_prime_data/multiple_lines.txt index ce8c77db7f7..dda4f8bf1f8 100644 --- a/test/recipes/20-test_prime_data/bad_format.txt +++ b/test/recipes/20-test_prime_data/multiple_lines.txt @@ -1,2 +1,3 @@ 123 456 +101