39 #include <openssl/bn.h>
40 #include <openssl/pem.h>
46 #include <sys/types.h>
50 #if OPENSSL_VERSION_NUMBER < 0x10100000L
51 #define X509_REVOKED_get0_revocationDate(x) (x)->revocationDate
52 #define X509_REVOKED_get0_serialNumber(x) (x)->serialNumber
53 #define X509_CRL_get0_lastUpdate X509_CRL_get_lastUpdate
54 #define X509_CRL_get0_nextUpdate X509_CRL_get_nextUpdate
62 EPNAME(
"X509Crl::XrdCryptosslX509Crl_file");
67 DEBUG(
"could not initialize the CRL from "<<cf);
71 if (InitFromURI(cf, 0) != 0) {
72 DEBUG(
"could not initialize the CRL from URI"<<cf);
82 EPNAME(
"X509Crl::XrdCryptosslX509Crl_file");
85 DEBUG(
"could not initialize the CRL from " << cf);
98 EPNAME(
"X509Crl::XrdCryptosslX509Crl_CA");
102 DEBUG(
"the CA certificate is undefined or not CA! ("<<cacert<<
")");
107 X509_EXTENSION *crlext = (X509_EXTENSION *) cacert->
GetExtension(
"crlDistributionPoints");
109 DEBUG(
"extension 'crlDistributionPoints' not found in the CA certificate");
114 BIO *bext = BIO_new(BIO_s_mem());
115 ASN1_OBJECT *obj = X509_EXTENSION_get_object(crlext);
116 i2a_ASN1_OBJECT(bext, obj);
117 X509V3_EXT_print(bext, crlext, 0, 4);
120 int lbio = (int) BIO_get_mem_data(bext, &cbio);
121 char *buf = (
char *) malloc(lbio+1);
123 memcpy(buf, cbio, lbio);
130 DEBUG(
"URI string: "<< uris);
134 while ((from = uris.
tokenize(uri, from,
' ')) != -1) {
158 int XrdCryptosslX509Crl::Init(
const char *cf)
166 DEBUG(
"file name undefined");
171 int fd =
open(cf, O_RDONLY);
174 if (errno == ENOENT) {
175 DEBUG(
"file "<<cf<<
" does not exist - do nothing");
177 DEBUG(
"cannot open file "<<cf<<
" (errno: "<<errno<<
")");
183 FILE *fc = fdopen(fd,
"r");
186 DEBUG(
"cannot open file "<<cf<<
" (errno: "<<errno<<
")");
191 auto rval = Init(fc, cf);
202 int XrdCryptosslX509Crl::Init(FILE *fc,
const char *cf)
210 if (!PEM_read_X509_CRL(fc, &crl, 0, 0)) {
211 DEBUG(
"Unable to load CRL from file");
217 DEBUG(
"CRL successfully loaded from "<< cf);
234 int XrdCryptosslX509Crl::InitFromURI(
const char *uri,
const char *hash)
239 EPNAME(
"X509Crl::InitFromURI");
243 DEBUG(
"uri undefined");
248 int isl = u.rfind(
'/');
249 if (isl !=
STR_NPOS) h.assign(u, isl + 1);
251 if (h ==
"") h =
"hashtmp";
255 if (outtmp.length() <= 0) outtmp =
"/tmp";
256 if (!outtmp.endswith(
"/")) outtmp +=
"/";
267 DEBUG(
"executing ... "<<cmd);
268 if (system(cmd.c_str()) == -1) {
269 DEBUG(
"'system' could not fork to execute command '"<<cmd<<
"'");
273 if (
stat(outtmp.c_str(), &st) != 0) {
274 DEBUG(
"did not manage to get the CRL file from "<<uri);
280 int needsopenssl = GetFileType(outtmp.c_str());
281 if (needsopenssl < 0) {
282 DEBUG(
"did not manage to coorectly parse "<<outtmp);
286 if (needsopenssl > 0) {
288 outpem.
replace(
".crltmp",
".pem");
289 cmd =
"openssl crl -inform DER -in ";
296 DEBUG(
"executing ... "<<cmd);
297 if (system(cmd.c_str()) == -1) {
298 DEBUG(
"system: problem executing: "<<cmd);
303 if (
unlink(outtmp.c_str()) != 0) {
304 DEBUG(
"problems removing "<<outtmp);
310 DEBUG(
"did not manage to change format from DER to PEM ("<<outpem<<
")");
315 if (Init(outpem.
c_str()) != 0) {
316 DEBUG(
"could not initialize the CRL from "<<outpem);
335 DEBUG(
"CRL object invalid; cannot write to a file");
339 if (PEM_write_X509_CRL(fh, crl) == 0) {
340 DEBUG(
"Unable to write CRL to file");
346 DEBUG(
"CRL successfully written to file");
352 int XrdCryptosslX509Crl::GetFileType(
const char *crlfn)
359 if (!crlfn || strlen(crlfn) <= 0) {
360 PRINT(
"file name undefined!");
364 char line[1024] = {0};
365 FILE *f =
fopen(crlfn,
"r");
367 PRINT(
"could not open file "<<crlfn<<
" - errno: "<<(
int)errno);
372 while (fgets(line, 1024, f)) {
374 if (line[0] ==
'\n')
continue;
376 if (strstr(line,
"BEGIN X509 CRL")) rc = 0;
388 return X509_CRL_get_ext_by_critical(crl,1,-1) != -1;
392 int XrdCryptosslX509Crl::LoadCache()
400 DEBUG(
"CRL undefined");
405 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
406 STACK_OF(X509_REVOKED *) rsk = X509_CRL_get_REVOKED(crl);
408 STACK_OF(X509_REVOKED *) *rsk = X509_CRL_get_REVOKED(crl);
411 DEBUG(
"could not get stack of revoked instances");
416 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
417 nrevoked = sk_X509_REVOKED_num(rsk);
419 nrevoked = sk_num(rsk);
421 DEBUG(nrevoked <<
"certificates have been revoked");
423 DEBUG(
"no valid certificate has been revoked - nothing to do");
430 for (; i < nrevoked; i++ ){
431 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
432 X509_REVOKED *rev = sk_X509_REVOKED_value(rsk,i);
434 X509_REVOKED *rev = (X509_REVOKED *)sk_value(rsk,i);
437 BIGNUM *bn = BN_new();
439 tagser = BN_bn2hex(bn);
441 TRACE(
Dump,
"certificate with serial number: "<<tagser<<
442 " has been revoked");
447 DEBUG(
"problems getting entry in the cache");
455 OPENSSL_free(tagser);
470 if (lastupdate < 0) {
486 if (nextupdate < 0) {
500 EPNAME(
"X509Crl::Issuer");
503 if (issuer.
length() <= 0) {
507 DEBUG(
"WARNING: no CRL available - cannot extract issuer name");
508 return (
const char *)0;
516 return (issuer.
length() > 0) ? issuer.
c_str() : (
const char *)0;
525 EPNAME(
"X509::IssuerHash");
527 #if (OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(__APPLE__))
530 if (issueroldhash.
length() <= 0) {
533 char chash[30] = {0};
534 snprintf(chash,
sizeof(chash),
535 "%08lx.0",X509_NAME_hash_old(X509_CRL_get_issuer(crl)));
536 issueroldhash = chash;
538 DEBUG(
"WARNING: no certificate available - cannot extract issuer hash (md5)");
542 return (issueroldhash.
length() > 0) ? issueroldhash.
c_str() : (
const char *)0;
549 if (issuerhash.
length() <= 0) {
553 char chash[30] = {0};
554 snprintf(chash,
sizeof(chash),
555 "%08lx.0",X509_NAME_hash(X509_CRL_get_issuer(crl)));
558 DEBUG(
"WARNING: no certificate available - cannot extract issuer hash (default)");
563 return (issuerhash.
length() > 0) ? issuerhash.
c_str() : (
const char *)0;
576 X509 *r = ref ? (X509 *)(ref->
Opaque()) : 0;
577 EVP_PKEY *rk = r ? X509_get_pubkey(r) : 0;
582 return (X509_CRL_verify(crl, rk) > 0);
593 int now = (when > 0) ? when : time(0);
597 DEBUG(
"WARNING: CRL is expired: you should download the updated one");
602 DEBUG(
"No certificate in the list");
607 char tagser[20] = {0};
608 sprintf(tagser,
"%x",serialnumber);
614 if (now > cent->
mtime) {
615 DEBUG(
"certificate "<<tagser<<
" has been revoked");
634 int now = (when > 0) ? when : time(0);
638 DEBUG(
"WARNING: CRL is expired: you should download the updated one");
643 DEBUG(
"No certificate in the list");
651 if (now > cent->
mtime) {
652 DEBUG(
"certificate "<<sernum<<
" has been revoked");
671 char stbeg[256] = {0};
673 localtime_r(&tbeg,&tst);
674 asctime_r(&tst,stbeg);
675 stbeg[strlen(stbeg)-1] = 0;
676 char stend[256] = {0};
678 localtime_r(&tend,&tst);
679 asctime_r(&tst,stend);
680 stend[strlen(stend)-1] = 0;
682 PRINT(
"+++++++++++++++ X509 CRL dump +++++++++++++++++++++++");
690 PRINT(
"+ Validity: (expired!)");
692 PRINT(
"+ Validity:");
694 PRINT(
"+ LastUpdate: "<<tbeg<<
" UTC - "<<stbeg);
695 PRINT(
"+ NextUpdate: "<<tend<<
" UTC - "<<stend);
697 PRINT(
"+ Number of revoked certificates: "<<nrevoked);
699 PRINT(
"+++++++++++++++++++++++++++++++++++++++++++++++++");
void XrdCryptosslNameOneLine(X509_NAME *nm, XrdOucString &s)
time_t XrdCryptosslASN1toUTC(const ASN1_TIME *tsn1)
#define X509_REVOKED_get0_serialNumber(x)
#define X509_CRL_get0_nextUpdate
#define X509_CRL_get0_lastUpdate
#define X509_REVOKED_get0_revocationDate(x)
int stat(const char *path, struct stat *buf)
int open(const char *path, int oflag,...)
int unlink(const char *path)
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()
const char * ParentFile()
bool IsRevoked(int serialnumber, int when=0)
bool Verify(XrdCryptoX509 *ref)
const char * c_str() const
int replace(const char *s1, const char *s2, int from=0, int to=-1)
int tokenize(XrdOucString &tok, int from, char del=':')
XrdSutCacheEntry * Get(const char *tag)