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