It appears this is resolved already, sort of. It appears the one thing I did not try after revoking the serverCA certificate with my root was to concatenate the new CRL to the root cert on the client machine. When I did that, my client got a certificate revoked error. However, I do have a question. Is there any way around this requirement? The requirement of apending the root certificate and CRL files on the client machine in /etc/ssl/crls?
From: jetso...@hotmail.com To: openssl-users@openssl.org Subject: Can't get my CRL to work on my OpenSSL client Date: Wed, 30 Jul 2014 18:18:03 +0000 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.