[OpenSSL笔记] ERROR处理

1. 操纵错误队列
每当有ERROR产生,一些重要的信息会被记录下来。一些信息可用于尝试自动恢复错误,但是其中的大多数都是用于调试和向用户报告错误。

有6个API用于从Error队列中获取信息。ERROR是依产生的顺序记录在队列中的,这些函数都能获取到当前队列中最早的信息。

最基本的消息是一个32-bit integer型的Error code。如果Error队列中无任何消息,error处理函数将返回0,0不是一个有效的错误号。

6个获取error信息的API(实质上都是对 get_error_values的包装调用):
// 1. 获取Error code并将其移除队列:
unsigned long ERR_get_error(void)
{ return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }

// 2. 获取Error code但并不将其移除队列:
unsigned long ERR_peek_error(void)
{ return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }

// 3. 获取Error code并将其移除队列,并反回错误产生的源文件(file)及行号(line):
unsigned long ERR_get_error_line(const char **file, int *line)
{ return(get_error_values(1,0,file,line,NULL,NULL)); }

// 4. 获取Error code但不将其移除队列,并反回错误产生的源文件(file)及行号(line):
unsigned long ERR_peek_error_line(const char **file, int *line)
{ return(get_error_values(0,0,file,line,NULL,NULL)); }

// 5. 获取Error code并将其移除队列,并反回错误产生的源文件(file)及行号(line),另提供额外的数据及标识如何处理这些数据的flag:
unsigned long ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags)
{ return(get_error_values(1,0,file,line,data,flags)); }

// 6. 获取Error code但不将其移除队列,并反回错误产生的源文件(file)及行号(line),另提供额外的数据及标识如何处理这些数据的flag:
unsigned long ERR_peek_last_error_line_data(const char **file, int *line, const char **data, int *flags)
{ return(get_error_values(0,1,file,line,data,flags)); }

清空error队列的api:
void ERR_clear_error(void);

5,6所获得的数据可能是任意的,但大多数情况下会是一个字符串。

如flag的ERR_TXT_MALLOCED被置1,则data所使用的内存可以使用OPENSSL_free函数释放。
如flag的ERR_TXT_STRING被置1,则相应的data可以按C-style字串使用。

例:打印error队列

void print_errors(void)
{
    int flags, line;
    char *data, *file;
    unsigned long code;

    code = ERR_get_error_line_data(&file, &line, &data, &flags);
    while(code)
    {
        printf("error code: %lu in %s line %d.\n", code, file, line);
        if(data && (flags & ERR_TXT_STRING))
            printf("error data: %s\n", data);
        code = ERR_get_error_line_data(&file, &line, &data, &flags);
    }
}

2. 人类可读的错误消息

error handling package为其定义的error code提供标准的错误消息,但是在使用前需被载入。

libcrypto和libssl的错误消息全部载入:
void SSL_load_error_strings(void)
        {
#ifndef OPENSSL_NO_ERR
        ERR_load_crypto_strings();
        ERR_load_SSL_strings();
#endif
        }

libcrypto的错误消息的载入:
void ERR_load_crypto_strings(void)
        {
#ifndef OPENSSL_NO_ERR
        ERR_load_ERR_strings(); /* include error strings for SYSerr */
        ERR_load_BN_strings();
#ifndef OPENSSL_NO_RSA
        ERR_load_RSA_strings();
#endif
#ifndef OPENSSL_NO_DH
        ERR_load_DH_strings();
#endif
        ERR_load_EVP_strings();
        ERR_load_BUF_strings();
        ERR_load_OBJ_strings();
        ERR_load_PEM_strings();
#ifndef OPENSSL_NO_DSA
        ERR_load_DSA_strings();
#endif
        ERR_load_X509_strings();
        ERR_load_ASN1_strings();
        ERR_load_CONF_strings();
        ERR_load_CRYPTO_strings();
        ERR_load_COMP_strings();
#ifndef OPENSSL_NO_EC
        ERR_load_EC_strings();
#endif
#ifndef OPENSSL_NO_ECDSA
        ERR_load_ECDSA_strings();
#endif
#ifndef OPENSSL_NO_ECDH
        ERR_load_ECDH_strings();
#endif
        /* skip ERR_load_SSL_strings() because it is not in this library */
        ERR_load_BIO_strings();
        ERR_load_PKCS7_strings();
        ERR_load_X509V3_strings();
        ERR_load_PKCS12_strings();
        ERR_load_RAND_strings();
        ERR_load_DSO_strings();
        ERR_load_TS_strings();
#ifndef OPENSSL_NO_ENGINE
        ERR_load_ENGINE_strings();
#endif
        ERR_load_OCSP_strings();
        ERR_load_UI_strings();
#ifndef OPENSSL_NO_CMS
        ERR_load_CMS_strings();
#endif
#ifndef OPENSSL_NO_JPAKE
        ERR_load_JPAKE_strings();
#endif
        ERR_load_COMP_strings();
#endif
#ifdef OPENSSL_FIPS
        ERR_load_FIPS_strings();
#endif
        }

libssl的错误消息的载入:
void ERR_load_SSL_strings(void)
        {
#ifndef OPENSSL_NO_ERR

        if (ERR_func_error_string(SSL_str_functs[0].error) == NULL)
                {
                ERR_load_strings(0,SSL_str_functs);
                ERR_load_strings(0,SSL_str_reasons);
                }
#endif
        }


一旦error字串被载入就可以使用下面两个API将error code译成相应的error message
char *ERR_error_string(unsigned long e, char *ret)
e - error code
ret - error message(最少256Byte)
void ERR_error_string_n(unsigned long e, char *buf, size_t len)

error message的格式:
error:error code(hex):error name:产生error的函数名:产生error的原因

为了获取error信息,必需使用ERR_get_error_line_data和ERR_error_string,OpenSSL提供了下列API来简化这个过程:

//生成一个error list并将其写入BIO
void ERR_print_errors(BIO *bp)
        {
        ERR_print_errors_cb(print_bio, bp);
        }

//生成一个error list并将其写入一个标准的C FILE对象
void ERR_print_errors_fp(FILE *fp)
        {
        ERR_print_errors_cb(print_fp, fp);
        }

线程级实际应用:

暂略




from:  http://www.douban.com/note/206067603/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值