On Wed, Jan 19, 2022 at 02:57:44PM +0100, Claudio Jeker wrote:
> > > +         return;
> > > + }
> > > +
> > > + /* TA found play back the stack and add all certs */
> > > + do {
> > > +         if (parser_cert_validate(nfile, cert) == NULL)
> > > +                 break;
> > 
> > I think this also needs a cert_free(cert).
> 
> Certs are special and never released once valid. The are added to the
> auths tree. If parser_cert_validate() fails then cert is already freed so
> that should also be fine.

Indeed. I got it now.

>  
> > > +         free(nfile);
> > > +         cert = stack[stacksz - 1];
> > > +         nfile = filestack[stacksz - 1];
> > 
> > I'm probably missing something, but I don't see why we don't hit this
> > in the last iteration where stacksz == 0 (which would be bad).
> > 
> > > + } while (stacksz-- > 0);
> > 
> > It's probably related to my above confusion: We don't need to free cert
> > if parser_cert_validate() fails but do need to free it if we exit the
> > while loop because stacksz == 0.
> 
> Yeah, I'm also confused. I think the code currently underflows the stack
> which seems to result in a NULL cert.
>  
> Anyway I totally rewrote that bit without recursion. Have a look below.
> Only think I dislike is the fact that parse_load_certchain() is using the
> URI instead of the filename (but should be easy enough to convert between
> the two).

This is much clearer to me and I like the non-recursive version better.

ok tb

Some tiny nits for your consideration. Apart from the %i do as you
prefer :)

> Index: parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 parser.c
> --- parser.c  18 Jan 2022 18:19:47 -0000      1.44
> +++ parser.c  19 Jan 2022 13:54:06 -0000
> @@ -383,24 +383,13 @@ proc_parser_mft(char *file, const unsign
>  }
>  
>  /*
> - * Certificates are from manifests (has a digest and is signed with
> - * another certificate) Parse the certificate, make sure its
> - * signatures are valid (with CRLs), then validate the RPKI content.
> - * This returns a certificate (which must not be freed) or NULL on
> - * parse failure.
> + * Validate a certificate, if invalid free the resouces and return NULL.
>   */
>  static struct cert *
> -proc_parser_cert(char *file, const unsigned char *der, size_t len)
> +parser_cert_validate(char *file, struct cert *cert)

This is the only function with a parser_ prefix.
Should this be proc_parser_cert_validate()?
(parse_cert_validate would be a bad name).

[...]

> +/*
> + * Build the certificate chain by using the Authority Information Access.
> + * This requires that the TA are already validated and added to the auths
> + * tree. Once the TA is located in the chain the chain is validated in
> + * reverse order.
> + */
> +static void
> +parse_load_certchain(char *uri)
> +{
> +     struct cert *stack[MAX_CERT_DEPTH];
> +     char *filestack[MAX_CERT_DEPTH];
> +     struct cert *cert;
> +     int i, failed;
> +
> +     for (i = 0; i < MAX_CERT_DEPTH; i++) {
> +             cert = parse_load_cert(uri);
> +             if (cert == NULL) {
> +                     warnx("failed to build authority chain");
> +                     return;
> +             }
> +             stack[i] = cert;
> +             filestack[i] = uri;
> +             if (auth_find(&auths, cert->aki) != NULL) {

no need for braces

> +                     break;  /* found the TA */
> +             }
> +             uri = cert->aia;
> +     }
> +
> +     if (i >= MAX_CERT_DEPTH) {
> +             warnx("authority chain exceeds max depth of %i",

use %d instead of %i

> +                 MAX_CERT_DEPTH);
> +             for (i = 0; i < MAX_CERT_DEPTH; i++) {

no need for braces

> +                     cert_free(stack[i]);
> +             }
> +             return;
> +     }

Reply via email to