I'm having trouble figuring out how to get a CRL I created working. I'll start 
from the beginning, apologies for length.
First, I created my own CA with OpenSSL (1.0.1h) on my server machine, 
consisting of 3 certificates:  root -> serverCA -> serverI successfully opened 
connections from my client to the server after installing the root certificate 
on my client machine, so I believe the CA I set up is working properly.
Then I attempted to create a CRL revoking the server cert with the following 
commands:
openssl ca -config openssl.cnf -revoke server.pem -keyfile rootkey.pem -cert 
root.pem
openssl ca -config openssl.cnf -keyfile rootkey.pem -cert root.pem -gencrl -out 
crl.pem
I also had to set up the crlnumber file and the index.txt file to get these 
commands to work. Later on, since I didn't know if revoking server with root 
would work properly, I also did the same commands to revoke serverCA. I did 
find that revoking server with root may not work, and I should actually have 
revoked serverCA instead. So I have tried all of my tests with a CRL that 
attempts to revoke both certs. The resulting CRL looks ok to me:
openssl crl -text -in crls/crl.pem
Certificate Revocation List (CRL):        Version 2 (0x1)    Signature 
Algorithm: sha1WithRSAEncryption        Issuer: 
/C=US/ST=MN/L=mycity/O=mycompany/OU=Networking/CN=My Root/emailAddress=edited   
     Last Update: Jul 30 14:31:31 2014 GMT        Next Update: Aug 29 14:31:31 
2014 GMT        CRL extensions:            X509v3 CRL Number:                
8998Revoked Certificates:    Serial Number: 9B7CBA0F9C48177C        Revocation 
Date: Jul 28 15:52:28 2014 GMT    Serial Number: AEB802C77D4CF001        
Revocation Date: Jul 23 13:19:40 2014 GMT    Serial Number: D3F15A42946EAFB2    
    Revocation Date: Jul 30 14:30:24 2014 GMT    Signature Algorithm: 
sha1WithRSAEncryption         
38:e3:51:c6:30:d5:ec:50:60:88:18:2c:60:ac:fa:80:98:b9:         
1d:81:65:99:bf:5b:02:71:88:e9:d3:22:40:8a:7b:fa:24:7d:         
ef:00:d6:ee:32:84:68:e9:bc:93:e3:6f:e6:0a:62:20:0f:0c:         
60:e2:f7:94:7c:25:13:54:68:98:11:fc:99:4e:9d:09:7b:8c:         
80:82:e7:96:f6:d2:73:75:85:6d:64:7c:56:ac:3c:76:44:ac:         
1e:32:bb:04:ad:a9:b3:cf:04:34:6e:ab:2b:0b:87:d7:9b:46:         
a9:fa:34:ae:35:80:39:a6:ce:2b:34:9c:a8:25:86:4b:b9:16:         
81:8d:8a:8f:f9:67:1c:4a:c5:b0:c2:5c:68:d3:e1:8a:d6:2f:         
dc:5b:a0:bf:10:ee:1b:54:fc:ae:b3:02:b4:10:18:5b:17:8f:         
2b:3a:d7:a7:a5:f3:2a:4d:7a:39:5f:49:10:a2:fa:3e:8f:bd:         
ed:6a:1d:aa:8b:00:f9:be:8d:29:12:46:a9:87:b2:dc:d8:25:         
69:e2:d1:bc:b6:00:4c:5a:7f:16:8e:5e:99:1d:89:7b:17:38:         
06:6c:c6:38:3b:e3:2f:fc:88:43:35:c5:03:42:7f:09:e2:c7:         
95:ab:4a:01:85:4f:bd:f3:8a:ed:bc:64:bf:d9:a8:67:77:79:         89:ed:d4:4a
You can ignore one of the serial numbers of the revoked certs, the two I was 
trying to revoke that are part of this CA are as follows:
openssl x509 -in certs/server.pem -text                                         
           Certificate:    Data:        Version: 3 (0x2)        Serial Number: 
