43#include <openssl/hmac.h>
44#include <openssl/bio.h>
45#include <openssl/buffer.h>
46#include <openssl/err.h>
47#include <openssl/ssl.h>
48# include "sys/param.h"
60void Tobase64(
const unsigned char *input,
int length,
char *out) {
68 b64 = BIO_new(BIO_f_base64());
69 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
70 bmem = BIO_new(BIO_s_mem());
72 BIO_write(b64, input, length);
74 if (BIO_flush(b64) <= 0) {
79 BIO_get_mem_ptr(b64, &bptr);
82 memcpy(out, bptr->data, bptr->length);
83 out[bptr->length] =
'\0';
90void Tobase64(
const std::vector<uint8_t> & input, std::string & base64Output) {
100 b64 = BIO_new(BIO_f_base64());
101 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
102 bmem = BIO_new(BIO_s_mem());
104 BIO_write(b64, input.data(), input.size());
106 if (BIO_flush(b64) <= 0) {
111 BIO_get_mem_ptr(b64, &bptr);
113 base64Output.assign(bptr->data,bptr->length);
118void base64ToBytes(
const std::string & base64digest, std::vector<uint8_t> & outputBytes) {
121 if (base64digest.empty()) {
125 BIO *b64 = BIO_new(BIO_f_base64());
126 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
128 BIO *bmem = BIO_new_mem_buf(base64digest.data(),
static_cast<int>(base64digest.size()));
129 bmem = BIO_push(b64, bmem);
132 std::vector<uint8_t> buffer(base64digest.size());
134 int decodedLen = BIO_read(bmem, buffer.data(),
static_cast<int>(buffer.size()));
135 if (decodedLen > 0) {
136 buffer.resize(decodedLen);
137 outputBytes.swap(buffer);
145void bytesToHex(
const std::vector<uint8_t> & bytes, std::string & output) {
146 static const char* lut =
"0123456789abcdef";
148 output.reserve(bytes.size() * 2);
149 for (uint8_t b : bytes) {
150 output.push_back(lut[b >> 4]);
151 output.push_back(lut[b & 0x0F]);
156 std::vector<uint8_t> bytes;
165 unsigned char c =
static_cast<unsigned char>(ch);
166 if (std::isdigit(c)) {
170 if (c >=
'a' && c <=
'f') {
177bool Fromhexdigest(
const std::string & hex, std::vector<uint8_t> & outputBytes) {
178 if(hex.size() % 2 != 0) {
182 outputBytes.reserve(hex.size() / 2);
184 for(
size_t i = 0; i < hex.size(); i += 2) {
187 if (upper < 0 || lower < 0)
return false;
188 outputBytes.push_back(
static_cast<uint8_t
>((upper << 4) + lower));
197 sprintf(buf,
"%ld", i);
206 char *ptr = strchr((
char *)s, c);
209 return strchr((
char *)s,
'\0');
245#if OPENSSL_VERSION_NUMBER >= 0x30000000L
253 unsigned char mdbuf[EVP_MAX_MD_SIZE];
267 if (!fn || !secent) {
271#if OPENSSL_VERSION_NUMBER >= 0x30000000L
273 if (!(mac = EVP_MAC_fetch(
nullptr,
"HMAC",
nullptr))) {
277 if (!(ctx = EVP_MAC_CTX_new(mac))) {
282 OSSL_PARAM params[2] = {
283 OSSL_PARAM_construct_utf8_string(
"digest", (
char*)
"SHA256", 0),
284 OSSL_PARAM_construct_end()
287 if (!EVP_MAC_init(ctx, (
const unsigned char *) key, strlen(key), params)) {
288 EVP_MAC_CTX_free(ctx);
294 EVP_MAC_update(ctx, (
const unsigned char *) fn,
297 EVP_MAC_update(ctx, (
const unsigned char *) &request,
301 EVP_MAC_update(ctx, (
const unsigned char *) secent->
name,
302 strlen(secent->
name) + 1);
305 EVP_MAC_update(ctx, (
const unsigned char *) secent->
vorg,
306 strlen(secent->
vorg) + 1);
309 EVP_MAC_update(ctx, (
const unsigned char *) secent->
host,
310 strlen(secent->
host) + 1);
313 EVP_MAC_update(ctx, (
const unsigned char *) secent->
moninfo,
316 localtime_r(&tim, &tms);
317 strftime(buf,
sizeof (buf),
"%s", &tms);
318 EVP_MAC_update(ctx, (
const unsigned char *) buf,
321 EVP_MAC_final(ctx, mdbuf, &len, EVP_MAX_MD_SIZE);
323 EVP_MAC_CTX_free(ctx);
328 ctx = HMAC_CTX_new();
336 HMAC_Init_ex(ctx, (
const void *) key, strlen(key), EVP_sha256(), 0);
340 HMAC_Update(ctx, (
const unsigned char *) fn,
343 HMAC_Update(ctx, (
const unsigned char *) &request,
347 HMAC_Update(ctx, (
const unsigned char *) secent->
name,
348 strlen(secent->
name) + 1);
351 HMAC_Update(ctx, (
const unsigned char *) secent->
vorg,
352 strlen(secent->
vorg) + 1);
355 HMAC_Update(ctx, (
const unsigned char *) secent->
host,
356 strlen(secent->
host) + 1);
359 HMAC_Update(ctx, (
const unsigned char *) secent->
moninfo,
362 localtime_r(&tim, &tms);
363 strftime(buf,
sizeof (buf),
"%s", &tms);
364 HMAC_Update(ctx, (
const unsigned char *) buf,
367 HMAC_Final(ctx, mdbuf, &len);
380 if (h1 == h2)
return 0;
385 return strcmp(h1, h2);
393 char *r = (
char *) malloc(l + 1);
397 for (i = 0; i < l; i++) {
403 char savec = str[i + 3];
406 r[j] = strtol(str + i + 1, 0, 16);
410 }
else r[j] = str[i];
425 char *r = (
char *) malloc(l*3 + 1);
429 for (i = 0; i < l; i++) {
434 strcpy(r + j,
"%20");
438 strcpy(r + j,
"%5B");
442 strcpy(r + j,
"%5D");
446 strcpy(r + j,
"%3A");
454 strcpy(r + j,
"%23");
458 strcpy(r + j,
"%0A");
462 strcpy(r + j,
"%0D");
466 strcpy(r + j,
"%3D");
484 char *r = (
char *) malloc(l*6 + 1);
488 for (i = 0; i < l; i++) {
493 strcpy(r + j,
""");
497 strcpy(r + j,
"&");
501 strcpy(r + j,
"<");
505 strcpy(r + j,
">");
509 strcpy(r + j,
"'");
606 case 100:
return "Continue";
607 case 101:
return "Switching Protocols";
608 case 102:
return "Processing";
609 case 103:
return "Early Hints";
612 case 200:
return "OK";
613 case 201:
return "Created";
614 case 202:
return "Accepted";
615 case 203:
return "Non-Authoritative Information";
616 case 204:
return "No Content";
617 case 205:
return "Reset Content";
618 case 206:
return "Partial Content";
619 case 207:
return "Multi-Status";
620 case 208:
return "Already Reported";
621 case 226:
return "IM Used";
624 case 300:
return "Multiple Choices";
625 case 301:
return "Moved Permanently";
626 case 302:
return "Found";
627 case 303:
return "See Other";
628 case 304:
return "Not Modified";
629 case 305:
return "Use Proxy";
630 case 307:
return "Temporary Redirect";
631 case 308:
return "Permanent Redirect";
634 case 400:
return "Bad Request";
635 case 401:
return "Unauthorized";
636 case 402:
return "Payment Required";
637 case 403:
return "Forbidden";
638 case 404:
return "Not Found";
639 case 405:
return "Method Not Allowed";
640 case 406:
return "Not Acceptable";
641 case 407:
return "Proxy Authentication Required";
642 case 408:
return "Request Timeout";
643 case 409:
return "Conflict";
644 case 410:
return "Gone";
645 case 411:
return "Length Required";
646 case 412:
return "Precondition Failed";
647 case 413:
return "Payload Too Large";
648 case 414:
return "URI Too Long";
649 case 415:
return "Unsupported Media Type";
650 case 416:
return "Range Not Satisfiable";
651 case 417:
return "Expectation Failed";
652 case 418:
return "I'm a teapot";
653 case 421:
return "Misdirected Request";
654 case 422:
return "Unprocessable Entity";
655 case 423:
return "Locked";
656 case 424:
return "Failed Dependency";
657 case 425:
return "Too Early";
658 case 426:
return "Upgrade Required";
659 case 428:
return "Precondition Required";
660 case 429:
return "Too Many Requests";
661 case 431:
return "Request Header Fields Too Large";
662 case 451:
return "Unavailable For Legal Reasons";
665 case 500:
return "Internal Server Error";
666 case 501:
return "Not Implemented";
667 case 502:
return "Bad Gateway";
668 case 503:
return "Service Unavailable";
669 case 504:
return "Gateway Timeout";
670 case 505:
return "HTTP Version Not Supported";
671 case 506:
return "Variant Also Negotiates";
672 case 507:
return "Insufficient Storage";
673 case 508:
return "Loop Detected";
674 case 510:
return "Not Extended";
675 case 511:
return "Network Authentication Required";
679 case 100 ... 199:
return "Informational";
680 case 200 ... 299:
return "Success";
681 case 300 ... 399:
return "Redirection";
682 case 400 ... 499:
return "Client Error";
683 case 500 ... 599:
return "Server Error";
684 default:
return "Unknown";
void Tobase64(const unsigned char *input, int length, char *out)
int compareHash(const char *h1, const char *h2)
static int char_to_int(int ch)
void base64ToBytes(const std::string &base64digest, std::vector< uint8_t > &outputBytes)
char * unquote(char *str)
int mapXrdErrToHttp(XErrorCode xrdError)
char * quote(const char *str)
bool Fromhexdigest(const std::string &hex, std::vector< uint8_t > &outputBytes)
char * escapeXML(const char *str)
int mapErrNoToHttp(int errNo)
char * mystrchrnul(const char *s, int c)
void calcHashes(char *hash, const char *fn, kXR_int16 request, XrdSecEntity *secent, time_t tim, const char *key)
std::string httpStatusToString(int status)
void base64DecodeHex(const std::string &base64, std::string &hexOutput)
void bytesToHex(const std::vector< uint8_t > &bytes, std::string &output)
Utility functions for XrdHTTP.
@ HTTP_INSUFFICIENT_STORAGE
@ HTTP_SERVICE_UNAVAILABLE
@ HTTP_INTERNAL_SERVER_ERROR
@ HTTP_UNPROCESSABLE_ENTITY
static int toErrno(int xerr)
char * vorg
Entity's virtual organization(s)
char * name
Entity's name.
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.