PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::security::certificate Class Reference

#include <certificate.h>

Collaboration diagram for kcenon::pacs::security::certificate:
Collaboration graph

Public Member Functions

 certificate ()
 Default constructor - creates an empty certificate.
 
 certificate (const certificate &other)
 Copy constructor.
 
 certificate (certificate &&other) noexcept
 Move constructor.
 
auto operator= (const certificate &other) -> certificate &
 Copy assignment.
 
auto operator= (certificate &&other) noexcept -> certificate &
 Move assignment.
 
 ~certificate ()
 Destructor.
 
auto subject_name () const -> std::string
 Get the subject distinguished name.
 
auto subject_common_name () const -> std::string
 Get the common name from the subject.
 
auto subject_organization () const -> std::string
 Get the organization from the subject.
 
auto issuer_name () const -> std::string
 Get the issuer distinguished name.
 
auto serial_number () const -> std::string
 Get the certificate serial number.
 
auto thumbprint () const -> std::string
 Get the certificate thumbprint (SHA-256)
 
auto not_before () const -> std::chrono::system_clock::time_point
 Get the not-before date.
 
auto not_after () const -> std::chrono::system_clock::time_point
 Get the not-after date.
 
auto is_valid () const -> bool
 Check if the certificate is currently valid.
 
auto is_expired () const -> bool
 Check if the certificate has expired.
 
auto to_pem () const -> std::string
 Export certificate as PEM string.
 
auto to_der () const -> std::vector< std::uint8_t >
 Export certificate as DER bytes.
 
auto is_loaded () const noexcept -> bool
 Check if certificate is loaded.
 
auto impl () const noexcept -> const certificate_impl *
 Get internal implementation (for internal use only)
 
auto impl () noexcept -> certificate_impl *
 

Static Public Member Functions

static auto load_from_pem (std::string_view path) -> kcenon::common::Result< certificate >
 Load certificate from PEM file.
 
static auto load_from_pem_string (std::string_view pem_data) -> kcenon::common::Result< certificate >
 Load certificate from PEM string.
 
static auto load_from_der (std::span< const std::uint8_t > der_data) -> kcenon::common::Result< certificate >
 Load certificate from DER-encoded bytes.
 

Private Attributes

std::unique_ptr< certificate_implimpl_
 

Friends

class certificate_chain
 

Detailed Description

Definition at line 56 of file certificate.h.

Constructor & Destructor Documentation

◆ certificate() [1/3]

kcenon::pacs::security::certificate::certificate ( )

Default constructor - creates an empty certificate.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 214 of file certificate.cpp.

214: impl_(std::make_unique<certificate_impl>()) {}
std::unique_ptr< certificate_impl > impl_

◆ certificate() [2/3]

kcenon::pacs::security::certificate::certificate ( const certificate & other)

Copy constructor.

Definition at line 216 of file certificate.cpp.

217 : impl_(std::make_unique<certificate_impl>(*other.impl_)) {}

◆ certificate() [3/3]

kcenon::pacs::security::certificate::certificate ( certificate && other)
defaultnoexcept

Move constructor.

◆ ~certificate()

kcenon::pacs::security::certificate::~certificate ( )
default

Member Function Documentation

◆ impl() [1/2]

auto kcenon::pacs::security::certificate::impl ( ) const -> const certificate_impl*
nodiscardnoexcept

Get internal implementation (for internal use only)

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 508 of file certificate.cpp.

508 {
509 return impl_.get();
510}

References impl_.

Referenced by kcenon::pacs::security::get_x509_from_certificate().

Here is the caller graph for this function:

◆ impl() [2/2]

auto kcenon::pacs::security::certificate::impl ( ) -> certificate_impl*
nodiscardnoexcept

Definition at line 512 of file certificate.cpp.

512 {
513 return impl_.get();
514}

References impl_.

◆ is_expired()

auto kcenon::pacs::security::certificate::is_expired ( ) const -> bool
nodiscard

Check if the certificate has expired.

Returns
true if certificate has expired
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 464 of file certificate.cpp.

464 {
465 if (!impl_->is_loaded()) {
466 return true;
467 }
468
469 auto now = std::chrono::system_clock::now();
470 return now > not_after();
471}
auto not_after() const -> std::chrono::system_clock::time_point
Get the not-after date.

