On Sat, Jan 22, 2022 at 07:08:12PM +0100, Claudio Jeker wrote:
> On Sat, Jan 22, 2022 at 02:21:23PM +0100, Theo Buehler wrote:
> > On Sat, Jan 22, 2022 at 12:42:30PM +0100, Theo Buehler wrote:
> > > On Sat, Jan 22, 2022 at 11:47:17AM +0100, Claudio Jeker wrote:
> > > > The valid_cert() and valid_roa() functions both redo the valid_aki_ski()
> > > > call that the callee already did. Adjust the functions and skip this
> > > > redundant call. Also move the place where we set the talid for roa to a
> > > > better place.
> > > > 
> > > > With RFC3779 support in LibreSSL these functions no longer trigger since
> > > > the range checks for IP and ASnums happen in X509_verify_cert().
> > > > The fucntions are still needed for libcrypto libs compiled without 
> > > > RFC3779
> > > > support. Also they print a less generic error message and change the 
> > > > stats
> > > > from failed parse to invalid (in case of roas).
> > > > 
> > > > Lets start with this diff and then see how error reporting could be
> > > > improved.
> > > 
> > > I'm fine with this in principle, but I have one question.
> > > 
> > > > -- 
> > > > :wq Claudio
> > > > 
> > > > Index: extern.h
> > > > ===================================================================
> > > > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> > > > retrieving revision 1.112
> > > > diff -u -p -r1.112 extern.h
> > > > --- extern.h    22 Jan 2022 09:18:48 -0000      1.112
> > > > +++ extern.h    22 Jan 2022 10:33:45 -0000
> > > > @@ -446,9 +446,8 @@ struct auth *valid_ski_aki(const char *,
> > > >                     const char *, const char *);
> > > >  int             valid_ta(const char *, struct auth_tree *,
> > > >                     const struct cert *);
> > > > -int             valid_cert(const char *, struct auth_tree *,
> > > > -                   const struct cert *);
> > > > -int             valid_roa(const char *, struct auth_tree *, struct roa 
> > > > *);
> > > > +int             valid_cert(const char *, struct auth *, const struct 
> > > > cert *);
> > > > +int             valid_roa(const char *, struct auth *, struct roa *);
> > > >  int             valid_filehash(int, const char *, size_t);
> > > >  int             valid_uri(const char *, size_t, const char *);
> > > >  int             valid_origin(const char *, const char *);
> > > > Index: parser.c
> > > > ===================================================================
> > > > RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> > > > retrieving revision 1.50
> > > > diff -u -p -r1.50 parser.c
> > > > --- parser.c    22 Jan 2022 09:18:48 -0000      1.50
> > > > +++ parser.c    22 Jan 2022 10:36:43 -0000
> > > > @@ -268,6 +268,8 @@ proc_parser_roa(char *file, const unsign
> > > >         }
> > > >         X509_free(x509);
> > > >  
> > > > +       roa->talid = a->cert->talid;
> > > 
> > > Previously there was a NULL check for a before doing this. As far as I
> > > can tell, we can now get here with a == NULL. This also makes me wonder
> > > if we should keep the NULL check for a in valid_roa() and valid_cert()
> > > and do this assignment only after a successful call to valid_roa().
> 
> We can't really end up here with a == NULL because valid_x509() above will
> fail for a == NULL (X509_verify_cert() with a empty trusted stack will
> fail. Now maybe that is a bit too indirect but we depend on the same fact
> in proc_parser_cert_validate().

Ah, that's what I was missing. I don't think it's too indirect. I should
have seen that. Thanks.

> > > > +
> > > >         /*
> > > >          * Check CRL to figure out the soonest transitive expiry moment
> > > >          */
> > > > @@ -288,7 +290,7 @@ proc_parser_roa(char *file, const unsign
> > > >          * the code around roa_read() to check the "valid" field itself.
> > > >          */
> > > >  
> > > > -       if (valid_roa(file, &auths, roa))
> > > > +       if (valid_roa(file, a, roa))
> > 
> > There is a second issue: a is not the return value of valid_ski_aki()
> > here, but rather the auth struct of the trust anchor due to the for loop
> > before this call.
> 
> This is indeed a good point. I moved the code up, so we do the valid_roa()
> check before figuring out the expire time.
>  
> Adjusted diff below

ok

> -- 
> :wq Claudio
> 
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.112
> diff -u -p -r1.112 extern.h
> --- extern.h  22 Jan 2022 09:18:48 -0000      1.112
> +++ extern.h  22 Jan 2022 10:33:45 -0000
> @@ -446,9 +446,8 @@ struct auth       *valid_ski_aki(const char *,
>                   const char *, const char *);
>  int           valid_ta(const char *, struct auth_tree *,
>                   const struct cert *);
> -int           valid_cert(const char *, struct auth_tree *,
> -                 const struct cert *);
> -int           valid_roa(const char *, struct auth_tree *, struct roa *);
> +int           valid_cert(const char *, struct auth *, const struct cert *);
> +int           valid_roa(const char *, struct auth *, struct roa *);
>  int           valid_filehash(int, const char *, size_t);
>  int           valid_uri(const char *, size_t, const char *);
>  int           valid_origin(const char *, const char *);
> Index: parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> retrieving revision 1.50
> diff -u -p -r1.50 parser.c
> --- parser.c  22 Jan 2022 09:18:48 -0000      1.50
> +++ parser.c  22 Jan 2022 18:00:01 -0000
> @@ -268,6 +268,16 @@ proc_parser_roa(char *file, const unsign
>       }
>       X509_free(x509);
>  
> +     roa->talid = a->cert->talid;
> +
> +     /*
> +      * If the ROA isn't valid, we accept it anyway and depend upon
> +      * the code around roa_read() to check the "valid" field itself.
> +      */
> +
> +     if (valid_roa(file, a, roa))
> +             roa->valid = 1;
> +
>       /*
>        * Check CRL to figure out the soonest transitive expiry moment
>        */
> @@ -283,14 +293,6 @@ proc_parser_roa(char *file, const unsign
>                       roa->expires = a->cert->expires;
>       }
>  
> -     /*
> -      * If the ROA isn't valid, we accept it anyway and depend upon
> -      * the code around roa_read() to check the "valid" field itself.
> -      */
> -
> -     if (valid_roa(file, &auths, roa))
> -             roa->valid = 1;
> -
>       return roa;
>  }
>  
> @@ -401,8 +403,8 @@ proc_parser_cert_validate(char *file, st
>  
>       cert->talid = a->cert->talid;
>  
> -     /* Validate the cert to get the parent */
> -     if (!valid_cert(file, &auths, cert)) {
> +     /* Validate the cert */
> +     if (!valid_cert(file, a, cert)) {
>               cert_free(cert);
>               return NULL;
>       }
> Index: validate.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 validate.c
> --- validate.c        22 Jan 2022 09:18:48 -0000      1.26
> +++ validate.c        22 Jan 2022 10:34:31 -0000
> @@ -143,17 +143,12 @@ valid_ta(const char *fn, struct auth_tre
>   * Returns 1 if valid, 0 otherwise.
>   */
>  int
> -valid_cert(const char *fn, struct auth_tree *auths, const struct cert *cert)
> +valid_cert(const char *fn, struct auth *a, const struct cert *cert)
>  {
> -     struct auth     *a;
>       size_t           i;
>       uint32_t         min, max;
>       char             buf1[64], buf2[64];
>  
> -     a = valid_ski_aki(fn, auths, cert->ski, cert->aki);
> -     if (a == NULL)
> -             return 0;
> -
>       for (i = 0; i < cert->asz; i++) {
>               if (cert->as[i].type == CERT_AS_INHERIT) {
>                       if (cert->purpose == CERT_PURPOSE_BGPSEC_ROUTER)
> @@ -207,17 +202,11 @@ valid_cert(const char *fn, struct auth_t
>   * Returns 1 if valid, 0 otherwise.
>   */
>  int
> -valid_roa(const char *fn, struct auth_tree *auths, struct roa *roa)
> +valid_roa(const char *fn, struct auth *a, struct roa *roa)
>  {
> -     struct auth     *a;
>       size_t   i;
>       char     buf[64];
>  
> -     a = valid_ski_aki(fn, auths, roa->ski, roa->aki);
> -     if (a == NULL)
> -             return 0;
> -
> -     roa->talid = a->cert->talid;
>  
>       for (i = 0; i < roa->ipsz; i++) {
>               if (valid_ip(a, roa->ips[i].afi, roa->ips[i].min,

Reply via email to