1/* 2 * Copyright 2019-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#define OSSL_FORCE_ERR_STATE 11 12#include <string.h> 13#include <openssl/err.h> 14#include "err_local.h" 15 16void ERR_new(void) 17{ 18 ERR_STATE *es; 19 20 es = ossl_err_get_state_int(); 21 if (es == NULL) 22 return; 23 24 /* Allocate a slot */ 25 err_get_slot(es); 26 err_clear(es, es->top, 0); 27} 28 29void ERR_set_debug(const char *file, int line, const char *func) 30{ 31 ERR_STATE *es; 32 33 es = ossl_err_get_state_int(); 34 if (es == NULL) 35 return; 36 37 err_set_debug(es, es->top, file, line, func); 38} 39 40void ERR_set_error(int lib, int reason, const char *fmt, ...) 41{ 42 va_list args; 43 44 va_start(args, fmt); 45 ERR_vset_error(lib, reason, fmt, args); 46 va_end(args); 47} 48 49void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) 50{ 51 ERR_STATE *es; 52 char *buf = NULL; 53 size_t buf_size = 0; 54 unsigned long flags = 0; 55 size_t i; 56 57 es = ossl_err_get_state_int(); 58 if (es == NULL) 59 return; 60 i = es->top; 61 62 if (fmt != NULL) { 63 int printed_len = 0; 64 char *rbuf = NULL; 65 66 buf = es->err_data[i]; 67 buf_size = es->err_data_size[i]; 68 69 /* 70 * To protect the string we just grabbed from tampering by other 71 * functions we may call, or to protect them from freeing a pointer 72 * that may no longer be valid at that point, we clear away the 73 * data pointer and the flags. We will set them again at the end 74 * of this function. 75 */ 76 es->err_data[i] = NULL; 77 es->err_data_flags[i] = 0; 78 79 /* 80 * Try to maximize the space available. If that fails, we use what 81 * we have. 82 */ 83 if (buf_size < ERR_MAX_DATA_SIZE 84 && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) { 85 buf = rbuf; 86 buf_size = ERR_MAX_DATA_SIZE; 87 } 88 89 if (buf != NULL) { 90 printed_len = BIO_vsnprintf(buf, buf_size, fmt, args); 91 } 92 if (printed_len < 0) 93 printed_len = 0; 94 if (buf != NULL) 95 buf[printed_len] = '\0'; 96 97 /* 98 * Try to reduce the size, but only if we maximized above. If that 99 * fails, we keep what we have. 100 * (According to documentation, realloc leaves the old buffer untouched 101 * if it fails) 102 */ 103 if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) { 104 buf = rbuf; 105 buf_size = printed_len + 1; 106 buf[printed_len] = '\0'; 107 } 108 109 if (buf != NULL) 110 flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; 111 } 112 113 err_clear_data(es, es->top, 0); 114 err_set_error(es, es->top, lib, reason); 115 if (fmt != NULL) 116 err_set_data(es, es->top, buf, buf_size, flags); 117} 118