References impl_, and not_after().

Here is the call graph for this function:

◆ is_loaded()

auto kcenon::pacs::security::certificate::is_loaded ( ) const -> bool
nodiscardnoexcept

Check if certificate is loaded.

Returns
true if certificate data is loaded
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 504 of file certificate.cpp.

504 {
505 return impl_ && impl_->is_loaded();
506}

References impl_.

◆ is_valid()

auto kcenon::pacs::security::certificate::is_valid ( ) const -> bool
nodiscard

Check if the certificate is currently valid.

Returns
true if current time is within validity period
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 455 of file certificate.cpp.

455 {
456 if (!impl_->is_loaded()) {
457 return false;
458 }
459
460 auto now = std::chrono::system_clock::now();
461 return now >= not_before() && now <= not_after();
462}
auto not_before() const -> std::chrono::system_clock::time_point
Get the not-before date.

References impl_, not_after(), and not_before().

Here is the call graph for this function:

◆ issuer_name()

auto kcenon::pacs::security::certificate::issuer_name ( ) const -> std::string
nodiscard

Get the issuer distinguished name.

Returns
Issuer name
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 368 of file certificate.cpp.

368 {
369 if (!impl_->is_loaded()) {
370 return "";
371 }
372
373 X509_NAME* name = X509_get_issuer_name(impl_->x509());
374 if (!name) {
375 return "";
376 }
377
378 bio_ptr bio(BIO_new(BIO_s_mem()));
379 X509_NAME_print_ex(bio.get(), name, 0, XN_FLAG_RFC2253);
380
381 char* data = nullptr;
382 long len = BIO_get_mem_data(bio.get(), &data);
383 return std::string(data, static_cast<size_t>(len));
384}
std::string_view name

References impl_, and name.

◆ load_from_der()

auto kcenon::pacs::security::certificate::load_from_der ( std::span< const std::uint8_t > der_data) -> kcenon::common::Result<certificate>
staticnodiscard

Load certificate from DER-encoded bytes.

Parameters
der_dataDER-encoded certificate bytes
Returns
Result containing certificate or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 264 of file certificate.cpp.

265 {
266 const unsigned char* data = der_data.data();
267 X509* x509 = d2i_X509(nullptr, &data, static_cast<long>(der_data.size()));
268 if (!x509) {
269 return kcenon::common::make_error<certificate>(
270 4, "Failed to parse DER certificate: " + get_openssl_error(), "certificate");
271 }
272
273 certificate cert;
274 cert.impl_ = std::make_unique<certificate_impl>(x509);
275 return cert;
276}

References impl_.

Referenced by kcenon::pacs::security::digital_signature::get_signature_info(), kcenon::pacs::security::digital_signature::verify(), and kcenon::pacs::security::digital_signature::verify_with_trust().

Here is the caller graph for this function:

◆ load_from_pem()

auto kcenon::pacs::security::certificate::load_from_pem ( std::string_view path) -> kcenon::common::Result<certificate>
staticnodiscard

Load certificate from PEM file.

Parameters
pathPath to PEM-encoded certificate file
Returns
Result containing certificate or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 232 of file certificate.cpp.

233 {
234 auto content_result = read_file(path);
235 if (content_result.is_err()) {
236 return kcenon::common::make_error<certificate>(
237 content_result.error().code,
238 content_result.error().message,
239 "certificate");
240 }
241
242 return load_from_pem_string(content_result.value());
243}
static auto load_from_pem_string(std::string_view pem_data) -> kcenon::common::Result< certificate >
Load certificate from PEM string.

◆ load_from_pem_string()

auto kcenon::pacs::security::certificate::load_from_pem_string ( std::string_view pem_data) -> kcenon::common::Result<certificate>
staticnodiscard

Load certificate from PEM string.

Parameters
pem_dataPEM-encoded certificate data
Returns
Result containing certificate or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 245 of file certificate.cpp.