11204034549200197500 (0x9b7cba0f9c48177c)    Signature Algorithm: 
sha256WithRSAEncryption        Issuer: C=US, ST=MN, L=mycity, O=mycompany, 
OU=Networking, CN=Server CA/emailAddress=edited        Validity            Not 
Before: Jul 21 14:41:11 2014 GMT            Not After : Aug 20 14:41:11 2014 
GMT        Subject: C=US, ST=Minnesota, L=mycity, O=mycompany, OU=Networking, 
CN= server/emailAddress=edited        Subject Public Key Info:            
Public Key Algorithm: rsaEncryption                Public-Key: (2048 bit)       
         Modulus:                    
00:e1:2c:c1:42:af:ab:f1:ae:07:3d:4f:d6:fe:d6:                    
cd:e6:8b:3d:00:fd:e4:ac:a3:73:bc:3e:46:3d:af:                    
64:88:ae:fb:cc:96:42:31:7a:71:59:e2:8c:24:e2:                    
fa:e8:7e:91:cd:c9:c1:04:bd:c6:b8:34:3c:26:e7:                    
4a:65:9b:2c:49:a2:9a:a3:d5:46:04:86:20:da:92:                    
bd:7b:ba:f9:65:20:62:f6:2f:2f:9e:96:8a:8f:00:                    
01:a4:d9:0e:ad:eb:d8:aa:af:5a:ff:e3:eb:0e:48:                    
f9:6e:5c:da:30:17:f3:e1:a8:2f:4e:47:43:a1:46:                    
ac:77:4f:75:fd:8c:9e:5e:91:8e:63:4c:85:68:5c:                    
b5:d5:1d:b6:82:d5:1d:50:0d:12:51:05:b6:0b:43:                    
ff:8f:c6:d4:3c:3a:10:1b:8c:35:38:f9:50:f7:e5:                    
44:95:55:17:31:2d:14:35:c6:a3:b3:93:f0:85:ff:                    
19:99:ad:27:d5:56:a0:5a:32:9b:9f:77:0f:14:4d:                    
24:de:db:29:59:4d:7c:58:f0:c7:44:f3:94:53:1f:                    
6f:c8:43:ff:67:33:67:9f:f7:cb:83:ea:9b:67:c2:                    
54:0a:89:f1:de:36:f2:bc:25:15:3d:48:30:58:7f:                    
85:a3:dc:c6:10:47:4c:27:02:e1:b6:d7:54:75:a4:                    90:09          
      Exponent: 65537 (0x10001)        X509v3 extensions:            X509v3 
Basic Constraints:                CA:FALSE            Netscape Comment:         
       OpenSSL Generated Certificate            X509v3 Subject Key Identifier:  
              D2:5B:0A:F5:E2:FC:C6:47:9A:EF:CA:58:F5:C2:9A:CD:F9:38:7A:6B       
     X509v3 Authority Key Identifier:                
keyid:7D:F9:4B:A9:56:16:6D:6B:4A:7C:FF:54:D3:A0:25:17:07:44:38:4C
    Signature Algorithm: sha256WithRSAEncryption         
44:3c:a0:9a:64:90:cb:4e:71:0d:1d:04:6e:66:3a:3c:73:0a:         
78:72:ed:b5:f3:8d:98:00:88:f3:b5:a6:68:46:c1:39:43:08:         
cf:bf:08:7e:74:cb:28:93:fe:6e:20:02:67:6d:ea:8d:eb:5f:         
a9:63:30:d2:c4:79:b5:06:ba:e7:47:5e:50:7b:69:94:ea:32:         
a8:01:45:0e:bd:bf:ce:38:2c:02:66:44:92:f8:6e:1b:a8:39:         
31:1a:bd:fd:3f:b2:73:b2:0e:4d:7e:ad:7c:3f:e8:6d:a0:b8:         
d3:72:ab:47:26:2d:13:05:b6:46:61:4f:89:8c:10:a6:d5:fa:         
bf:46:df:69:35:ab:11:f7:cd:5c:df:f3:6c:31:d4:27:a4:fe:         
89:91:8b:60:27:18:0b:a1:c3:ca:ce:ec:23:24:fb:0e:08:2d:         
a4:9a:95:c3:a3:10:c6:98:f1:1a:1d:a8:99:46:cc:82:5c:33:         
73:82:95:d7:e0:fe:25:cd:20:30:05:1c:28:d1:40:07:20:04:         
3e:2a:d6:b5:92:5b:dc:29:a0:d1:09:27:65:02:c6:80:c5:8b:         
c4:0f:93:97:cb:dc:01:72:84:b8:70:0e:32:e2:fe:1d:4d:83:         
a5:fc:a6:22:41:02:12:b7:3d:4d:65:64:ec:c3:4b:60:d0:db:         2f:25:ac:2d
and
openssl x509 -in certs/serverCA.pem -textCertificate:    Data:        Version: 
3 (0x2)        Serial Number: 15272087053394685874 (0xd3f15a42946eafb2)    
Signature Algorithm: sha256WithRSAEncryption        Issuer: C=US, ST=MN, 
L=mycity, O=mycompany, OU=Networking, CN=Root/emailAddress=edited        
Validity            Not Before: Jul 21 14:29:04 2014 GMT            Not After : 
Aug 20 14:29:04 2014 GMT        Subject: C=US, ST=MN, L=mycity, O=mycompany, 
OU=Networking, CN=Server CA/emailAddress=edited        Subject Public Key Info: 
           Public Key Algorithm: rsaEncryption                Public-Key: (2048 
bit)                Modulus:                    
00:d7:4a:be:2b:46:77:9e:89:9e:1d:8c:f7:66:6a:                    
8b:bb:57:ef:0a:9a:4e:13:f8:a4:07:a2:6d:2a:1c:                    
04:c1:b3:6b:98:ca:bc:e7:91:4d:c9:9c:d0:b9:69:                    
d6:36:72:05:cd:f9:a4:3d:7f:a8:8b:c2:53:07:78:                    
ac:ef:9d:e1:2c:51:30:df:2d:b4:93:a3:f6:2f:b5:                    
49:02:3a:1c:3d:33:1d:1c:80:0d:35:d0:5c:31:37:                    
e3:18:63:53:8d:a2:e3:54:b6:c6:2c:f9:1e:c0:8a:                    
33:18:7a:db:e2:4f:f7:d6:a2:16:9b:93:85:04:06:                    
c1:b1:73:76:01:54:ed:23:c4:1d:37:b2:a4:68:81:                    
14:7e:d8:1a:1a:4f:e0:72:ee:3a:9e:a9:80:dd:14:                    
21:89:7d:8e:04:2a:1b:58:27:50:e9:50:a3:31:4f:                    
f5:4f:47:1b:50:d0:29:c9:05:a5:6b:c2:38:85:2d:                    
1b:41:cd:39:8d:87:30:f4:a0:9f:7a:14:40:86:d5:                    
c2:7b:12:ea:0b:64:47:e4:da:79:52:55:09:8a:82:                    
63:4b:90:1d:a9:b5:66:42:ff:d2:d7:59:4d:15:fc:                    
1b:9f:db:92:98:d0:ee:1a:cd:78:c3:f0:78:f0:b2:                    
0e:30:6c:32:2a:d2:84:fe:6e:f4:1f:e1:af:93:61:                    25:65          
      Exponent: 65537 (0x10001)        X509v3 extensions:            X509v3 
Subject Key Identifier:                
7D:F9:4B:A9:56:16:6D:6B:4A:7C:FF:54:D3:A0:25:17:07:44:38:4C            X509v3 
Authority Key Identifier:                
keyid:C5:B3:BC:42:13:58:90:50:BD:08:73:26:CC:17:F7:E4:45:FF:18:04
            X509v3 Basic Constraints:                CA:TRUE    Signature 
