On Tue, Jan 18, 2022 at 12:16:44PM +0100, Claudio Jeker wrote:
> How X509_verify_cert() is called in rpki-client is mostly the same in all
> places so move all this X509 boilerplate into valid_x509().
> 
> This simplifies the x509 validation in the parser a fair but and will also
> make it easier for -f to validate certs.
> 
> OK?

ok

I would suggest we merge the three if (crl != NULL) checks into one
(maybe in a follow-up).

The _roa and _gbr paths called the warnx() with the
X509_verify_cert_error_string() only conditionally. I guess we can
adjust that later if this turns out to be too noisy.


> -- 
> :wq Claudio
> 
> Index: parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 parser.c
> --- parser.c  14 Jan 2022 15:00:23 -0000      1.37
> +++ parser.c  18 Jan 2022 11:01:45 -0000
> @@ -200,52 +200,74 @@ verify_cb(int ok, X509_STORE_CTX *store_
>  }
>  
>  /*
> - * Parse and validate a ROA.
> - * This is standard stuff.
> - * Returns the roa on success, NULL on failure.
> + * Validate the X509 certificate.  If crl is NULL don't check CRL.
> + * Returns 1 for valid certificates, returns 0 if there is a verify error
>   */
> -static struct roa *
> -proc_parser_roa(char *file, const unsigned char *der, size_t len)
> +static int
> +valid_x509(char *file, X509 *x509, struct auth *a, struct crl *crl)
>  {
> -     struct roa              *roa;
> -     X509                    *x509;
> -     int                      c;
> -     struct auth             *a;
>       STACK_OF(X509)          *chain;
> -     STACK_OF(X509_CRL)      *crls;
> -     struct crl              *crl;
> -
> -     if ((roa = roa_parse(&x509, file, der, len)) == NULL)
> -             return NULL;
> +     STACK_OF(X509_CRL)      *crls = NULL;
> +     int                      c;
>  
> -     a = valid_ski_aki(file, &auths, roa->ski, roa->aki);
>       build_chain(a, &chain);
> -     crl = get_crl(a);
> -     build_crls(crl, &crls);
> +     if (crl != NULL)
> +             build_crls(crl, &crls);
>  
>       assert(x509 != NULL);
>       if (!X509_STORE_CTX_init(ctx, NULL, x509, NULL))
>               cryptoerrx("X509_STORE_CTX_init");
> +
>       X509_STORE_CTX_set_verify_cb(ctx, verify_cb);
>       if (!X509_STORE_CTX_set_app_data(ctx, file))
>               cryptoerrx("X509_STORE_CTX_set_app_data");
> -     X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
> +     if (crl != NULL)
> +             X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
>       X509_STORE_CTX_set_depth(ctx, MAX_CERT_DEPTH);
>       X509_STORE_CTX_set0_trusted_stack(ctx, chain);
> -     X509_STORE_CTX_set0_crls(ctx, crls);
> +     if (crl != NULL)
> +             X509_STORE_CTX_set0_crls(ctx, crls);
>  
>       if (X509_verify_cert(ctx) <= 0) {
>               c = X509_STORE_CTX_get_error(ctx);
> +             warnx("%s: %s", file, X509_verify_cert_error_string(c));
>               X509_STORE_CTX_cleanup(ctx);
> -             if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL)
> -                     warnx("%s: %s", file, X509_verify_cert_error_string(c));
> -             X509_free(x509);
> -             roa_free(roa);
>               sk_X509_free(chain);
>               sk_X509_CRL_free(crls);
> -             return NULL;
> +             return 0;
>       }
> +
>       X509_STORE_CTX_cleanup(ctx);
> +     sk_X509_free(chain);
> +     sk_X509_CRL_free(crls);
> +     return 1;
> +}
> +
> +/*
> + * Parse and validate a ROA.
> + * This is standard stuff.
> + * Returns the roa on success, NULL on failure.
> + */
> +static struct roa *
> +proc_parser_roa(char *file, const unsigned char *der, size_t len)
> +{
> +     struct roa              *roa;
> +     struct crl              *crl;
> +     struct auth             *a;
> +     X509                    *x509;
> +
> +     if ((roa = roa_parse(&x509, file, der, len)) == NULL)
> +             return NULL;
> +
> +     a = valid_ski_aki(file, &auths, roa->ski, roa->aki);
> +     crl = get_crl(a);
> +
> +     if (!valid_x509(file, x509, a, crl)) {
> +             X509_free(x509);
> +             roa_free(roa);
> +             return NULL;
> +     }
> +     X509_free(x509);
>  
>       /*
>        * Check CRL to figure out the soonest transitive expiry moment
> @@ -270,10 +292,6 @@ proc_parser_roa(char *file, const unsign
>       if (valid_roa(file, &auths, roa))
>               roa->valid = 1;
>  
> -     sk_X509_free(chain);
> -     sk_X509_CRL_free(crls);
> -     X509_free(x509);
> -
>       return roa;
>  }
>  
> @@ -336,38 +354,18 @@ proc_parser_mft(char *file, const unsign
>  {
>       struct mft              *mft;
>       X509                    *x509;
> -     int                      c;
>       struct auth             *a;
> -     STACK_OF(X509)          *chain;
>  
>       if ((mft = mft_parse(&x509, file, der, len)) == NULL)
>               return NULL;
>  
>       a = valid_ski_aki(file, &auths, mft->ski, mft->aki);
> -     build_chain(a, &chain);
>  
> -     if (!X509_STORE_CTX_init(ctx, NULL, x509, NULL))
> -             cryptoerrx("X509_STORE_CTX_init");
> -
> -     /* CRL checks disabled here because CRL is referenced from mft */
> -     X509_STORE_CTX_set_verify_cb(ctx, verify_cb);
> -     if (!X509_STORE_CTX_set_app_data(ctx, file))
> -             cryptoerrx("X509_STORE_CTX_set_app_data");
> -     X509_STORE_CTX_set_depth(ctx, MAX_CERT_DEPTH);
> -     X509_STORE_CTX_set0_trusted_stack(ctx, chain);
> -
> -     if (X509_verify_cert(ctx) <= 0) {
> -             c = X509_STORE_CTX_get_error(ctx);
> -             X509_STORE_CTX_cleanup(ctx);
> -             warnx("%s: %s", file, X509_verify_cert_error_string(c));
> +     if (!valid_x509(file, x509, a, NULL)) {
>               mft_free(mft);
>               X509_free(x509);
> -             sk_X509_free(chain);
>               return NULL;
>       }
> -
> -     X509_STORE_CTX_cleanup(ctx);
> -     sk_X509_free(chain);
>       X509_free(x509);
>  
>       mft->repoid = repoid;
> @@ -396,10 +394,8 @@ proc_parser_cert(char *file, const unsig
>  {
>       struct cert             *cert;
>       X509                    *x509;
> -     int                      c;
> -     struct auth             *a = NULL;
> -     STACK_OF(X509)          *chain;
> -     STACK_OF(X509_CRL)      *crls;
> +     struct auth             *a;
> +     struct crl              *crl;
>  
>       /* Extract certificate data and X509. */
>  
> @@ -408,35 +404,13 @@ proc_parser_cert(char *file, const unsig
>               return NULL;
>  
>       a = valid_ski_aki(file, &auths, cert->ski, cert->aki);
> -     build_chain(a, &chain);
> -     build_crls(get_crl(a), &crls);
> -
> -     assert(x509 != NULL);
> -     if (!X509_STORE_CTX_init(ctx, NULL, x509, NULL))
> -             cryptoerrx("X509_STORE_CTX_init");
> -
> -     X509_STORE_CTX_set_verify_cb(ctx, verify_cb);
> -     if (!X509_STORE_CTX_set_app_data(ctx, file))
> -             cryptoerrx("X509_STORE_CTX_set_app_data");
> -     X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
> -     X509_STORE_CTX_set_depth(ctx, MAX_CERT_DEPTH);
> -     X509_STORE_CTX_set0_trusted_stack(ctx, chain);
> -     X509_STORE_CTX_set0_crls(ctx, crls);
> +     crl = get_crl(a);
>  
> -     if (X509_verify_cert(ctx) <= 0) {
> -             c = X509_STORE_CTX_get_error(ctx);
> -             warnx("%s: %s", file, X509_verify_cert_error_string(c));
> -             X509_STORE_CTX_cleanup(ctx);
> +     if (!valid_x509(file, x509, a, crl)) {
>               cert_free(cert);
> -             sk_X509_free(chain);
> -             sk_X509_CRL_free(crls);
>               X509_free(x509);
>               return NULL;
>       }
> -
> -     X509_STORE_CTX_cleanup(ctx);
> -     sk_X509_free(chain);
> -     sk_X509_CRL_free(crls);
>       X509_free(x509);
>  
>       cert->talid = a->cert->talid;
> @@ -597,39 +571,18 @@ proc_parser_gbr(char *file, const unsign
>  {
>       struct gbr              *gbr;
>       X509                    *x509;
> -     int                      c;
>       struct auth             *a;
> -     STACK_OF(X509)          *chain;
> -     STACK_OF(X509_CRL)      *crls;
> +     struct crl              *crl;
>  
>       if ((gbr = gbr_parse(&x509, file, der, len)) == NULL)
>               return;
>  
>       a = valid_ski_aki(file, &auths, gbr->ski, gbr->aki);
> +     crl = get_crl(a);
>  
> -     build_chain(a, &chain);
> -     build_crls(get_crl(a), &crls);
> -
> -     assert(x509 != NULL);
> -     if (!X509_STORE_CTX_init(ctx, NULL, x509, NULL))
> -             cryptoerrx("X509_STORE_CTX_init");
> -     X509_STORE_CTX_set_verify_cb(ctx, verify_cb);
> -     if (!X509_STORE_CTX_set_app_data(ctx, file))
> -             cryptoerrx("X509_STORE_CTX_set_app_data");
> -     X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
> -     X509_STORE_CTX_set_depth(ctx, MAX_CERT_DEPTH);
> -     X509_STORE_CTX_set0_trusted_stack(ctx, chain);
> -     X509_STORE_CTX_set0_crls(ctx, crls);
> -
> -     if (X509_verify_cert(ctx) <= 0) {
> -             c = X509_STORE_CTX_get_error(ctx);
> -             if (verbose > 0 || c != X509_V_ERR_UNABLE_TO_GET_CRL)
> -                     warnx("%s: %s", file, X509_verify_cert_error_string(c));
> -     }
> +     /* return value can be ignored since nothing happens here */
> +     valid_x509(file, x509, a, crl);
>  
> -     X509_STORE_CTX_cleanup(ctx);
> -     sk_X509_free(chain);
> -     sk_X509_CRL_free(crls);
>       X509_free(x509);
>       gbr_free(gbr);
>  }
> 

Reply via email to