Moving to openssl-dev now that I think I've found the answers...

On Sun, 2009-05-31 at 10:13 +0100, David Woodhouse wrote:
> I found another strange behaviour that I didn't expect -- the _order_ of
> the certificates in the cafile seems to be important. My original
> scripts which interact with the company's internal PKI infrastructure
> would download a bunch of certificates separately and I would shove them
> all in a single file with a command line like:
>    for a in *.crt ; do cat $a ; echo > company-certchain.crt

The intermediate CAs have been replaced recently. And the new ones have
the same names as the old ones.

> The resulting file would work, and allow me to connect to the server.
> 
> So I modified the scripts to create one big file just the same... except
> that they'd be stored in the order that they were downloaded, instead of
> alphabetical order by filename as the above shell command gave me. And
> _that_ cafile doesn't work; I still get summarily disconnected.
> 
> Does ordering in trustchain files matter? 

It shouldn't, but yes it does -- because sometimes there are _two_
certificates with the same name in the trust chain file, and
ssl3_output_cert_chain() makes no effort to ensure that it has the
_right_ one. Despite the existence of a helpful
X509_STORE_CTX_get1_issuer() function which would have got it right.

> If so, how do I ensure I get the right order?

Like this... 

Index: ssl/d1_both.c
===================================================================
RCS file: /home/dwmw2/openssl-cvs/openssl/ssl/d1_both.c,v
retrieving revision 1.4.2.9
diff -u -p -r1.4.2.9 d1_both.c
--- ssl/d1_both.c       2 Apr 2009 22:32:15 -0000       1.4.2.9
+++ ssl/d1_both.c       31 May 2009 17:55:41 -0000
@@ -808,7 +808,6 @@ unsigned long dtls1_output_cert_chain(SS
        unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
        BUF_MEM *buf;
        X509_STORE_CTX xs_ctx;
-       X509_OBJECT obj;
 
        /* TLSv1 sends a chain with nothing in it, instead of an alert */
        buf=s->init_buf;
@@ -827,6 +826,7 @@ unsigned long dtls1_output_cert_chain(SS
 
                for (;;)
                        {
+                       X509 *issuer;
                        n=i2d_X509(x,NULL);
                        if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
                                {
@@ -837,16 +837,18 @@ unsigned long dtls1_output_cert_chain(SS
                        l2n3(n,p);
                        i2d_X509(x,&p);
                        l+=n+3;
-                       if (X509_NAME_cmp(X509_get_subject_name(x),
-                               X509_get_issuer_name(x)) == 0) break;
 
-                       i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
-                               X509_get_issuer_name(x),&obj);
+                       /* self-signed */
+                       if (xs_ctx.check_issued(&xs_ctx, x, x))
+                               break;
+
+                       i=X509_STORE_CTX_get1_issuer(&issuer, &xs_ctx, x);
                        if (i <= 0) break;
-                       x=obj.data.x509;
+
                        /* Count is one too high since the X509_STORE_get uped 
the
                         * ref count */
                        X509_free(x);
+                       x = issuer;
                        }
 
                X509_STORE_CTX_cleanup(&xs_ctx);
Index: ssl/s3_both.c
===================================================================
RCS file: /home/dwmw2/openssl-cvs/openssl/ssl/s3_both.c,v
retrieving revision 1.43
diff -u -p -r1.43 s3_both.c
--- ssl/s3_both.c       26 Apr 2005 16:02:39 -0000      1.43
+++ ssl/s3_both.c       31 May 2009 17:51:31 -0000
@@ -271,8 +271,6 @@ unsigned long ssl3_output_cert_chain(SSL
        unsigned long l=7;
        BUF_MEM *buf;
        X509_STORE_CTX xs_ctx;
-       X509_OBJECT obj;
-
        int no_chain;
 
        if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
@@ -297,6 +295,7 @@ unsigned long ssl3_output_cert_chain(SSL
 
                for (;;)
                        {
+                       X509 *issuer;
                        n=i2d_X509(x,NULL);
                        if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
                                {
@@ -311,16 +310,17 @@ unsigned long ssl3_output_cert_chain(SSL
                        if (no_chain)
                                break;
 
-                       if (X509_NAME_cmp(X509_get_subject_name(x),
-                               X509_get_issuer_name(x)) == 0) break;
+                       /* self-signed */
+                       if (xs_ctx.check_issued(&xs_ctx, x, x))
+                               break;
 
-                       i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
-                               X509_get_issuer_name(x),&obj);
+                       i=X509_STORE_CTX_get1_issuer(&issuer, &xs_ctx, x);
                        if (i <= 0) break;
-                       x=obj.data.x509;
+
                        /* Count is one too high since the X509_STORE_get uped 
the
                         * ref count */
                        X509_free(x);
+                       x = issuer;
                        }
                if (!no_chain)
                        X509_STORE_CTX_cleanup(&xs_ctx);

-- 
dwmw2

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to