Algorithm: sha256WithRSAEncryption         
a6:57:43:b7:7b:3f:b7:2c:ce:fc:e6:45:ed:1b:55:16:c0:ae:         
a1:f7:20:20:22:d4:52:8e:d1:6a:d8:0c:1b:53:cb:03:25:60:         
13:18:42:6a:71:d0:e9:74:df:fa:1f:32:bd:a9:d8:44:f4:7a:         
5e:be:8b:de:2c:81:d6:b3:b7:f0:eb:4f:d7:b8:bb:2b:d9:32:         
55:71:39:fc:5c:9e:a9:36:99:27:2e:f9:e8:0f:85:32:9d:49:         
5e:89:55:35:2a:d1:07:54:7f:67:1d:0e:14:18:04:3c:16:fd:         
02:5a:de:88:40:1a:79:4a:39:b3:90:9d:2b:b0:56:50:30:2c:         
4f:4c:e4:ea:ff:00:ea:10:39:5d:f0:7a:33:0f:cf:6d:a9:8e:         
3a:fa:67:ec:23:25:65:fc:fb:02:d0:f2:d4:08:9a:53:8f:85:         
d0:06:e6:29:84:16:ad:af:94:5a:ce:41:6a:55:d7:c6:5b:22:         
ba:74:c2:ec:1c:c1:50:e0:5b:38:50:1c:57:33:f4:7d:5a:0c:         
05:ba:9a:14:01:c6:98:3a:4e:dd:ef:3d:96:8d:cb:3c:c5:fc:         
8c:57:f3:e9:45:f3:11:b3:42:c9:c8:c1:78:e6:8d:de:b3:2a:         
3b:d2:4e:1a:54:fb:a1:59:c7:f5:37:c9:49:ed:15:3f:a5:31:         20:a1:0d:6d

I moved crl.pem to my client machine and placed it in /etc/ssl/crls. The client 
is also running 1.0.1h. The relevant code in the client follows.
Reading the file in; I have edited out a lot of error checking, etc, but the 
CRL is read in successfully:
X509_STORE    *trusted_store;X509_CRL      *crl;fp = 
fopen("/etc/ssl/crls/crl.pem", "r");crl = PEM_read_X509_CRL(fp, NULL, 0, 
NULL);X509_STORE_add_crl(trusted_store,crl);
Then I enable CRL checking as follows (I have also tried  setting only 
X509_V_FLAG_CRL_CHECK):
        X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();        
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK |                      
                      X509_V_FLAG_CRL_CHECK_ALL);        
