]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Update to use BIO_get_line() with support for multiple primes per in file
authorzriback <zacharythecdr@gmail.com>
Fri, 4 Apr 2025 09:47:24 +0000 (05:47 -0400)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Tue, 29 Apr 2025 04:17:06 +0000 (14:17 +1000)
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26549)

apps/prime.c
test/recipes/20-test_prime.t
test/recipes/20-test_prime_data/multiple_lines.txt [moved from test/recipes/20-test_prime_data/bad_format.txt with 66% similarity]

index 92c04569a643b391f69b95f0a5c6ee5ef8a6d4fe..c582de98a5b26586e801e2ce410bd8afbe220586 100644 (file)
@@ -13,7 +13,8 @@
 #include "progs.h"
 #include <openssl/bn.h>
 
-#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;
 }
index 16e69eb6526c739208e57e26ca428f64159711e1..a44cdf0862a5c4f5806b2537bd81c7ed28726840 100644 (file)
@@ -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
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 ce8c77db7f732ddc56661bc5f5cae2e1198978b1..dda4f8bf1f8c952a75fe4ab90a277dc651e03679 100644 (file)
@@ -1,2 +1,3 @@
 123
 456
+101