39#include <openssl/bn.h>
40#include <openssl/pem.h>
55 EPNAME(
"X509Crl::XrdCryptosslX509Crl_file");
60 DEBUG(
"could not initialize the CRL from "<<cf);
64 if (InitFromURI(cf, 0) != 0) {
65 DEBUG(
"could not initialize the CRL from URI"<<cf);
75 EPNAME(
"X509Crl::XrdCryptosslX509Crl_file");
78 DEBUG(
"could not initialize the CRL from " << cf);
91 EPNAME(
"X509Crl::XrdCryptosslX509Crl_CA");
95 DEBUG(
"the CA certificate is undefined or not CA! ("<<cacert<<
")");
100 X509_EXTENSION *crlext = (X509_EXTENSION *) cacert->
GetExtension(
"crlDistributionPoints");
102 DEBUG(
"extension 'crlDistributionPoints' not found in the CA certificate");
107 BIO *bext = BIO_new(BIO_s_mem());
108 ASN1_OBJECT *obj = X509_EXTENSION_get_object(crlext);
109 i2a_ASN1_OBJECT(bext, obj);
110 X509V3_EXT_print(bext, crlext, 0, 4);
113 int lbio = (int) BIO_get_mem_data(bext, &cbio);
114 char *buf = (
char *) malloc(lbio+1);
116 memcpy(buf, cbio, lbio);
123 DEBUG(
"URI string: "<< uris);
127 while ((from = uris.
tokenize(uri, from,
' ')) != -1) {
151int XrdCryptosslX509Crl::Init(
const char *cf)
159 DEBUG(
"file name undefined");
164 int fd =
open(cf, O_RDONLY);
167 if (errno == ENOENT) {
168 DEBUG(
"file "<<cf<<
" does not exist - do nothing");
170 DEBUG(
"cannot open file "<<cf<<
" (errno: "<<errno<<
")");
176 FILE *fc = fdopen(fd,
"r");
179 DEBUG(
"cannot open file "<<cf<<
" (errno: "<<errno<<
")");
184 auto rval = Init(fc, cf);
195int XrdCryptosslX509Crl::Init(FILE *fc,
const char *cf)
203 if (!PEM_read_X509_CRL(fc, &crl, 0, 0)) {
204 DEBUG(
"Unable to load CRL from file");
210 DEBUG(
"CRL successfully loaded from "<< cf);
227int XrdCryptosslX509Crl::InitFromURI(
const char *uri,
const char *hash)
232 EPNAME(
"X509Crl::InitFromURI");
236 DEBUG(
"uri undefined");
239 XrdOucString u(uri), h(hash);
241 int isl = u.rfind(
'/');
242 if (isl !=
STR_NPOS) h.assign(u, isl + 1);
244 if (h ==
"") h =
"hashtmp";
247 XrdOucString outtmp(getenv(
"TMPDIR")), outpem;
248 if (outtmp.length() <= 0) outtmp =
"/tmp";
249 if (!outtmp.endswith(
"/")) outtmp +=
"/";
254 XrdOucString cmd(
"wget ");
260 DEBUG(
"executing ... "<<cmd);
261 if (system(cmd.c_str()) == -1) {
262 DEBUG(
"'system' could not fork to execute command '"<<cmd<<
"'");
266 if (
stat(outtmp.c_str(), &st) != 0) {
267 DEBUG(
"did not manage to get the CRL file from "<<uri);
273 int needsopenssl = GetFileType(outtmp.c_str());
274 if (needsopenssl < 0) {
275 DEBUG(
"did not manage to coorectly parse "<<outtmp);
279 if (needsopenssl > 0) {
281 outpem.
replace(
".crltmp",
".pem");
282 cmd =
"openssl crl -inform DER -in ";
289 DEBUG(
"executing ... "<<cmd);
290 if (system(cmd.c_str()) == -1) {
291 DEBUG(
"system: problem executing: "<<cmd);
296 if (
unlink(outtmp.c_str()) != 0) {
297 DEBUG(
"problems removing "<<outtmp);
303 DEBUG(
"did not manage to change format from DER to PEM ("<<outpem<<
")");
308 if (Init(outpem.
c_str()) != 0) {
309 DEBUG(
"could not initialize the CRL from "<<outpem);
328 DEBUG(
"CRL object invalid; cannot write to a file");
332 if (PEM_write_X509_CRL(fh, crl) == 0) {
333 DEBUG(
"Unable to write CRL to file");
339 DEBUG(
"CRL successfully written to file");
345int XrdCryptosslX509Crl::GetFileType(
const char *crlfn)
352 if (!crlfn || strlen(crlfn) <= 0) {
353 PRINT(
"file name undefined!");
357 char line[1024] = {0};
358 FILE *f =
fopen(crlfn,
"r");
360 PRINT(
"could not open file "<<crlfn<<
" - errno: "<<(
int)errno);
365 while (fgets(line, 1024, f)) {
367 if (line[0] ==
'\n')
continue;
369 if (strstr(line,
"BEGIN X509 CRL")) rc = 0;
381 return X509_CRL_get_ext_by_critical(crl,1,-1) != -1;
385int XrdCryptosslX509Crl::LoadCache()
393 DEBUG(
"CRL undefined");
398 STACK_OF(X509_REVOKED *) rsk = X509_CRL_get_REVOKED(crl);
400 DEBUG(
"could not get stack of revoked instances");
405 nrevoked = sk_X509_REVOKED_num(rsk);
406 DEBUG(nrevoked <<
"certificates have been revoked");
408 DEBUG(
"no valid certificate has been revoked - nothing to do");
415 for (; i < nrevoked; i++ ){
416 X509_REVOKED *rev = sk_X509_REVOKED_value(rsk,i);
418 BIGNUM *bn = BN_new();
419 ASN1_INTEGER_to_BN(X509_REVOKED_get0_serialNumber(rev), bn);
420 tagser = BN_bn2hex(bn);
422 TRACE(
Dump,
"certificate with serial number: "<<tagser<<
423 " has been revoked");
426 XrdSutCacheEntry *cent = cache.Get((
const char *)tagser, rdlock);
428 DEBUG(
"problems getting entry in the cache");
436 OPENSSL_free(tagser);
451 if (lastupdate < 0) {
467 if (nextupdate < 0) {
481 EPNAME(
"X509Crl::Issuer");
484 if (issuer.length() <= 0) {
488 DEBUG(
"WARNING: no CRL available - cannot extract issuer name");
489 return (
const char *)0;
497 return (issuer.length() > 0) ? issuer.c_str() : (
const char *)0;
506 EPNAME(
"X509::IssuerHash");
510 if (issueroldhash.length() <= 0) {
513 char chash[30] = {0};
514 snprintf(chash,
sizeof(chash),
515 "%08lx.0",X509_NAME_hash_old(X509_CRL_get_issuer(crl)));
516 issueroldhash = chash;
518 DEBUG(
"WARNING: no certificate available - cannot extract issuer hash (md5)");
522 return (issueroldhash.length() > 0) ? issueroldhash.c_str() : (
const char *)0;
526 if (issuerhash.length() <= 0) {
530 char chash[30] = {0};
531 snprintf(chash,
sizeof(chash),
532 "%08lx.0",X509_NAME_hash(X509_CRL_get_issuer(crl)));
535 DEBUG(
"WARNING: no certificate available - cannot extract issuer hash (default)");
540 return (issuerhash.length() > 0) ? issuerhash.c_str() : (
const char *)0;
553 X509 *r = ref ? (X509 *)(ref->
Opaque()) : 0;
554 EVP_PKEY *rk = r ? X509_get_pubkey(r) : 0;
559 return (X509_CRL_verify(crl, rk) > 0);
570 int now = (when > 0) ? when : time(0);
574 DEBUG(
"WARNING: CRL is expired: you should download the updated one");
579 DEBUG(
"No certificate in the list");
584 char tagser[20] = {0};
585 sprintf(tagser,
"%x",serialnumber);
591 if (now > cent->
mtime) {
592 DEBUG(
"certificate "<<tagser<<
" has been revoked");
611 int now = (when > 0) ? when : time(0);
615 DEBUG(
"WARNING: CRL is expired: you should download the updated one");
620 DEBUG(
"No certificate in the list");
628 if (now > cent->
mtime) {
629 DEBUG(
"certificate "<<sernum<<
" has been revoked");
648 char stbeg[256] = {0};
650 localtime_r(&tbeg,&tst);
651 asctime_r(&tst,stbeg);
652 stbeg[strlen(stbeg)-1] = 0;
653 char stend[256] = {0};
655 localtime_r(&tend,&tst);
656 asctime_r(&tst,stend);
657 stend[strlen(stend)-1] = 0;
659 PRINT(
"+++++++++++++++ X509 CRL dump +++++++++++++++++++++++");
667 PRINT(
"+ Validity: (expired!)");
669 PRINT(
"+ Validity:");
671 PRINT(
"+ LastUpdate: "<<tbeg<<
" UTC - "<<stbeg);
672 PRINT(
"+ NextUpdate: "<<tend<<
" UTC - "<<stend);
674 PRINT(
"+ Number of revoked certificates: "<<nrevoked);
676 PRINT(
"+++++++++++++++++++++++++++++++++++++++++++++++++");
void XrdCryptosslNameOneLine(X509_NAME *nm, XrdOucString &s)
time_t XrdCryptosslASN1toUTC(const ASN1_TIME *tsn1)
virtual bool IsExpired(int when=0)
const char * IssuerHash()
virtual XrdCryptoX509data GetExtension(const char *oid)
virtual XrdCryptoX509data Opaque()
virtual const char * SubjectHash(int)
XrdCryptosslX509Crl(const char *crlf, int opt=0)
virtual ~XrdCryptosslX509Crl()
bool hasCriticalExtension()
bool IsRevoked(int serialnumber, int when=0)
const char * ParentFile()
bool Verify(XrdCryptoX509 *ref)
int replace(const char *s1, const char *s2, int from=0, int to=-1)
int tokenize(XrdOucString &tok, int from, char del=':')
const char * c_str() const