X509_STORE_set1_param(trusted_store, param);        
X509_VERIFY_PARAM_free(param);
If anyone can find anything wrong in my setup, please advise. I'm hoping I'm 
not missing something terribly simple and obvious. 
But the bottom line is I am not able to get the client to recognize that both 
the serverCA and server certificates are revoked by crl.pem. I have tried a lot 
of combinations of how everything is set up and tweaks to my code I have set up 
a hash link to the CRL as follows:
ln -s crl.pem `openssl crl -hash -noout -in crl.pem`.r0
Setting up the hash worked fine, but that didn't change the outcome of a 
successful handshake when getting the revoked certificate.
I have also tried concatenating the CA's root cert and CRL into one file and 
installing that in /etc/ssl/crls as well as /etc/ssl/certs.
None of the above changed my results, so I went ahead built my own OpenSSL with 
some debug code in it to try to follow the path through certificate 
verification when I run my client and open a connection to my server configured 
with my CA's certificates. I have configured both the server and serverCA 
certificates on my server and verified the resulting chains that get sent to 
the client. As I said before, I think it might only work to revoke the serverCA 
certificate with my root, so that's what I've tried most recently. I'll post 
some code fragments below, I may have narrowed things down to where something 
is amiss, which will hopefully help diagnose my issue.
In X509_vfy.c, check_cert is called:
static int check_cert(X509_STORE_CTX *ctx)      {       X509_CRL *crl = NULL, 
*dcrl = NULL;     X509 *x;        int ok, cnum;   unsigned int last_reasons;    
  cnum = ctx->error_depth;        x = sk_X509_value(ctx->chain, cnum);    
ctx->current_cert = x;  ctx->current_issuer = NULL;     ctx->current_crl_score 
= 0;     ctx->current_reasons = 0;       while (ctx->current_reasons != 
CRLDP_ALL_REASONS)               {               last_reasons = 
ctx->current_reasons;            /* Try to retrieve relevant CRL */             
 if (ctx->get_crl)          {            printf("get crl\n");                   
 ok = ctx->get_crl(ctx, &crl, x);          }             else          {        
    printf("get crl delta\n");                   ok = get_crl_delta(ctx, &crl, 
&dcrl, x);  // This is called          }          /* If error looking up CRL, 
nothing we can do except             * notify callback               */         
    if(!ok)                 {            printf("unable to get crl\n");         
            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;                      ok 
= ctx->verify_cb(0, ctx);                    goto err;                       }  
             ctx->current_crl = crl;        printf("call check_crl\n");         
     ok = ctx->check_crl(ctx, crl);          if (!ok)                        
goto err;
                if (dcrl)                       {            printf("call 
check_crl2\n");                       ok = ctx->check_crl(ctx, dcrl);           
      if (!ok)                                goto err;            printf("call 
cert_crl\n");                 ok = ctx->cert_crl(ctx, dcrl, x);                 
      if (!ok)                                goto err;                       } 
              else                    ok = 1;
                /* Don't look in full CRL if delta reason is removefromCRL */   
        if (ok != 2)                    {            printf("call 
cert_crl2\n");                        ok = ctx->cert_crl(ctx, crl, x);   // 
This is called                    if (!ok)                                goto 
err;                       }
                X509_CRL_free(crl);             X509_CRL_free(dcrl);            
crl = NULL;             dcrl = NULL;            /* If reasons not updated we 
wont get anywhere by                * another iteration, so exit loop.          
    */             if (last_reasons == ctx->current_reasons)                    
   {            printf("last reasons = current reasons\n");                     
   ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;                      ok = 
ctx->verify_cb(0, ctx);                    goto err;                       }    
           }       err:    X509_CRL_free(crl);     X509_CRL_free(dcrl);
        ctx->current_crl = NULL;        return ok;
        }
The printfs are obviously added by me, and I have added comments ("// This is 
called") to show the path. It seems like the check for revocation would take 
place in cert_crl():
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)        {       
int ok; X509_REVOKED *rev;      /* The rules changed for this... previously if 
a CRL contained   * unhandled critical extensions it could still be used to 
indicate      * a certificate was revoked. This has since been changed since    
      * critical extension can change the meaning of CRL entries.     */     if 
(!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)          && (crl->flags & 
EXFLAG_CRITICAL))              {        printf("unhandld ext\n");              
ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;               ok = 
ctx->verify_cb(0, ctx);            if(!ok)                 return 0;            
   }       /* Look for serial number of certificate in CRL  * If found make 
sure reason is not removeFromCRL.       */     if (X509_CRL_get0_by_cert(crl, 
&rev, x))                {        printf("get0 by cert\n");              if 
(rev->reason == CRL_REASON_REMOVE_FROM_CRL)                  return 2;        
printf("cert revoked\n");              ctx->error = X509_V_ERR_CERT_REVOKED;    
       ok = ctx->verify_cb(0, ctx);            if (!ok)                        
return 0;               }
        return 1;       }
>From my debug code, I can see that when X509_CRL_get0_by_cert is called it 
>returns 0 and doesn't set up the cert revoked error. However, in 
>X509_CRL_get0_by_cert:
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)   {    
printf("in get0 by cert\n");       if (crl->meth->crl_lookup)      {        
printf("crllookup\n");         return crl->meth->crl_lookup(crl, ret,           
                               X509_get_serialNumber(x),                        
                       X509_get_issuer_name(x));      }        return 0;       }
The crl_lookup function never gets called, so it's obviously NULL. I'm guessing 
the crl_lookup function would be what compares the certificate's serial number 
to those revoked in the CRL. Unfortunately, I have no idea what this means, as 
far as I'm aware, this isn't a function I need to be setting up with an OpenSSL 
API. But the fact that that function is never executing seems to be the 
problem. 
I'm not sure if my trip through the OpenSSL code was a red herring or not, but 
I'm including it here anyway.
Thanks in advance for any help.

                                          

Reply via email to