From 1771668096efcfe987acc0216035e7e22f7a8625 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 2 Sep 2009 12:47:28 +0000 Subject: [PATCH] Tidy up and fix verify callbacks to avoid structure dereference, use of obsolete functions and enhance to handle new conditions such as policy printing. --- CHANGES | 5 ++++ apps/s_cb.c | 30 +++++++++++++++++------- apps/verify.c | 63 ++++++++++++++++++++++++++++----------------------- 3 files changed, 62 insertions(+), 36 deletions(-) diff --git a/CHANGES b/CHANGES index fe98cddc69..d43e499aed 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,11 @@ Changes between 0.9.8k and 1.0 [xx XXX xxxx] + *) Update verify callback code in apps/s_cb.c and apps/verify.c, it + needlessly dereferenced structures, used obsolete functions and + didn't handle all updated verify codes correctly. + [Steve Henson] + *) Delete MD2 from algorithm tables. This follows the recommendation in several standards that it is not used in new applications due to several cryptographic weaknesses. The algorithm is also disabled in diff --git a/apps/s_cb.c b/apps/s_cb.c index 3fc73a27aa..4d8a662988 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -127,7 +127,6 @@ int verify_return_error=0; int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) { - char buf[256]; X509 *err_cert; int err,depth; @@ -135,8 +134,15 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) err= X509_STORE_CTX_get_error(ctx); depth= X509_STORE_CTX_get_error_depth(ctx); - X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf); - BIO_printf(bio_err,"depth=%d %s\n",depth,buf); + BIO_printf(bio_err,"depth=%d ",depth); + if (err_cert) + { + X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); + } + else + BIO_puts(bio_err, "\n"); if (!ok) { BIO_printf(bio_err,"verify error:num=%d:%s\n",err, @@ -153,25 +159,33 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; } } - switch (ctx->error) + switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf); - BIO_printf(bio_err,"issuer= %s\n",buf); + BIO_puts(bio_err,"issuer= "); + X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: BIO_printf(bio_err,"notBefore="); - ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert)); + ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); BIO_printf(bio_err,"\n"); break; case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: BIO_printf(bio_err,"notAfter="); - ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert)); + ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); BIO_printf(bio_err,"\n"); break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(bio_err, ctx); + break; } + if (err == X509_V_OK && ok == 2) + policies_print(bio_err, ctx); + BIO_printf(bio_err,"verify return:%d\n",ok); return(ok); } diff --git a/apps/verify.c b/apps/verify.c index 20cc9e354c..838ac46827 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -326,42 +326,49 @@ end: static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx) { - char buf[256]; + int cert_error = X509_STORE_CTX_get_error(ctx); + X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); if (!ok) { - if (ctx->current_cert) + if (current_cert) { - X509_NAME_oneline( - X509_get_subject_name(ctx->current_cert),buf, - sizeof buf); - printf("%s\n",buf); + X509_NAME_print_ex_fp(stdout, + X509_get_subject_name(current_cert), + 0, XN_FLAG_ONELINE); + printf("\n"); } - printf("error %d at %d depth lookup:%s\n",ctx->error, - ctx->error_depth, - X509_verify_cert_error_string(ctx->error)); - if (ctx->error == X509_V_ERR_CERT_HAS_EXPIRED) ok=1; - /* since we are just checking the certificates, it is - * ok if they are self signed. But we should still warn - * the user. - */ - if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1; - /* Continue after extension errors too */ - if (ctx->error == X509_V_ERR_INVALID_CA) ok=1; - if (ctx->error == X509_V_ERR_INVALID_NON_CA) ok=1; - if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1; - if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1; - if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1; - if (ctx->error == X509_V_ERR_CRL_HAS_EXPIRED) ok=1; - if (ctx->error == X509_V_ERR_CRL_NOT_YET_VALID) ok=1; - if (ctx->error == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) ok=1; - - if (ctx->error == X509_V_ERR_NO_EXPLICIT_POLICY) - policies_print(NULL, ctx); + printf("error %d at %d depth lookup:%s\n",cert_error, + X509_STORE_CTX_get_error_depth(ctx), + X509_verify_cert_error_string(cert_error)); + switch(cert_error) + { + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(NULL, ctx); + case X509_V_ERR_CERT_HAS_EXPIRED: + + /* since we are just checking the certificates, it is + * ok if they are self signed. But we should still warn + * the user. + */ + + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + /* Continue after extension errors too */ + case X509_V_ERR_INVALID_CA: + case X509_V_ERR_INVALID_NON_CA: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_PURPOSE: + case X509_V_ERR_CRL_HAS_EXPIRED: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + ok = 1; + + } + return ok; } - if ((ctx->error == X509_V_OK) && (ok == 2)) + if (cert_error == X509_V_OK && ok == 2) policies_print(NULL, ctx); if (!v_verbose) ERR_clear_error(); -- 2.34.1