21 #include "kinetic/hmac_provider.h"
24 #include <arpa/inet.h>
26 #include <openssl/hmac.h>
27 #include <openssl/sha.h>
28 #include "glog/logging.h"
32 using com::seagate::kinetic::client::proto::Message;
34 HmacProvider::HmacProvider() {}
36 std::string HmacProvider::ComputeHmac(
const Message& message,
37 const std::string& key)
const {
38 HMAC_CTX *ctx = HMAC_CTX_new();
39 HMAC_Init_ex(ctx, key.c_str(), key.length(), EVP_sha1(), NULL);
41 if (message.commandbytes().length() != 0) {
42 uint32_t message_length_bigendian = htonl(message.commandbytes().length());
43 HMAC_Update(ctx, reinterpret_cast<unsigned char *>(&message_length_bigendian),
45 HMAC_Update(ctx, reinterpret_cast<const unsigned char *>(message.commandbytes().c_str()),
46 message.commandbytes().length());
49 unsigned char result[SHA_DIGEST_LENGTH];
50 unsigned int result_length = SHA_DIGEST_LENGTH;
51 HMAC_Final(ctx, result, &result_length);
54 return std::string(reinterpret_cast<char *>(result), result_length);
57 bool HmacProvider::ValidateHmac(
const Message& message,
const std::string& key)
const {
58 std::string correct_hmac(ComputeHmac(message, key));
60 if (!message.has_hmacauth()) {
64 const std::string &provided_hmac = message.hmacauth().hmac();
66 if (provided_hmac.length() != correct_hmac.length()) {
71 for (
size_t i = 0; i < correct_hmac.length(); i++) {
72 result |= provided_hmac[i] ^ correct_hmac[i];