1 /* 2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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 "internal/e_os.h" /* LIST_SEPARATOR_CHAR */ 11 #include "apps.h" 12 #include <openssl/bio.h> 13 #include <openssl/err.h> 14 #include <openssl/rand.h> 15 #include <openssl/conf.h> 16 17 static char *save_rand_file; 18 static STACK_OF(OPENSSL_STRING) *randfiles; 19 20 void app_RAND_load_conf(CONF *c, const char *section) 21 { 22 const char *randfile = app_conf_try_string(c, section, "RANDFILE"); 23 24 if (randfile == NULL) 25 return; 26 if (RAND_load_file(randfile, -1) < 0) { 27 BIO_printf(bio_err, "Can't load %s into RNG\n", randfile); 28 ERR_print_errors(bio_err); 29 } 30 if (save_rand_file == NULL) { 31 save_rand_file = OPENSSL_strdup(randfile); 32 /* If some internal memory errors have occurred */ 33 if (save_rand_file == NULL) { 34 BIO_printf(bio_err, "Can't duplicate %s\n", randfile); 35 ERR_print_errors(bio_err); 36 } 37 } 38 } 39 40 static int loadfiles(char *name) 41 { 42 char *p; 43 int last, ret = 1; 44 45 for (;;) { 46 last = 0; 47 for (p = name; *p != '\0' && *p != LIST_SEPARATOR_CHAR; p++) 48 continue; 49 if (*p == '\0') 50 last = 1; 51 *p = '\0'; 52 if (RAND_load_file(name, -1) < 0) { 53 BIO_printf(bio_err, "Can't load %s into RNG\n", name); 54 ERR_print_errors(bio_err); 55 ret = 0; 56 } 57 if (last) 58 break; 59 name = p + 1; 60 if (*name == '\0') 61 break; 62 } 63 return ret; 64 } 65 66 int app_RAND_load(void) 67 { 68 char *p; 69 int i, ret = 1; 70 71 for (i = 0; i < sk_OPENSSL_STRING_num(randfiles); i++) { 72 p = sk_OPENSSL_STRING_value(randfiles, i); 73 if (!loadfiles(p)) 74 ret = 0; 75 } 76 sk_OPENSSL_STRING_free(randfiles); 77 return ret; 78 } 79 80 int app_RAND_write(void) 81 { 82 int ret = 1; 83 84 if (save_rand_file == NULL) 85 return 1; 86 if (RAND_write_file(save_rand_file) == -1) { 87 BIO_printf(bio_err, "Cannot write random bytes:\n"); 88 ERR_print_errors(bio_err); 89 ret = 0; 90 } 91 OPENSSL_free(save_rand_file); 92 save_rand_file = NULL; 93 return ret; 94 } 95 96 97 /* 98 * See comments in opt_verify for explanation of this. 99 */ 100 enum r_range { OPT_R_ENUM }; 101 102 int opt_rand(int opt) 103 { 104 switch ((enum r_range)opt) { 105 case OPT_R__FIRST: 106 case OPT_R__LAST: 107 break; 108 case OPT_R_RAND: 109 if (randfiles == NULL 110 && (randfiles = sk_OPENSSL_STRING_new_null()) == NULL) 111 return 0; 112 if (!sk_OPENSSL_STRING_push(randfiles, opt_arg())) 113 return 0; 114 break; 115 case OPT_R_WRITERAND: 116 OPENSSL_free(save_rand_file); 117 save_rand_file = OPENSSL_strdup(opt_arg()); 118 if (save_rand_file == NULL) 119 return 0; 120 break; 121 } 122 return 1; 123 } 124