246 {
247 bio_ptr bio(BIO_new_mem_buf(pem_data.data(), static_cast<int>(pem_data.size())));
248 if (!bio) {
249 return kcenon::common::make_error<certificate>(
250 2, "Failed to create BIO: " + get_openssl_error(), "certificate");
251 }
252
253 X509* x509 = PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr);
254 if (!x509) {
255 return kcenon::common::make_error<certificate>(
256 3, "Failed to parse PEM certificate: " + get_openssl_error(), "certificate");
257 }
258
259 certificate cert;
260 cert.impl_ = std::make_unique<certificate_impl>(x509);
261 return cert;
262}

References impl_.

◆ not_after()

auto kcenon::pacs::security::certificate::not_after ( ) const -> std::chrono::system_clock::time_point
nodiscard

Get the not-after date.

Returns
End of validity period
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 446 of file certificate.cpp.

446 {
447 if (!impl_->is_loaded()) {
448 return std::chrono::system_clock::time_point{};
449 }
450
451 const ASN1_TIME* time = X509_get0_notAfter(impl_->x509());
452 return asn1_time_to_time_point(time);
453}

References impl_.

Referenced by is_expired(), and is_valid().

Here is the caller graph for this function:

◆ not_before()

auto kcenon::pacs::security::certificate::not_before ( ) const -> std::chrono::system_clock::time_point
nodiscard

Get the not-before date.

Returns
Start of validity period
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 437 of file certificate.cpp.

437 {
438 if (!impl_->is_loaded()) {
439 return std::chrono::system_clock::time_point{};
440 }
441
442 const ASN1_TIME* time = X509_get0_notBefore(impl_->x509());
443 return asn1_time_to_time_point(time);
444}

References impl_.

Referenced by is_valid().

Here is the caller graph for this function:

◆ operator=() [1/2]

auto kcenon::pacs::security::certificate::operator= ( certificate && other) -> certificate &
defaultnoexcept

Move assignment.

◆ operator=() [2/2]

auto kcenon::pacs::security::certificate::operator= ( const certificate & other) -> certificate&

Copy assignment.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 221 of file certificate.cpp.

221 {
222 if (this != &other) {
223 impl_ = std::make_unique<certificate_impl>(*other.impl_);
224 }
225 return *this;
226}

References kcenon::pacs::security::other.

◆ serial_number()

auto kcenon::pacs::security::certificate::serial_number ( ) const -> std::string
nodiscard

Get the certificate serial number.

Returns
Serial number as hex string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 386 of file certificate.cpp.

386 {
387 if (!impl_->is_loaded()) {
388 return "";
389 }
390
391 const ASN1_INTEGER* serial = X509_get_serialNumber(impl_->x509());
392 if (!serial) {
393 return "";
394 }
395
396 BIGNUM* bn = ASN1_INTEGER_to_BN(serial, nullptr);
397 if (!bn) {
398 return "";
399 }
400
401 char* hex = BN_bn2hex(bn);
402 BN_free(bn);
403
404 if (!hex) {
405 return "";
406 }
407
408 std::string result(hex);
409 OPENSSL_free(hex);
410 return result;
411}

References impl_.

◆ subject_common_name()

auto kcenon::pacs::security::certificate::subject_common_name ( ) const -> std::string
nodiscard

Get the common name from the subject.

Returns
Common name (CN) or empty string if not present
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 296 of file certificate.cpp.

296 {
297 if (!impl_->is_loaded()) {
298 return "";
299 }
300
301 X509_NAME* name = X509_get_subject_name(impl_->x509());
302 if (!name) {
303 return "";
304 }
305
306 int idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
307 if (idx < 0) {
308 return "";
309 }
310
311 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx);
312 if (!entry) {
313 return "";
314 }
315
316 ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
317 if (!data) {
318 return "";
319 }
320
321 unsigned char* utf8 = nullptr;
322 int len = ASN1_STRING_to_UTF8(&utf8, data);
323 if (len < 0) {
324 return "";
325 }
326
327 std::string result(reinterpret_cast<char*>(utf8), static_cast<size_t>(len));
328 OPENSSL_free(utf8);
329 return result;
330}

References impl_, and name.

◆ subject_name()

auto kcenon::pacs::security::certificate::subject_name ( ) const -> std::string
nodiscard

Get the subject distinguished name.

Returns
Subject name (e.g., "CN=John Doe,O=Hospital,C=US")
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 278 of file certificate.cpp.

