Skip to content

Commit

Permalink
Merge pull request #1431 from bbockelm/overhaul_curl_ca
Browse files Browse the repository at this point in the history
Overhaul curl's usage of CAs.
  • Loading branch information
abh3 committed Apr 14, 2021
2 parents cf1d4e5 + 87b341c commit 0e460d7
Show file tree
Hide file tree
Showing 12 changed files with 772 additions and 61 deletions.
63 changes: 46 additions & 17 deletions src/XrdCrypto/XrdCryptosslAux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,26 @@ XrdSutBucket *XrdCryptosslX509ExportChain(XrdCryptoX509Chain *chain,
return bck;
}

//____________________________________________________________________________
int XrdCryptosslX509ToFile(XrdCryptoX509 *x509, FILE *file, const char *fname)
{
// Dump a single X509 certificate to a file in PEM format.
EPNAME("X509ChainToFile");

// Check inputs
if (!x509 || !file) {
DEBUG("Invalid inputs");
return -1;
}

if (PEM_write_X509(file, (X509 *)x509->Opaque()) != 1) {
DEBUG("error while writing certificate " << fname);
return -1;
}

return 0;
}

//____________________________________________________________________________
int XrdCryptosslX509ChainToFile(XrdCryptoX509Chain *ch, const char *fn)
{
Expand Down Expand Up @@ -433,6 +453,27 @@ int XrdCryptosslX509ParseStack(XrdTlsPeerCerts* pc, XrdCryptoX509Chain *chain)
//____________________________________________________________________________
int XrdCryptosslX509ParseFile(const char *fname,
XrdCryptoX509Chain *chain)
{
EPNAME("X509ParseFile");

//
// Open file and read the content:
// it should contain blocks on information in PEM form
FILE *fcer = fopen(fname, "r");
if (!fcer) {
DEBUG("unable to open file (errno: "<<errno<<")");
return 0;
}

auto retval = XrdCryptosslX509ParseFile(fcer, chain, fname);
fclose(fcer);
return retval;
}

//____________________________________________________________________________
int XrdCryptosslX509ParseFile(FILE *fcer,
XrdCryptoX509Chain *chain,
const char *fname)
{
// Parse content of file 'fname' and add X509 certificates to
// chain (which must be initialized by the caller).
Expand All @@ -441,9 +482,9 @@ int XrdCryptosslX509ParseFile(const char *fname,
EPNAME("X509ParseFile");
int nci = 0;

// Make sure we got a file to import
if (!fname) {
DEBUG("file name undefined: can do nothing");
// Make sure we got a valid file
if (!fcer) {
DEBUG("FILE object undefined: can do nothing");
return nci;
}

Expand All @@ -453,15 +494,6 @@ int XrdCryptosslX509ParseFile(const char *fname,
return nci;
}

//
// Open file and read the content:
// it should contain blocks on information in PEM form
FILE *fcer = fopen(fname, "r");
if (!fcer) {
DEBUG("unable to open file (errno: "<<errno<<")");
return nci;
}

// Now read out certificates and add them to the chain
X509 *xcer = 0;
while (PEM_read_X509(fcer, &xcer, 0, 0)) {
Expand All @@ -485,9 +517,9 @@ int XrdCryptosslX509ParseFile(const char *fname,
rewind(fcer);
RSA *rsap = 0;
if (!PEM_read_RSAPrivateKey(fcer, &rsap, 0, 0)) {
DEBUG("no RSA private key found in file "<<fname);
DEBUG("no RSA private key found in file " << fname);
} else {
DEBUG("found a RSA private key in file "<<fname);
DEBUG("found a RSA private key in file " << fname);
// We need to complete the key: we save it temporarly
// to a bio and check all the private keys of the
// loaded certificates
Expand Down Expand Up @@ -538,9 +570,6 @@ int XrdCryptosslX509ParseFile(const char *fname,
}
}

// We can close the file now
fclose(fcer);

// We are done
return nci;
}
Expand Down
4 changes: 4 additions & 0 deletions src/XrdCrypto/XrdCryptosslAux.hh
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ bool XrdCryptosslX509VerifyChain(XrdCryptoX509Chain *chain, int &errcode);
XrdSutBucket *XrdCryptosslX509ExportChain(XrdCryptoX509Chain *c, bool key = 0);
// chain export to file (proxy file creation)
int XrdCryptosslX509ChainToFile(XrdCryptoX509Chain *c, const char *fn);
// export single certificate to file; fname is solely for debug message purposes
extern "C" int XrdCryptosslX509ToFile(XrdCryptoX509 *x509, FILE *file, const char *fname);
// certificates from file parsing
int XrdCryptosslX509ParseFile(const char *fname, XrdCryptoX509Chain *c);
// certificates from FILE object; fname is solely for debug message purposes
extern "C" int XrdCryptosslX509ParseFile(FILE *file, XrdCryptoX509Chain *c, const char *fname);
// certificates from bucket parsing
int XrdCryptosslX509ParseBucket(XrdSutBucket *b, XrdCryptoX509Chain *c);
// certificates from STACK_OF(X509*)
Expand Down
78 changes: 55 additions & 23 deletions src/XrdCrypto/XrdCryptosslX509Crl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,6 @@ XrdCryptosslX509Crl::XrdCryptosslX509Crl(const char *cf, int opt)
// Constructor certificate from file 'cf'.
EPNAME("X509Crl::XrdCryptosslX509Crl_file");

// Init private members
crl = 0; // The crl object
lastupdate = -1; // begin-validity time in secs since Epoch
nextupdate = -1; // end-validity time in secs since Epoch
issuer = ""; // issuer;
issuerhash = ""; // hash of issuer;
srcfile = ""; // source file;
nrevoked = 0; // number of revoked certificates

// Make sure file name is defined;
if (opt == 0) {
if (Init(cf) != 0) {
Expand All @@ -82,6 +73,18 @@ XrdCryptosslX509Crl::XrdCryptosslX509Crl(const char *cf, int opt)
}
}

//_____________________________________________________________________________
XrdCryptosslX509Crl::XrdCryptosslX509Crl(FILE *fc, const char *cf)
{
// Constructe CRL from a FILE handle `fc` with (assumed) filename `cf`.
EPNAME("X509Crl::XrdCryptosslX509Crl_file");

if (Init(fc, cf)) {
DEBUG("could not initialize the CRL from " << cf);
return;
}
}

//_____________________________________________________________________________
XrdCryptosslX509Crl::XrdCryptosslX509Crl(XrdCryptoX509 *cacert)
: XrdCryptoX509Crl()
Expand All @@ -92,15 +95,6 @@ XrdCryptosslX509Crl::XrdCryptosslX509Crl(XrdCryptoX509 *cacert)
// loads it in the cache
EPNAME("X509Crl::XrdCryptosslX509Crl_CA");

// Init private members
crl = 0; // The crl object
lastupdate = -1; // begin-validity time in secs since Epoch
nextupdate = -1; // end-validity time in secs since Epoch
issuer = ""; // issuer;
issuerhash = ""; // hash of issuer;
srcfile = ""; // source file;
nrevoked = 0; // number of revoked certificates

// The CA certificate must be defined
if (!cacert || cacert->type != XrdCryptoX509::kCA) {
DEBUG("the CA certificate is undefined or not CA! ("<<cacert<<")");
Expand Down Expand Up @@ -161,8 +155,8 @@ XrdCryptosslX509Crl::~XrdCryptosslX509Crl()
//_____________________________________________________________________________
int XrdCryptosslX509Crl::Init(const char *cf)
{
// Constructor certificate from file 'cf'.
// Return 0 on success, -1 on failure
// Load a CRL from an open file handle; for debugging purposes,
// we assume it's loaded from file named `cf`.
EPNAME("X509Crl::Init");

// Make sure file name is defined;
Expand All @@ -187,15 +181,30 @@ int XrdCryptosslX509Crl::Init(const char *cf)
DEBUG("cannot open file "<<cf<<" (errno: "<<errno<<")");
return -1;
}

auto rval = Init(fc, cf);

//
// Close the file
fclose(fc);

return rval;
}


//_____________________________________________________________________________
int XrdCryptosslX509Crl::Init(FILE *fc, const char *cf)
{
// Constructor certificate from file 'cf'.
// Return 0 on success, -1 on failure
EPNAME("X509Crl::Init");

//
// Read the content:
if (!PEM_read_X509_CRL(fc, &crl, 0, 0)) {
DEBUG("Unable to load CRL from file");
return -1;
}
//
// Close the file
fclose(fc);

//
// Notify
Expand Down Expand Up @@ -310,6 +319,29 @@ int XrdCryptosslX509Crl::InitFromURI(const char *uri, const char *hash)
return 0;
}

//_____________________________________________________________________________
bool XrdCryptosslX509Crl::ToFile(FILE *fh)
{
// Write the CRL's contents to a file in the PEM format.
EPNAME("ToFile");

if (!crl) {
DEBUG("CRL object invalid; cannot write to a file");
return false;
}

if (PEM_write_X509_CRL(fh, crl) == 0) {
DEBUG("Unable to write CRL to file");
return false;
}

//
// Notify
DEBUG("CRL successfully written to file");

return true;
}

//_____________________________________________________________________________
int XrdCryptosslX509Crl::GetFileType(const char *crlfn)
{
Expand Down
27 changes: 16 additions & 11 deletions src/XrdCrypto/XrdCryptosslX509Crl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class XrdCryptosslX509Crl : public XrdCryptoX509Crl {
public:

XrdCryptosslX509Crl(const char *crlf, int opt = 0);
XrdCryptosslX509Crl(FILE *, const char *crlf);
XrdCryptosslX509Crl(XrdCryptoX509 *cacert);
virtual ~XrdCryptosslX509Crl();

Expand Down Expand Up @@ -79,22 +80,26 @@ public:
// Verify signature
bool Verify(XrdCryptoX509 *ref);

// Dump CRL object to a file.
bool ToFile(FILE *fh);

private:
X509_CRL *crl; // The CRL object
time_t lastupdate; // time of last update
time_t nextupdate; // time of next update
XrdOucString issuer; // issuer name;
XrdOucString issuerhash; // hash of issuer name (default algorithm);
XrdOucString issueroldhash; // hash of issuer name (md5 algorithm);
XrdOucString srcfile; // source file name, if any;
XrdOucString crluri; // URI from where to get the CRL file, if any;

int nrevoked; // Number of certificates revoked
XrdSutCache cache; // cached infor about revoked certificates
X509_CRL *crl{nullptr}; // The CRL object
time_t lastupdate{-1}; // time of last update
time_t nextupdate{-1}; // time of next update
XrdOucString issuer; // issuer name;
XrdOucString issuerhash; // hash of issuer name (default algorithm);
XrdOucString issueroldhash; // hash of issuer name (md5 algorithm);
XrdOucString srcfile; // source file name, if any;
XrdOucString crluri; // URI from where to get the CRL file, if any;

int nrevoked{0}; // Number of certificates revoked
XrdSutCache cache; // cached infor about revoked certificates

int GetFileType(const char *crlfn); //Determine file type
int LoadCache(); // Load the cache
int Init(const char *crlf); // Init from file
int Init(FILE *fc, const char *crlf); // Init from file handle
int InitFromURI(const char *uri, const char *hash); // Init from URI
};

Expand Down
1 change: 1 addition & 0 deletions src/XrdHttp/XrdHttpProtocol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2799,6 +2799,7 @@ int XrdHttpProtocol::LoadExtHandler(std::vector<extHInfo> &hiVec,
// Add the pointer to the cadir and the cakey to the environment.
//
if (sslcadir) myEnv.Put("http.cadir", sslcadir);
if (sslcafile) myEnv.Put("http.cafile", sslcafile);
if (sslcert) myEnv.Put("http.cert", sslcert);
if (sslkey) myEnv.Put("http.key" , sslkey);

Expand Down
4 changes: 4 additions & 0 deletions src/XrdSys/XrdSysFD.hh
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ inline int XrdSysFD_Socketpair(int domain, int type, int protocol, int sfd[2])
}
#endif

// openat is part of POSIX.1-2008; in Linux, BSD, and Solaris
inline int XrdSysFD_Openat(int dirfd, const char *pathname, int flags)
{return openat(dirfd, pathname, flags | O_CLOEXEC);}

inline bool XrdSysFD_Yield(int fd)
{int fdFlags = fcntl(fd, F_GETFD);
if (fdFlags < 0) return false;
Expand Down
Loading

0 comments on commit 0e460d7

Please sign in to comment.