Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul curl's usage of CAs. #1431

Merged
merged 18 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5e31d97
Overhaul curl's usage of CAs.
bbockelm Mar 18, 2021
75f631e
Add support for certfile directive for TPC handler.
bbockelm Mar 18, 2021
c84668f
Provide a pure-environment override for the XrdTpc cadir.
bbockelm Mar 18, 2021
399d5a7
XrdTpc: Switch update variables to std::atomics.
bbockelm Mar 19, 2021
1fe8f5d
XrdTpc: Remove deprecated readdir_r.
bbockelm Mar 19, 2021
5793ac7
Remove use of smart pointers.
bbockelm Mar 25, 2021
97deb89
XrdTpc: Pass filename to parsing / exporting functions.
bbockelm Mar 28, 2021
2719b4b
XrdTpc: Use XrdSysFD functions where possible for CLOEXEC protection.
bbockelm Mar 28, 2021
380f476
XrdTpc: If NSS hack is needed and fails, do not startup server.
bbockelm Mar 28, 2021
5f49669
XrdTls: Move temp CA generator code into core XrdTls.
bbockelm Mar 28, 2021
ab5fad4
XrdTpc: Remove XrdTpcNSSSupport implementation.
bbockelm Mar 28, 2021
1eb60a5
XrdTls: HACK - temporarily link crypto files into XrdUtils.
bbockelm Mar 28, 2021
c3dc4c1
XrdTls: Extend XrdCryptosslX509Crl to load / write CRLs to a FILE*
bbockelm Mar 28, 2021
342ba6c
XrdTls: HACK - add CRLs to XrdUtils. Revert when we understand linki…
bbockelm Mar 28, 2021
399fc03
XrdTls: Add CRL concatenation support to TempCA manager.
bbockelm Mar 28, 2021
7d3a823
XrdTls: Remove XrdTlsTempCA from its dedicated namespace.
bbockelm Mar 30, 2021
639e6e3
XrdTls: Convert TempCA loader to a separate thread.
bbockelm Apr 4, 2021
87b341c
XrdTls: Refactor temp CA code to use ADMINPATH directory.
bbockelm Apr 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);

bbockelm marked this conversation as resolved.
Show resolved Hide resolved
// 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
bbockelm marked this conversation as resolved.
Show resolved Hide resolved
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