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