mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
 | |
|  *
 | |
|  * Licensed under the Apache License 2.0 (the "License").  You may not use
 | |
|  * this file except in compliance with the License.  You can obtain a copy
 | |
|  * in the file LICENSE in the source distribution or at
 | |
|  * https://www.openssl.org/source/license.html
 | |
|  */
 | |
| 
 | |
| /* TODO: When ERR_STATE becomes opaque, this musts be removed */
 | |
| #define OSSL_FORCE_ERR_STATE
 | |
| 
 | |
| #include <string.h>
 | |
| #include <openssl/err.h>
 | |
| #include "err_local.h"
 | |
| 
 | |
| void ERR_new(void)
 | |
| {
 | |
|     ERR_STATE *es;
 | |
| 
 | |
|     es = err_get_state_int();
 | |
|     if (es == NULL)
 | |
|         return;
 | |
| 
 | |
|     /* Allocate a slot */
 | |
|     err_get_slot(es);
 | |
|     err_clear(es, es->top, 0);
 | |
| }
 | |
| 
 | |
| void ERR_set_debug(const char *file, int line, const char *func)
 | |
| {
 | |
|     ERR_STATE *es;
 | |
| 
 | |
|     es = err_get_state_int();
 | |
|     if (es == NULL)
 | |
|         return;
 | |
| 
 | |
|     err_set_debug(es, es->top, file, line, func);
 | |
| }
 | |
| 
 | |
| void ERR_set_error(int lib, int reason, const char *fmt, ...)
 | |
| {
 | |
|     va_list args;
 | |
| 
 | |
|     va_start(args, fmt);
 | |
|     ERR_vset_error(lib, reason, fmt, args);
 | |
|     va_end(args);
 | |
| }
 | |
| 
 | |
| void ERR_vset_error(int lib, int reason, const char *fmt, va_list args)
 | |
| {
 | |
|     ERR_STATE *es;
 | |
|     char *buf = NULL;
 | |
|     size_t buf_size = 0;
 | |
|     unsigned long flags = 0;
 | |
|     size_t i;
 | |
| 
 | |
|     es = err_get_state_int();
 | |
|     if (es == NULL)
 | |
|         return;
 | |
|     i = es->top;
 | |
| 
 | |
|     if (fmt != NULL) {
 | |
|         int printed_len = 0;
 | |
|         char *rbuf = NULL;
 | |
| 
 | |
|         buf = es->err_data[i];
 | |
|         buf_size = es->err_data_size[i];
 | |
| 
 | |
|         /*
 | |
|          * To protect the string we just grabbed from tampering by other
 | |
|          * functions we may call, or to protect them from freeing a pointer
 | |
|          * that may no longer be valid at that point, we clear away the
 | |
|          * data pointer and the flags.  We will set them again at the end
 | |
|          * of this function.
 | |
|          */
 | |
|         es->err_data[i] = NULL;
 | |
|         es->err_data_flags[i] = 0;
 | |
| 
 | |
|         /*
 | |
|          * Try to maximize the space available.  If that fails, we use what
 | |
|          * we have.
 | |
|          */
 | |
|         if (buf_size < ERR_MAX_DATA_SIZE
 | |
|             && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) {
 | |
|             buf = rbuf;
 | |
|             buf_size = ERR_MAX_DATA_SIZE;
 | |
|         }
 | |
| 
 | |
|         if (buf != NULL) {
 | |
|             printed_len = BIO_vsnprintf(buf, buf_size, fmt, args);
 | |
|         }
 | |
|         if (printed_len < 0)
 | |
|             printed_len = 0;
 | |
|         buf[printed_len] = '\0';
 | |
| 
 | |
|         /*
 | |
|          * Try to reduce the size, but only if we maximized above.  If that
 | |
|          * fails, we keep what we have.
 | |
|          * (According to documentation, realloc leaves the old buffer untouched
 | |
|          * if it fails)
 | |
|          */
 | |
|         if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) {
 | |
|             buf = rbuf;
 | |
|             buf_size = printed_len + 1;
 | |
|         }
 | |
| 
 | |
|         if (buf != NULL)
 | |
|             flags = ERR_TXT_MALLOCED | ERR_TXT_STRING;
 | |
|     }
 | |
| 
 | |
|     err_clear_data(es, es->top, 0);
 | |
|     err_set_error(es, es->top, lib, reason);
 | |
|     if (fmt != NULL)
 | |
|         err_set_data(es, es->top, buf, buf_size, flags);
 | |
| }
 |