31 #include <netinet/in.h>
34 #include <sys/types.h>
38 #define COMMON_DIGEST_FOR_OPENSSL
39 #include "CommonCrypto/CommonDigest.h"
41 #include <openssl/sha.h>
44 #include <openssl/evp.h>
46 #include "XrdVersion.hh"
57 #if OPENSSL_VERSION_NUMBER < 0x10100000L
59 EVP_MD_CTX *ctx = (EVP_MD_CTX *)OPENSSL_malloc(
sizeof(EVP_MD_CTX));
60 if (ctx) EVP_MD_CTX_init(ctx);
66 EVP_MD_CTX_cleanup(ctx);
99 XrdSecVec(
int arg, ...)
102 memset(Vec, 0,
sizeof(Vec));
104 reqCode = va_arg(ap,
int);
107 {sVal = va_arg(ap,
int);
108 Vec[i][reqCode-
kXR_auth] =
static_cast<char>(sVal);
110 reqCode = va_arg(ap,
int);
124 XrdSecVec secTable(0,
164 bool XrdSecProtect::GetSHA2(
unsigned char *hBuff,
struct iovec *iovP,
int iovN)
168 const EVP_MD *md = EVP_get_digestbyname(
"sha256");
172 if (1 != EVP_DigestInit_ex(mdctx, md, 0))
goto err;
176 for (
int i = 0; i < iovN; i++)
178 if (1 != EVP_DigestUpdate(mdctx, iovP[i].iov_base, iovP[i].iov_len))
184 if (1 != EVP_DigestFinal_ex(mdctx, hBuff, 0))
goto err;
205 if (reqCode < kXR_auth || reqCode >=
kXR_REQFENCE || !secVec)
return false;
220 return (
opts & rwOpen) != 0;
237 default:
return false;
264 buffHold() : P(0), bP(0) {}
265 ~buffHold() {
if (P) free(P);
if (bP)
delete bP;}
267 static const int iovNum = 3;
268 struct iovec
iov[iovNum];
271 const char *sigBuff, *payload = thedata;
272 unsigned char secHash[SHA256_DIGEST_LENGTH];
273 int sigSize, n, newSize, rc, paysize = 0;
279 mySeq = htonll(mySeq);
286 if (!payload) payload = ((
char *)&thereq) +
sizeof(
ClientRequest);
293 iov[0].iov_base = (
char *)&mySeq;
294 iov[0].iov_len =
sizeof(mySeq);
295 iov[1].iov_base = (
char *)&thereq;
297 if (n < 3) nodata =
true;
298 else {
iov[2].iov_base = (
char *)payload;
299 iov[2].iov_len = paysize;
304 if (!GetSHA2(secHash,
iov, n))
return -EDOM;
309 {rc = authProt->Encrypt((
const char *)secHash,
sizeof(secHash),&myReq.bP);
310 if (rc < 0)
return rc;
311 sigSize = myReq.bP->
size;
312 sigBuff = myReq.bP->buffer;
314 sigSize =
sizeof(secHash);
315 sigBuff = (
char *)secHash;
322 if (!myReq.P)
return -ENOMEM;
327 memcpy(&(myReq.P->secReq.header.streamid ), thereq.
header.
streamid,
328 sizeof(myReq.P->secReq.header.streamid));
330 sizeof(myReq.P->secReq.sigver.expectrid));
331 myReq.P->secReq.sigver.seqno = mySeq;
332 if (nodata) myReq.P->secReq.sigver.flags |=
kXR_nodata;
333 myReq.P->secReq.sigver.dlen = htonl(sigSize);
337 memcpy(&(myReq.P->secSig), sigBuff, sigSize);
341 newreq = &(myReq.P->secReq); myReq.P = 0;
351 unsigned int lvl, vsz;
356 {memset(&myReqs, 0,
sizeof(myReqs));
369 secVec = secTable.Vec[lvl-1];
373 myReqs.secopt = inReqs.
secopt;
383 memcpy(myVec, secVec, maxRIX);
385 for (
unsigned int i = 0; i < vsz; i++, urVec++)
406 buffHold() : bP(0) {}
407 ~buffHold() {
if (bP)
delete bP;}
409 static const int iovNum = 3;
410 struct iovec
iov[iovNum];
412 unsigned char *inHash, secHash[SHA256_DIGEST_LENGTH];
419 if (memcmp(&lastSeqno, &secreq.
sigver.
seqno,
sizeof(lastSeqno)) >= 0)
420 return "Incorrect signature sequence";
426 return "Signature streamid mismatch";
428 return "Signature requestid mismatch";
430 return "Unsupported signature version";
432 return "Unsupported signature hash";
434 return "Unsupported signature key";
444 {rc = authProt->Decrypt((
const char *)inHash, dlen, &myReq.bP);
446 if (myReq.bP->size != (
int)
sizeof(secHash))
447 return "Invalid signature hash length";
448 inHash = (
unsigned char *)myReq.bP->buffer;
450 if (dlen != (
int)
sizeof(secHash))
451 return "Invalid signature hash length";
458 iov[1].iov_base = (
char *)&thereq;
461 else {
iov[2].iov_base = (
char *)thedata;
468 if (!GetSHA2(secHash,
iov, n))
469 return "Signature hash computation failed";
473 if (memcmp(secHash, inHash,
sizeof(secHash)))
474 return "Signature hash mismatch";
struct ClientRequestHdr header
struct ClientSetRequest set
struct ClientOpenRequest open
struct ClientRequestHdr header
ServerResponseSVec_Protocol secvec
struct ClientSigverRequest sigver
struct ClientQueryRequest query
unsigned long long kXR_unt64
static EVP_MD_CTX * EVP_MD_CTX_new()
static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
const char * XrdSysE2T(int errcode)
virtual const char * Verify(SecurityRequest &secreq, ClientRequest &thereq, const char *thedata)
void SetProtection(const ServerResponseReqs_Protocol &inReqs)
virtual int Secure(SecurityRequest *&newreq, ClientRequest &thereq, const char *thedata)
Generic structure to pass security information back and forth.