Logger System 1.0.0
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
kcenon::logger::security::hmac_sha256_integrity_policy Class Referencefinal

HMAC-SHA256 integrity policy (ISO/IEC 27001 A.12.4.2 default). More...

#include <integrity_policy.h>

Inheritance diagram for kcenon::logger::security::hmac_sha256_integrity_policy:
Inheritance graph
Collaboration diagram for kcenon::logger::security::hmac_sha256_integrity_policy:
Collaboration graph

Public Member Functions

 hmac_sha256_integrity_policy (secure_key key)
 Construct from a secure_key.
 
std::string sign (const std::string &record) const override
 Produce a signature for record.
 
bool verify (const std::string &record, const std::string &signature) const override
 Verify that signature matches record.
 
std::string name () const override
 Short identifier used as a prefix in serialized signatures (e.g. "HMAC-SHA256"). Implementations must return a stable non-empty ASCII string.
 
- Public Member Functions inherited from kcenon::logger::security::integrity_policy
virtual ~integrity_policy ()=default
 

Static Private Member Functions

static std::string compute_hmac (const std::string &message, const secure_key &key)
 

Private Attributes

std::shared_ptr< secure_keykey_
 

Detailed Description

HMAC-SHA256 integrity policy (ISO/IEC 27001 A.12.4.2 default).

Uses OpenSSL's EVP_MAC API when available; otherwise falls back to a portable, non-cryptographic hash. The fallback is functionally correct (sign/verify round-trip) but MUST NOT be relied on for tamper detection in production. Build with OpenSSL 3.x to get real HMAC-SHA256.

Thread-safety: instances are immutable after construction; sign() and verify() may be called concurrently.

Definition at line 93 of file integrity_policy.h.

Constructor & Destructor Documentation

◆ hmac_sha256_integrity_policy()

kcenon::logger::security::hmac_sha256_integrity_policy::hmac_sha256_integrity_policy ( secure_key key)
inlineexplicit

Construct from a secure_key.

Parameters
keyHMAC key (moved in; policy takes ownership).

The key is stored in a secure_key to guarantee zeroization on destruction (see secure_key_storage.h).

Definition at line 102 of file integrity_policy.h.

103 : key_(std::make_shared<secure_key>(std::move(key))) {
104 }

Member Function Documentation

◆ compute_hmac()

static std::string kcenon::logger::security::hmac_sha256_integrity_policy::compute_hmac ( const std::string & message,
const secure_key & key )
inlinestaticprivate

Definition at line 133 of file integrity_policy.h.

134 {
135#ifdef LOGGER_INTEGRITY_HAS_OPENSSL
136 unsigned char digest[EVP_MAX_MD_SIZE];
137 size_t digest_len = 0;
138
139 EVP_MAC* mac = EVP_MAC_fetch(nullptr, "HMAC", nullptr);
140 if (!mac) {
141 return std::string();
142 }
143
144 EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac);
145 if (!ctx) {
146 EVP_MAC_free(mac);
147 return std::string();
148 }
149
150 OSSL_PARAM params[] = {
151 OSSL_PARAM_construct_utf8_string(
152 OSSL_MAC_PARAM_DIGEST,
153 const_cast<char*>("SHA256"),
154 0),
155 OSSL_PARAM_END
156 };
157
158 if (EVP_MAC_init(ctx, key.data().data(), key.size(), params) != 1) {
159 EVP_MAC_CTX_free(ctx);
160 EVP_MAC_free(mac);
161 return std::string();
162 }
163
164 if (EVP_MAC_update(
165 ctx,
166 reinterpret_cast<const unsigned char*>(message.data()),
167 message.size()) != 1) {
168 EVP_MAC_CTX_free(ctx);
169 EVP_MAC_free(mac);
170 return std::string();
171 }
172
173 if (EVP_MAC_final(ctx, digest, &digest_len, sizeof(digest)) != 1) {
174 EVP_MAC_CTX_free(ctx);
175 EVP_MAC_free(mac);
176 return std::string();
177 }
178
179 EVP_MAC_CTX_free(ctx);
180 EVP_MAC_free(mac);
181
182 std::ostringstream hex;
183 hex << std::hex << std::setfill('0');
184 for (size_t i = 0; i < digest_len; ++i) {
185 hex << std::setw(2) << static_cast<int>(digest[i]);
186 }
187 return hex.str();
188#else
189 // Portable fallback. NOT cryptographically secure; intended only
190 // to keep sign/verify round-trip working on builds without OpenSSL.
191 std::size_t hash = 0xcbf29ce484222325ULL;
192 for (size_t i = 0; i < message.size(); ++i) {
193 hash ^= static_cast<unsigned char>(message[i]);
194 hash *= 0x100000001b3ULL;
195 if (i < key.size()) {
196 hash ^= key.data()[i];
197 }
198 }
199 std::ostringstream oss;
200 oss << std::hex << std::setfill('0') << std::setw(16) << hash;
201 return oss.str();
202#endif
203 }

References kcenon::logger::security::secure_key::data(), and kcenon::logger::security::secure_key::size().

Referenced by sign(), and verify().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ name()

std::string kcenon::logger::security::hmac_sha256_integrity_policy::name ( ) const
inlineoverridevirtual

Short identifier used as a prefix in serialized signatures (e.g. "HMAC-SHA256"). Implementations must return a stable non-empty ASCII string.

Implements kcenon::logger::security::integrity_policy.

Definition at line 128 of file integrity_policy.h.

128 {
129 return "HMAC-SHA256";
130 }

◆ sign()

std::string kcenon::logger::security::hmac_sha256_integrity_policy::sign ( const std::string & record) const
inlineoverridevirtual

Produce a signature for record.

Parameters
recordThe serialized log record to sign.
Returns
Hex-encoded signature, or empty string on failure.

Implements kcenon::logger::security::integrity_policy.

Definition at line 106 of file integrity_policy.h.

106 {
107 return compute_hmac(record, *key_);
108 }
static std::string compute_hmac(const std::string &message, const secure_key &key)

References compute_hmac(), and key_.

Here is the call graph for this function:

◆ verify()

bool kcenon::logger::security::hmac_sha256_integrity_policy::verify ( const std::string & record,
const std::string & signature ) const
inlineoverridevirtual

Verify that signature matches record.

Parameters
recordThe original log record.
signatureThe signature previously emitted by sign().
Returns
true if the signature is valid, false otherwise.

Implements kcenon::logger::security::integrity_policy.

Definition at line 110 of file integrity_policy.h.

111 {
112 if (signature.empty()) {
113 return false;
114 }
115 const std::string expected = compute_hmac(record, *key_);
116 if (expected.empty() || expected.size() != signature.size()) {
117 return false;
118 }
119 // Constant-time compare to avoid signature-timing leaks.
120 unsigned char diff = 0;
121 for (size_t i = 0; i < expected.size(); ++i) {
122 diff |= static_cast<unsigned char>(expected[i])
123 ^ static_cast<unsigned char>(signature[i]);
124 }
125 return diff == 0;
126 }

References compute_hmac(), and key_.

Here is the call graph for this function:

Member Data Documentation

◆ key_

std::shared_ptr<secure_key> kcenon::logger::security::hmac_sha256_integrity_policy::key_
private

Definition at line 207 of file integrity_policy.h.

Referenced by sign(), and verify().


The documentation for this class was generated from the following file: