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