On Fri, Jan 20, 2023 at 08:06:00PM +0000, Job Snijders wrote:
> While studying why X509_check_ca() is the ugly thing it is, tb@
> suggested x509v3_cache_extensions() might benefit from a wrapper to
> avoid duplication of locking and checking the stupid EXFLAG_INVALID
> flag. x509v3_cache_extensions() isn't a public function anyway.
> 
> Passes regress & rpki-client.
> 
> OK?

Cool, thanks. I think it's better to pull the EXFLAG_SET check into the
new function like beck has done in x509_verify_cert_cache_extensions()
which then becomes a simple wrapper (it's nice to keep the 'namespacing'
clean in x509_verify.c).

Details inline.

> 
> Kind regards,
> 
> Job
> 
> Index: x509/x509_internal.h
> ===================================================================
> RCS file: /cvs/src/lib/libcrypto/x509/x509_internal.h,v
> retrieving revision 1.23
> diff -u -p -r1.23 x509_internal.h
> --- x509/x509_internal.h      26 Nov 2022 16:08:54 -0000      1.23
> +++ x509/x509_internal.h      20 Jan 2023 19:59:56 -0000
> @@ -94,7 +94,8 @@ int x509_vfy_check_policy(X509_STORE_CTX
>  int x509_vfy_check_trust(X509_STORE_CTX *ctx);
>  int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
>  int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx);
> -void x509v3_cache_extensions(X509 *x);
> +void x509v3_cache_extensions_internal(X509 *x);

remove the internal function here.

> +int x509v3_cache_extensions(X509 *x);
>  X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
>  
>  time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter);
> Index: x509/x509_purp.c
> ===================================================================
> RCS file: /cvs/src/lib/libcrypto/x509/x509_purp.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 x509_purp.c
> --- x509/x509_purp.c  26 Nov 2022 16:08:55 -0000      1.18
> +++ x509/x509_purp.c  20 Jan 2023 19:59:57 -0000
> @@ -76,7 +76,8 @@
>  #define ns_reject(x, usage) \
>       (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
>  
> -void x509v3_cache_extensions(X509 *x);
> +void x509v3_cache_extensions_internal(X509 *x);
> +int x509v3_cache_extensions(X509 *x);

drop these two prototypes

>  
>  static int check_ssl_ca(const X509 *x);
>  static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
> @@ -132,12 +133,10 @@ X509_check_purpose(X509 *x, int id, int 
>       const X509_PURPOSE *pt;
>  
>       if (!(x->ex_flags & EXFLAG_SET)) {
> -             CRYPTO_w_lock(CRYPTO_LOCK_X509);
> -             x509v3_cache_extensions(x);
> -             CRYPTO_w_unlock(CRYPTO_LOCK_X509);
> -             if (x->ex_flags & EXFLAG_INVALID)
> +             if (!x509v3_cache_extensions(x))
>                       return -1;
>       }

This becomes

        if (!x509v3_cache_extensions(x))
                return -1;

> +
>       if (id == -1)
>               return 1;
>       idx = X509_PURPOSE_get_by_id(id);
> @@ -450,7 +449,7 @@ setup_crldp(X509 *x)
>  }
>  
>  void

static void

> -x509v3_cache_extensions(X509 *x)
> +x509v3_cache_extensions_internal(X509 *x)
>  {
>       BASIC_CONSTRAINTS *bs;
>       PROXY_CERT_INFO_EXTENSION *pci;
> @@ -640,6 +639,19 @@ x509v3_cache_extensions(X509 *x)
>       x->ex_flags |= EXFLAG_SET;
>  }
>  
> +/*
> + * 1 is success, 0 is failure.
> + */
> +int
> +x509v3_cache_extensions(X509 *x)
> +{

        if ((x->ex_flags & EXFLAG_SET) == 0) {
                CRYPTO_w_lock(CRYPTO_LOCK_X509);
                x509v3_cache_extensions_internal(x);
                CRYPTO_w_unlock(CRYPTO_LOCK_X509);
        }       

> +     CRYPTO_w_lock(CRYPTO_LOCK_X509);
> +     x509v3_cache_extensions_internal(x);
> +     CRYPTO_w_unlock(CRYPTO_LOCK_X509);
> +
> +     return ((x->ex_flags & EXFLAG_INVALID) == 0);

Drop outer parentheses.

> +}
> +
>  /* CA checks common to all purposes
>   * return codes:
>   * 0 not a CA
> @@ -680,11 +692,8 @@ check_ca(const X509 *x)
>  int
>  X509_check_ca(X509 *x)
>  {
> -     if (!(x->ex_flags & EXFLAG_SET)) {
> -             CRYPTO_w_lock(CRYPTO_LOCK_X509);
> +     if (!(x->ex_flags & EXFLAG_SET))
>               x509v3_cache_extensions(x);
> -             CRYPTO_w_unlock(CRYPTO_LOCK_X509);
> -     }

        x509v3_cache_extensions(x)
        
>  
>       return check_ca(x);
>  }
> @@ -896,19 +905,13 @@ X509_check_issued(X509 *issuer, X509 *su
>           X509_get_issuer_name(subject)))
>               return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
>       if (!(issuer->ex_flags & EXFLAG_SET)) {
> -             CRYPTO_w_lock(CRYPTO_LOCK_X509);
> -             x509v3_cache_extensions(issuer);
> -             CRYPTO_w_unlock(CRYPTO_LOCK_X509);
> +             if (!x509v3_cache_extensions(issuer))
> +                     return X509_V_ERR_UNSPECIFIED;
>       }
> -     if (issuer->ex_flags & EXFLAG_INVALID)
> -             return X509_V_ERR_UNSPECIFIED;
>       if (!(subject->ex_flags & EXFLAG_SET)) {
> -             CRYPTO_w_lock(CRYPTO_LOCK_X509);
> -             x509v3_cache_extensions(subject);
> -             CRYPTO_w_unlock(CRYPTO_LOCK_X509);
> +             if (!x509v3_cache_extensions(subject))
> +                     return X509_V_ERR_UNSPECIFIED;
>       }
> -     if (subject->ex_flags & EXFLAG_INVALID)
> -             return X509_V_ERR_UNSPECIFIED;

The entire hunk above becomes

        if (!x509v3_cache_extensions(issuer))
                return X509_V_ERR_UNSPECIFIED;
        if (!x509v3_cache_extensions(subject))
                return X509_V_ERR_UNSPECIFIED;

>  
>       if (subject->akid) {
>               int ret = X509_check_akid(issuer, subject->akid);
> Index: x509/x509_verify.c
> ===================================================================
> RCS file: /cvs/src/lib/libcrypto/x509/x509_verify.c,v
> retrieving revision 1.62
> diff -u -p -r1.62 x509_verify.c
> --- x509/x509_verify.c        17 Jan 2023 23:49:28 -0000      1.62
> +++ x509/x509_verify.c        20 Jan 2023 19:59:57 -0000
> @@ -242,12 +242,9 @@ static int
>  x509_verify_cert_cache_extensions(X509 *cert)
>  {

        return x509v3_cache_extensions(cert);

>       if (!(cert->ex_flags & EXFLAG_SET)) {
> -             CRYPTO_w_lock(CRYPTO_LOCK_X509);
> -             x509v3_cache_extensions(cert);
> -             CRYPTO_w_unlock(CRYPTO_LOCK_X509);
> +             if (!x509v3_cache_extensions(cert))
> +                     return 0;
>       }
> -     if (cert->ex_flags & EXFLAG_INVALID)
> -             return 0;
>  
>       return (cert->ex_flags & EXFLAG_SET);
>  }
> 

Reply via email to