/* * Copyright (C) 2000 Nikos Mavroyanopoulos * * This file is part of GNUTLS. * * The GNUTLS library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include "gnutls_errors.h" #include #ifdef STDC_HEADERS # include #endif extern void (*_gnutls_log_func)( const char*); #define GNUTLS_ERROR_ENTRY(name, fatal) \ { #name, name, fatal } struct gnutls_error_entry { const char *name; int number; int fatal; }; typedef struct gnutls_error_entry gnutls_error_entry; static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_SUCCESS, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_CERTIFICATE_KEY_MISMATCH, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_PK_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_MAC_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNWANTED_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_LARGE_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNSUPPORTED_VERSION_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_DH_PRIME_UNACCEPTABLE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET_LENGTH, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INVALID_SESSION, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INTERNAL_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNABLE_SEND_DATA, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_FATAL_ALERT_RECEIVED ,1), GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_BAD_MESSAGE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_MORE_DATA, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_WARNING_ALERT_RECEIVED, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_CERTIFICATE_FOUND, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_TEMPORARY_RSA_PARAMS, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_SCAN_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_PRINT_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_DECRYPTION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ENCRYPTION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PK_DECRYPTION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PK_ENCRYPTION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PK_SIGNATURE_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_DECOMPRESSION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_COMPRESSION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_MEMORY_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INSUFICIENT_CREDENTIALS, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PWD_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PKCS1_WRONG_PAD, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPIRED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_HASH_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PARSING_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_PULL_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPORT_CIPHER_SUITE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_PUSH_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_RECORD_LIMIT_REACHED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_CERTIFICATE_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_UNKNOWN_SAN, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_KEY_USAGE_VIOLATION, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_INTERRUPTED, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_REHANDSHAKE, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_APPLICATION_DATA, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INVALID_PARAMETERS, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INVALID_REQUEST, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ILLEGAL_PARAMETER, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_FILE_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASCII_ARMOR_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_ELEMENT_NOT_FOUND, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_DER_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_VALUE_NOT_FOUND, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_GENERIC_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_VALUE_NOT_VALID, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_TAG_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_TAG_IMPLICIT, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_TYPE_ANY_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_SYNTAX_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_DER_OVERFLOW, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_TOO_MANY_EMPTY_PACKETS, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_INIT_LIBEXTRA, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_LIBRARY_VERSION_MISMATCH, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED, 1), {0} }; #define GNUTLS_ERROR_LOOP(b) \ gnutls_error_entry *p; \ for(p = error_algorithms; p->name != NULL; p++) { b ; } #define GNUTLS_ERROR_ALG_LOOP(a) \ GNUTLS_ERROR_LOOP( if(p->number == error) { a; break; } ) /** * gnutls_error_is_fatal - Returns non-zero in case of a fatal error * @error: is an error returned by a gnutls function. Error should be a negative value. * * If a function returns a negative value you may feed that value * to this function to see if it is fatal. Returns 1 for a fatal * error 0 otherwise. However you may want to check the * error code manualy, since some non-fatal errors to the protocol * may be fatal for you (your program). **/ int gnutls_error_is_fatal(int error) { int ret = 0; GNUTLS_ERROR_ALG_LOOP(ret = p->fatal); return ret; } /** * gnutls_perror - prints a string to stderr with a description of an error * @error: is an error returned by a gnutls function. Error is always a negative value. * * This function is like perror(). The only difference is that it accepts an * error returned by a gnutls function. **/ void gnutls_perror(int error) { char *ret = NULL; /* avoid prefix */ GNUTLS_ERROR_ALG_LOOP(ret = gnutls_strdup(p->name + sizeof("GNUTLS_E_") - 1)); fprintf(stderr, "GNUTLS ERROR: %s\n", ret); gnutls_free( ret); } /** * gnutls_strerror - Returns a string with a description of an error * @error: is an error returned by a gnutls function. Error is always a negative value. * * This function is similar to strerror(). The only difference is that it * accepts an error (number) returned by a gnutls function. **/ const char* gnutls_strerror(int error) { const char *ret = NULL; /* avoid prefix */ GNUTLS_ERROR_ALG_LOOP(ret = p->name + sizeof("GNUTLS_E_") - 1); return ret; } int _gnutls_asn2err( int asn_err) { switch( asn_err) { case ASN1_FILE_NOT_FOUND: return GNUTLS_E_FILE_ERROR; case ASN1_ELEMENT_NOT_FOUND: return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; case ASN1_IDENTIFIER_NOT_FOUND: return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND; case ASN1_DER_ERROR: return GNUTLS_E_ASN1_DER_ERROR; case ASN1_VALUE_NOT_FOUND: return GNUTLS_E_ASN1_VALUE_NOT_FOUND; case ASN1_GENERIC_ERROR: return GNUTLS_E_ASN1_GENERIC_ERROR; case ASN1_VALUE_NOT_VALID: return GNUTLS_E_ASN1_VALUE_NOT_VALID; case ASN1_TAG_ERROR: return GNUTLS_E_ASN1_TAG_ERROR; case ASN1_TAG_IMPLICIT: return GNUTLS_E_ASN1_TAG_IMPLICIT; case ASN1_ERROR_TYPE_ANY: return GNUTLS_E_ASN1_TYPE_ANY_ERROR; case ASN1_SYNTAX_ERROR: return GNUTLS_E_ASN1_SYNTAX_ERROR; case ASN1_MEM_ERROR: return GNUTLS_E_MEMORY_ERROR; case ASN1_DER_OVERFLOW: return GNUTLS_E_ASN1_DER_OVERFLOW; default: return GNUTLS_E_ASN1_GENERIC_ERROR; } } /* this function will output a message using the * caller provided function */ #ifdef DEBUG void _gnutls_log( const char *fmt, ...) { va_list args; char str[MAX_LOG_SIZE]; void (*log_func)(const char*) = _gnutls_log_func; if (_gnutls_log_func==NULL) return; va_start(args,fmt); vsprintf( str,fmt,args); /* Flawfinder: ignore */ va_end(args); log_func( str); return; } #else /* not DEBUG */ # ifndef C99_MACROS /* Without C99 macros these functions have to * be called. This may affect performance. */ void _gnutls_null_log( void* x, ...) { return; } char* GET_CN( gnutls_datum x) { return NULL; } const char* _gnutls_handshake2str( int handshake) { return NULL; } char * _gnutls_bin2hex(const unsigned char *old, const size_t oldlen) { return NULL; } const char* _gnutls_packet2str( int packet) { return NULL; } # endif /* C99_MACROS */ #endif /* DEBUG */