278 {
279 if (!impl_->is_loaded()) {
280 return "";
281 }
282
283 X509_NAME* name = X509_get_subject_name(impl_->x509());
284 if (!name) {
285 return "";
286 }
287
288 bio_ptr bio(BIO_new(BIO_s_mem()));
289 X509_NAME_print_ex(bio.get(), name, 0, XN_FLAG_RFC2253);
290
291 char* data = nullptr;
292 long len = BIO_get_mem_data(bio.get(), &data);
293 return std::string(data, static_cast<size_t>(len));
294}

References impl_, and name.

◆ subject_organization()

auto kcenon::pacs::security::certificate::subject_organization ( ) const -> std::string
nodiscard

Get the organization from the subject.

Returns
Organization (O) or empty string if not present
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 332 of file certificate.cpp.

332 {
333 if (!impl_->is_loaded()) {
334 return "";
335 }
336
337 X509_NAME* name = X509_get_subject_name(impl_->x509());
338 if (!name) {
339 return "";
340 }
341
342 int idx = X509_NAME_get_index_by_NID(name, NID_organizationName, -1);
343 if (idx < 0) {
344 return "";
345 }
346
347 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx);
348 if (!entry) {
349 return "";
350 }
351
352 ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
353 if (!data) {
354 return "";
355 }
356
357 unsigned char* utf8 = nullptr;
358 int len = ASN1_STRING_to_UTF8(&utf8, data);
359 if (len < 0) {
360 return "";
361 }
362
363 std::string result(reinterpret_cast<char*>(utf8), static_cast<size_t>(len));
364 OPENSSL_free(utf8);
365 return result;
366}

References impl_, and name.

◆ thumbprint()

auto kcenon::pacs::security::certificate::thumbprint ( ) const -> std::string
nodiscard

Get the certificate thumbprint (SHA-256)

Returns
Thumbprint as hex string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 413 of file certificate.cpp.

413 {
414 if (!impl_->is_loaded()) {
415 return "";
416 }
417
418 unsigned char hash[EVP_MAX_MD_SIZE];
419 unsigned int hash_len = 0;
420
421 if (X509_digest(impl_->x509(), EVP_sha256(), hash, &hash_len) != 1) {
422 return "";
423 }
424
425 std::string result;
426 result.reserve(hash_len * 2);
427
428 static const char hex_chars[] = "0123456789ABCDEF";
429 for (unsigned int i = 0; i < hash_len; ++i) {
430 result += hex_chars[(hash[i] >> 4) & 0x0F];
431 result += hex_chars[hash[i] & 0x0F];
432 }
433
434 return result;
435}
@ hash
Hash the value for research linkage.

References kcenon::pacs::security::hash, and impl_.

◆ to_der()

auto kcenon::pacs::security::certificate::to_der ( ) const -> std::vector<std::uint8_t>
nodiscard

Export certificate as DER bytes.

Returns
DER-encoded certificate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 488 of file certificate.cpp.

488 {
489 if (!impl_->is_loaded()) {
490 return {};
491 }
492
493 unsigned char* data = nullptr;
494 int len = i2d_X509(impl_->x509(), &data);
495 if (len <= 0) {
496 return {};
497 }
498
499 std::vector<std::uint8_t> result(data, data + len);
500 OPENSSL_free(data);
501 return result;
502}

References impl_.

◆ to_pem()

auto kcenon::pacs::security::certificate::to_pem ( ) const -> std::string
nodiscard

Export certificate as PEM string.

Returns
PEM-encoded certificate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/certificate.h.

Definition at line 473 of file certificate.cpp.

473 {
474 if (!impl_->is_loaded()) {
475 return "";
476 }
477
478 bio_ptr bio(BIO_new(BIO_s_mem()));
479 if (PEM_write_bio_X509(bio.get(), impl_->x509()) != 1) {
480 return "";
481 }
482
483 char* data = nullptr;
484 long len = BIO_get_mem_data(bio.get(), &data);
485 return std::string(data, static_cast<size_t>(len));
486}

References impl_.

Friends And Related Symbol Documentation

◆ certificate_chain

Member Data Documentation

◆ impl_


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