diff --git a/src/x509.c b/src/x509.c index f2a3eba..349832a 100644 --- a/src/x509.c +++ b/src/x509.c @@ -144,6 +144,82 @@ finish: return; } +int x509_get_last_ca(const char *file, X509 *cx509) +{ + int last = 0; + X509 *x = NULL; + BIO *bio = NULL; + + if ((bio = BIO_new(BIO_s_file())) == NULL) + { + goto finish; + } + if (BIO_read_filename(bio, file) <= 0) + { + goto finish; + } + while(NULL!=(x=PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL))) + { + if (0 == X509_NAME_cmp(X509_get_issuer_name(x), X509_get_subject_name(cx509))) + { + last = 1; + X509_free(x); + break; + }; + X509_free(x); + } + BIO_free (bio); +finish: + return last; +} + +X509* x509_get_root_ca(const char *file, STACK_OF(X509) **stack_ca) +{ + int x509_cnt = 0; + X509 *x = NULL, *end = NULL; + BIO *bio = NULL; + STACK_OF(X509) *stack_x509 = NULL; + + if ((bio = BIO_new(BIO_s_file())) == NULL) + { + goto finish; + } + if (BIO_read_filename(bio, file) <= 0) + { + goto finish; + } + if ((stack_x509 = sk_X509_new_null()) == NULL) + { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto finish; + } + + while(NULL!=(x=PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL))) + { + if (0 == X509_NAME_cmp(X509_get_issuer_name(x), X509_get_subject_name(x))) + { + /*This is root ca**/ + continue; + X509_free(x); + }; + /*This is last ca*/ + if (x509_get_last_ca(file, x) == 0) + { + end = x; + continue; + } + sk_X509_push(stack_x509, x); + x509_cnt++; + X509_free(x); + } + if (x509_cnt >= 1) + *stack_ca = stack_x509; + + BIO_free (bio); +finish: + return end; +} + static X509 * cert_base_load_x509 (BIO * in_bio, STACK_OF(X509) **stack_ca, int iFormat) { @@ -780,12 +856,11 @@ x509_parse_check(char *cafile, char *keyfile) X509 *x509 = NULL; STACK_OF(X509) *stack_ca = NULL; - - x509 = cert_load_x509(cafile, &informat, &stack_ca); + x509 = x509_get_root_ca(cafile, &stack_ca); if (!x509){ printf("unable to load certificate\n"); goto finish; - } + } if (!X509_check_private_key(x509, pkey)) { printf("Matching failure\n"); }else{