err.c revision 296465
1168777Srwatson/* crypto/err/err.c */ 2168777Srwatson/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3168777Srwatson * All rights reserved. 4168777Srwatson * 5168777Srwatson * This package is an SSL implementation written 6168777Srwatson * by Eric Young (eay@cryptsoft.com). 7168777Srwatson * The implementation was written so as to conform with Netscapes SSL. 8168777Srwatson * 9168777Srwatson * This library is free for commercial and non-commercial use as long as 10168777Srwatson * the following conditions are aheared to. The following conditions 11168777Srwatson * apply to all code found in this distribution, be it the RC4, RSA, 12168777Srwatson * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13168777Srwatson * included with this distribution is covered by the same copyright terms 14168777Srwatson * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15168777Srwatson * 16168777Srwatson * Copyright remains Eric Young's, and as such any Copyright notices in 17168777Srwatson * the code are not to be removed. 18168777Srwatson * If this package is used in a product, Eric Young should be given attribution 19168777Srwatson * as the author of the parts of the library used. 20168777Srwatson * This can be in the form of a textual message at program startup or 21168777Srwatson * in documentation (online or textual) provided with the package. 22168777Srwatson * 23168777Srwatson * Redistribution and use in source and binary forms, with or without 24168777Srwatson * modification, are permitted provided that the following conditions 25168777Srwatson * are met: 26185573Srwatson * 1. Redistributions of source code must retain the copyright 27168777Srwatson * notice, this list of conditions and the following disclaimer. 28168777Srwatson * 2. Redistributions in binary form must reproduce the above copyright 29168777Srwatson * notice, this list of conditions and the following disclaimer in the 30168777Srwatson * documentation and/or other materials provided with the distribution. 31168777Srwatson * 3. All advertising materials mentioning features or use of this software 32168777Srwatson * must display the following acknowledgement: 33168777Srwatson * "This product includes cryptographic software written by 34168777Srwatson * Eric Young (eay@cryptsoft.com)" 35168777Srwatson * The word 'cryptographic' can be left out if the rouines from the library 36168777Srwatson * being used are not cryptographic related :-). 37168777Srwatson * 4. If you include any Windows specific code (or a derivative thereof) from 38168777Srwatson * the apps directory (application code) you must include an acknowledgement: 39168777Srwatson * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40168777Srwatson * 41168777Srwatson * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42168777Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43168777Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44168777Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45168777Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46168777Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47168777Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48168777Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49168777Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50168777Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51168777Srwatson * SUCH DAMAGE. 52168777Srwatson * 53168777Srwatson * The licence and distribution terms for any publically available version or 54168777Srwatson * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58/* ==================================================================== 59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 60 * 61 * Redistribution and use in source and binary forms, with or without 62 * modification, are permitted provided that the following conditions 63 * are met: 64 * 65 * 1. Redistributions of source code must retain the above copyright 66 * notice, this list of conditions and the following disclaimer. 67 * 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in 70 * the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3. All advertising materials mentioning features or use of this 74 * software must display the following acknowledgment: 75 * "This product includes software developed by the OpenSSL Project 76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77 * 78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79 * endorse or promote products derived from this software without 80 * prior written permission. For written permission, please contact 81 * openssl-core@openssl.org. 82 * 83 * 5. Products derived from this software may not be called "OpenSSL" 84 * nor may "OpenSSL" appear in their names without prior written 85 * permission of the OpenSSL Project. 86 * 87 * 6. Redistributions of any form whatsoever must retain the following 88 * acknowledgment: 89 * "This product includes software developed by the OpenSSL Project 90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91 * 92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103 * OF THE POSSIBILITY OF SUCH DAMAGE. 104 * ==================================================================== 105 * 106 * This product includes cryptographic software written by Eric Young 107 * (eay@cryptsoft.com). This product includes software written by Tim 108 * Hudson (tjh@cryptsoft.com). 109 * 110 */ 111 112#include <stdio.h> 113#include <stdarg.h> 114#include <string.h> 115#include "cryptlib.h" 116#include <openssl/lhash.h> 117#include <openssl/crypto.h> 118#include <openssl/buffer.h> 119#include <openssl/bio.h> 120#include <openssl/err.h> 121 122static unsigned long get_error_values(int inc, int top, 123 const char **file, int *line, 124 const char **data, int *flags); 125 126#define err_clear_data(p,i) \ 127 do { \ 128 if (((p)->err_data[i] != NULL) && \ 129 (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ 130 { \ 131 OPENSSL_free((p)->err_data[i]); \ 132 (p)->err_data[i]=NULL; \ 133 } \ 134 (p)->err_data_flags[i]=0; \ 135 } while(0) 136 137#define err_clear(p,i) \ 138 do { \ 139 (p)->err_flags[i]=0; \ 140 (p)->err_buffer[i]=0; \ 141 err_clear_data(p,i); \ 142 (p)->err_file[i]=NULL; \ 143 (p)->err_line[i]= -1; \ 144 } while(0) 145 146void ERR_put_error(int lib, int func, int reason, const char *file, int line) 147{ 148 ERR_STATE *es; 149 150#ifdef _OSD_POSIX 151 /* 152 * In the BS2000-OSD POSIX subsystem, the compiler generates path names 153 * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to 154 * something sensible. @@@ We shouldn't modify a const string, though. 155 */ 156 if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { 157 char *end; 158 159 /* Skip the "*POSIX(" prefix */ 160 file += sizeof("*POSIX(") - 1; 161 end = &file[strlen(file) - 1]; 162 if (*end == ')') 163 *end = '\0'; 164 /* Optional: use the basename of the path only. */ 165 if ((end = strrchr(file, '/')) != NULL) 166 file = &end[1]; 167 } 168#endif 169 es = ERR_get_state(); 170 171 es->top = (es->top + 1) % ERR_NUM_ERRORS; 172 if (es->top == es->bottom) 173 es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; 174 es->err_flags[es->top] = 0; 175 es->err_buffer[es->top] = ERR_PACK(lib, func, reason); 176 es->err_file[es->top] = file; 177 es->err_line[es->top] = line; 178 err_clear_data(es, es->top); 179} 180 181void ERR_clear_error(void) 182{ 183 int i; 184 ERR_STATE *es; 185 186 es = ERR_get_state(); 187 188 for (i = 0; i < ERR_NUM_ERRORS; i++) { 189 err_clear(es, i); 190 } 191 es->top = es->bottom = 0; 192} 193 194unsigned long ERR_get_error(void) 195{ 196 return (get_error_values(1, 0, NULL, NULL, NULL, NULL)); 197} 198 199unsigned long ERR_get_error_line(const char **file, int *line) 200{ 201 return (get_error_values(1, 0, file, line, NULL, NULL)); 202} 203 204unsigned long ERR_get_error_line_data(const char **file, int *line, 205 const char **data, int *flags) 206{ 207 return (get_error_values(1, 0, file, line, data, flags)); 208} 209 210unsigned long ERR_peek_error(void) 211{ 212 return (get_error_values(0, 0, NULL, NULL, NULL, NULL)); 213} 214 215unsigned long ERR_peek_error_line(const char **file, int *line) 216{ 217 return (get_error_values(0, 0, file, line, NULL, NULL)); 218} 219 220unsigned long ERR_peek_error_line_data(const char **file, int *line, 221 const char **data, int *flags) 222{ 223 return (get_error_values(0, 0, file, line, data, flags)); 224} 225 226unsigned long ERR_peek_last_error(void) 227{ 228 return (get_error_values(0, 1, NULL, NULL, NULL, NULL)); 229} 230 231unsigned long ERR_peek_last_error_line(const char **file, int *line) 232{ 233 return (get_error_values(0, 1, file, line, NULL, NULL)); 234} 235 236unsigned long ERR_peek_last_error_line_data(const char **file, int *line, 237 const char **data, int *flags) 238{ 239 return (get_error_values(0, 1, file, line, data, flags)); 240} 241 242static unsigned long get_error_values(int inc, int top, const char **file, 243 int *line, const char **data, 244 int *flags) 245{ 246 int i = 0; 247 ERR_STATE *es; 248 unsigned long ret; 249 250 es = ERR_get_state(); 251 252 if (inc && top) { 253 if (file) 254 *file = ""; 255 if (line) 256 *line = 0; 257 if (data) 258 *data = ""; 259 if (flags) 260 *flags = 0; 261 262 return ERR_R_INTERNAL_ERROR; 263 } 264 265 if (es->bottom == es->top) 266 return 0; 267 if (top) 268 i = es->top; /* last error */ 269 else 270 i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ 271 272 ret = es->err_buffer[i]; 273 if (inc) { 274 es->bottom = i; 275 es->err_buffer[i] = 0; 276 } 277 278 if ((file != NULL) && (line != NULL)) { 279 if (es->err_file[i] == NULL) { 280 *file = "NA"; 281 if (line != NULL) 282 *line = 0; 283 } else { 284 *file = es->err_file[i]; 285 if (line != NULL) 286 *line = es->err_line[i]; 287 } 288 } 289 290 if (data == NULL) { 291 if (inc) { 292 err_clear_data(es, i); 293 } 294 } else { 295 if (es->err_data[i] == NULL) { 296 *data = ""; 297 if (flags != NULL) 298 *flags = 0; 299 } else { 300 *data = es->err_data[i]; 301 if (flags != NULL) 302 *flags = es->err_data_flags[i]; 303 } 304 } 305 return ret; 306} 307 308void ERR_set_error_data(char *data, int flags) 309{ 310 ERR_STATE *es; 311 int i; 312 313 es = ERR_get_state(); 314 315 i = es->top; 316 if (i == 0) 317 i = ERR_NUM_ERRORS - 1; 318 319 err_clear_data(es, i); 320 es->err_data[i] = data; 321 es->err_data_flags[i] = flags; 322} 323 324void ERR_add_error_data(int num, ...) 325{ 326 va_list args; 327 int i, n, s; 328 char *str, *p, *a; 329 330 s = 80; 331 str = OPENSSL_malloc(s + 1); 332 if (str == NULL) 333 return; 334 str[0] = '\0'; 335 336 va_start(args, num); 337 n = 0; 338 for (i = 0; i < num; i++) { 339 a = va_arg(args, char *); 340 /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */ 341 if (a != NULL) { 342 n += strlen(a); 343 if (n > s) { 344 s = n + 20; 345 p = OPENSSL_realloc(str, s + 1); 346 if (p == NULL) { 347 OPENSSL_free(str); 348 goto err; 349 } else 350 str = p; 351 } 352 BUF_strlcat(str, a, (size_t)s + 1); 353 } 354 } 355 ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING); 356 357 err: 358 va_end(args); 359} 360 361int ERR_set_mark(void) 362{ 363 ERR_STATE *es; 364 365 es = ERR_get_state(); 366 367 if (es->bottom == es->top) 368 return 0; 369 es->err_flags[es->top] |= ERR_FLAG_MARK; 370 return 1; 371} 372 373int ERR_pop_to_mark(void) 374{ 375 ERR_STATE *es; 376 377 es = ERR_get_state(); 378 379 while (es->bottom != es->top 380 && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { 381 err_clear(es, es->top); 382 es->top -= 1; 383 if (es->top == -1) 384 es->top = ERR_NUM_ERRORS - 1; 385 } 386 387 if (es->bottom == es->top) 388 return 0; 389 es->err_flags[es->top] &= ~ERR_FLAG_MARK; 390 return 1; 391} 392 393#ifdef OPENSSL_FIPS 394 395static ERR_STATE *fget_state(void) 396{ 397 static ERR_STATE fstate; 398 return &fstate; 399} 400 401ERR_STATE *(*get_state_func) (void) = fget_state; 402void (*remove_state_func) (unsigned long pid); 403 404ERR_STATE *ERR_get_state(void) 405{ 406 return get_state_func(); 407} 408 409void int_ERR_set_state_func(ERR_STATE *(*get_func) (void), 410 void (*remove_func) (unsigned long pid)) 411{ 412 get_state_func = get_func; 413 remove_state_func = remove_func; 414} 415 416void ERR_remove_state(unsigned long pid) 417{ 418 if (remove_state_func) 419 remove_state_func(pid); 420} 421 422#endif 423