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"
84 XrdSecVec(
int arg, ...)
87 memset(Vec, 0,
sizeof(Vec));
89 reqCode = va_arg(ap,
int);
92 {sVal = va_arg(ap,
int);
93 Vec[i][reqCode-
kXR_auth] =
static_cast<char>(sVal);
95 reqCode = va_arg(ap,
int);
109 XrdSecVec secTable(0,
149 bool XrdSecProtect::GetSHA2(
unsigned char *hBuff,
struct iovec *iovP,
int iovN)
152 EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
153 const EVP_MD *md = EVP_get_digestbyname(
"sha256");
157 if (1 != EVP_DigestInit_ex(mdctx, md, 0))
goto err;
161 for (
int i = 0; i < iovN; i++)
163 if (1 != EVP_DigestUpdate(mdctx, iovP[i].iov_base, iovP[i].iov_len))
169 if (1 != EVP_DigestFinal_ex(mdctx, hBuff, 0))
goto err;
173 EVP_MD_CTX_free (mdctx);
190 if (reqCode < kXR_auth || reqCode >=
kXR_REQFENCE || !secVec)
return false;
205 return (
opts & rwOpen) != 0;
222 default:
return false;
249 buffHold() : P(0), bP(0) {}
250 ~buffHold() {
if (P) free(P);
if (bP)
delete bP;}
252 static const int iovNum = 3;
253 struct iovec
iov[iovNum];
256 const char *sigBuff, *payload = thedata;
257 unsigned char secHash[SHA256_DIGEST_LENGTH];
258 int sigSize, n, newSize, rc, paysize = 0;
264 mySeq = htonll(mySeq);
271 if (!payload) payload = ((
char *)&thereq) +
sizeof(
ClientRequest);
278 iov[0].iov_base = (
char *)&mySeq;
279 iov[0].iov_len =
sizeof(mySeq);
280 iov[1].iov_base = (
char *)&thereq;
282 if (n < 3) nodata =
true;
283 else {
iov[2].iov_base = (
char *)payload;
284 iov[2].iov_len = paysize;
289 if (!GetSHA2(secHash,
iov, n))
return -EDOM;
294 {rc = authProt->Encrypt((
const char *)secHash,
sizeof(secHash),&myReq.bP);
295 if (rc < 0)
return rc;
296 sigSize = myReq.bP->
size;
297 sigBuff = myReq.bP->buffer;
299 sigSize =
sizeof(secHash);
300 sigBuff = (
char *)secHash;
307 if (!myReq.P)
return -ENOMEM;
312 memcpy(&(myReq.P->secReq.header.streamid ), thereq.
header.
streamid,
313 sizeof(myReq.P->secReq.header.streamid));
315 sizeof(myReq.P->secReq.sigver.expectrid));
316 myReq.P->secReq.sigver.seqno = mySeq;
317 if (nodata) myReq.P->secReq.sigver.flags |=
kXR_nodata;
318 myReq.P->secReq.sigver.dlen = htonl(sigSize);
322 memcpy(&(myReq.P->secSig), sigBuff, sigSize);
326 newreq = &(myReq.P->secReq); myReq.P = 0;
336 unsigned int lvl, vsz;
341 {memset(&myReqs, 0,
sizeof(myReqs));
354 secVec = secTable.Vec[lvl-1];
358 myReqs.secopt = inReqs.
secopt;
368 memcpy(myVec, secVec, maxRIX);
370 for (
unsigned int i = 0; i < vsz; i++, urVec++)
391 buffHold() : bP(0) {}
392 ~buffHold() {
if (bP)
delete bP;}
394 static const int iovNum = 3;
395 struct iovec
iov[iovNum];
397 unsigned char *inHash, secHash[SHA256_DIGEST_LENGTH];
404 if (memcmp(&lastSeqno, &secreq.
sigver.
seqno,
sizeof(lastSeqno)) >= 0)
405 return "Incorrect signature sequence";
411 return "Signature streamid mismatch";
413 return "Signature requestid mismatch";
415 return "Unsupported signature version";
417 return "Unsupported signature hash";
419 return "Unsupported signature key";
429 {rc = authProt->Decrypt((
const char *)inHash, dlen, &myReq.bP);
431 if (myReq.bP->size != (
int)
sizeof(secHash))
432 return "Invalid signature hash length";
433 inHash = (
unsigned char *)myReq.bP->buffer;
435 if (dlen != (
int)
sizeof(secHash))
436 return "Invalid signature hash length";
443 iov[1].iov_base = (
char *)&thereq;
446 else {
iov[2].iov_base = (
char *)thedata;
453 if (!GetSHA2(secHash,
iov, n))
454 return "Signature hash computation failed";
458 if (memcmp(secHash, inHash,
sizeof(secHash)))
459 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
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.