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

#include <digital_signature.h>

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

Static Public Member Functions

static auto sign (core::dicom_dataset &dataset, const certificate &cert, const private_key &key, signature_algorithm algo=signature_algorithm::rsa_sha256) -> kcenon::common::VoidResult
 Sign a DICOM dataset.
 
static auto sign_tags (core::dicom_dataset &dataset, const certificate &cert, const private_key &key, std::span< const core::dicom_tag > tags_to_sign, signature_algorithm algo=signature_algorithm::rsa_sha256) -> kcenon::common::VoidResult
 Sign specific tags in a DICOM dataset.
 
static auto verify (const core::dicom_dataset &dataset) -> kcenon::common::Result< signature_status >
 Verify digital signatures in a dataset.
 
static auto verify_with_trust (const core::dicom_dataset &dataset, const std::vector< certificate > &trusted_certs) -> kcenon::common::Result< signature_status >
 Verify digital signatures with a trusted certificate store.
 
static auto get_signature_info (const core::dicom_dataset &dataset) -> std::optional< signature_info >
 Get information about signatures in a dataset.
 
static auto get_all_signatures (const core::dicom_dataset &dataset) -> std::vector< signature_info >
 Get all signatures in a dataset.
 
static auto has_signature (const core::dicom_dataset &dataset) -> bool
 Check if a dataset contains digital signatures.
 
static auto remove_signatures (core::dicom_dataset &dataset) -> bool
 Remove all digital signatures from a dataset.
 
static auto generate_signature_uid () -> std::string
 Generate a new Digital Signature UID.
 

Static Private Member Functions

static auto compute_mac (const core::dicom_dataset &dataset, std::span< const core::dicom_tag > tags, mac_algorithm algo) -> std::vector< std::uint8_t >
 
static auto sign_mac (std::span< const std::uint8_t > mac_data, const private_key &key, signature_algorithm algo) -> kcenon::common::Result< std::vector< std::uint8_t > >
 
static auto verify_mac_signature (std::span< const std::uint8_t > mac_data, std::span< const std::uint8_t > signature, const certificate &cert, signature_algorithm algo) -> bool
 

Detailed Description

Definition at line 68 of file digital_signature.h.

Member Function Documentation

◆ compute_mac()

auto kcenon::pacs::security::digital_signature::compute_mac ( const core::dicom_dataset & dataset,
std::span< const core::dicom_tag > tags,
mac_algorithm algo ) -> std::vector<std::uint8_t>
staticprivate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 602 of file digital_signature.cpp.

606 {
607 // Serialize elements
608 auto data = serialize_elements_for_mac(dataset, tags);
609
610 // Compute hash
611 const EVP_MD* md = get_mac_evp_md(algo);
612 unsigned int md_len = EVP_MD_size(md);
613
614 std::vector<std::uint8_t> result(md_len);
615
616 evp_md_ctx_ptr ctx(EVP_MD_CTX_new());
617 if (!ctx) {
618 return {};
619 }
620
621 if (EVP_DigestInit_ex(ctx.get(), md, nullptr) != 1) {
622 return {};
623 }
624
625 if (EVP_DigestUpdate(ctx.get(), data.data(), data.size()) != 1) {
626 return {};
627 }
628
629 if (EVP_DigestFinal_ex(ctx.get(), result.data(), &md_len) != 1) {
630 return {};
631 }
632
633 result.resize(md_len);
634 return result;
635}

◆ generate_signature_uid()

auto kcenon::pacs::security::digital_signature::generate_signature_uid ( ) -> std::string
staticnodiscard

Generate a new Digital Signature UID.

Creates a new unique identifier for a digital signature.

Returns
New UID string
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 598 of file digital_signature.cpp.

598 {
599 return generate_uid();
600}
std::string generate_uid(const std::string &root="1.2.826.0.1.3680043.9.9999")
Generate a unique UID for testing.

◆ get_all_signatures()

auto kcenon::pacs::security::digital_signature::get_all_signatures ( const core::dicom_dataset & dataset) -> std::vector<signature_info>
staticnodiscard

Get all signatures in a dataset.

Extracts information for all signatures if multiple are present.

Parameters
datasetThe dataset to inspect
Returns
Vector of signature info (empty if no signatures)
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 556 of file digital_signature.cpp.

558 {
559 // For this simplified implementation, we only support one signature
560 std::vector<signature_info> result;
561
562 auto info = get_signature_info(dataset);
563 if (info) {
564 result.push_back(std::move(*info));
565 }
566
567 return result;
568}
static auto get_signature_info(const core::dicom_dataset &dataset) -> std::optional< signature_info >
Get information about signatures in a dataset.

◆ get_signature_info()

auto kcenon::pacs::security::digital_signature::get_signature_info ( const core::dicom_dataset & dataset) -> std::optional<signature_info>
staticnodiscard

Get information about signatures in a dataset.

Extracts signature metadata from the Digital Signature Sequence without performing verification.

Parameters
datasetThe dataset to inspect
Returns
Optional containing signature info, or nullopt if no signature
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 506 of file digital_signature.cpp.

508 {
509 if (!has_signature(dataset)) {
510 return std::nullopt;
511 }
512
513 signature_info info;
514
515 // Get signature UID
516 info.signature_uid = dataset.get_string(signature_uid_tag);
517
518 // Get timestamp
519 std::string dt_str = dataset.get_string(signature_datetime_tag);
520 if (!dt_str.empty()) {
521 info.timestamp = parse_dicom_datetime(dt_str);
522 }
523
524 // Get certificate and extract signer info
525 const auto* cert_elem = dataset.get(certificate_of_signer_tag);
526 if (cert_elem) {
527 auto cert_result = certificate::load_from_der(cert_elem->raw_data());
528 if (cert_result.is_ok()) {
529 const auto& cert = cert_result.value();
530 info.signer_name = cert.subject_common_name();
531 info.signer_organization = cert.subject_organization();
532 info.certificate_thumbprint = cert.thumbprint();
533 }
534 }
535
536 // Default algorithm (could be extracted from MAC algorithm tag)
538
539 // Get signed tags
540 const auto* signed_tags_elem = dataset.get(data_elements_signed_tag);
541 if (signed_tags_elem) {
542 const auto& tag_data = signed_tags_elem->raw_data();
543 for (size_t i = 0; i + 3 < tag_data.size(); i += 4) {
544 uint16_t group = static_cast<uint16_t>(tag_data[i]) |
545 (static_cast<uint16_t>(tag_data[i + 1]) << 8);
546 uint16_t element = static_cast<uint16_t>(tag_data[i + 2]) |
547 (static_cast<uint16_t>(tag_data[i + 3]) << 8);
548 info.signed_tags.push_back(
549 (static_cast<uint32_t>(group) << 16) | element);
550 }
551 }
552
553 return info;
554}
static auto load_from_der(std::span< const std::uint8_t > der_data) -> kcenon::common::Result< certificate >
Load certificate from DER-encoded bytes.
static auto has_signature(const core::dicom_dataset &dataset) -> bool
Check if a dataset contains digital signatures.
@ rsa_sha256
RSA with SHA-256 (recommended for most use cases)

References kcenon::pacs::security::certificate::load_from_der(), and kcenon::pacs::security::rsa_sha256.

Here is the call graph for this function:

◆ has_signature()

auto kcenon::pacs::security::digital_signature::has_signature ( const core::dicom_dataset & dataset) -> bool
staticnodiscard

Check if a dataset contains digital signatures.

Parameters
datasetThe dataset to check
Returns
true if Digital Signature Sequence is present
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 570 of file digital_signature.cpp.

572 {
573 // Check for signature tag or signature sequence
574 return dataset.contains(signature_tag) ||
575 dataset.contains(digital_signature_sequence_tag);
576}

◆ remove_signatures()

auto kcenon::pacs::security::digital_signature::remove_signatures ( core::dicom_dataset & dataset) -> bool
static

Remove all digital signatures from a dataset.

Removes the Digital Signature Sequence (0400,0561) from the dataset.

Parameters
datasetThe dataset to modify
Returns
true if signatures were removed, false if none present
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 578 of file digital_signature.cpp.

580 {
581 bool removed = false;
582
583 // Remove all signature-related tags
584 removed |= dataset.remove(digital_signature_sequence_tag);
585 removed |= dataset.remove(signature_uid_tag);
586 removed |= dataset.remove(signature_datetime_tag);
587 removed |= dataset.remove(certificate_type_tag);
588 removed |= dataset.remove(certificate_of_signer_tag);
589 removed |= dataset.remove(signature_tag);
590 removed |= dataset.remove(mac_id_number_tag);
591 removed |= dataset.remove(mac_calculation_transfer_syntax_tag);
592 removed |= dataset.remove(mac_algorithm_tag);
593 removed |= dataset.remove(data_elements_signed_tag);
594
595 return removed;
596}

◆ sign()

auto kcenon::pacs::security::digital_signature::sign ( core::dicom_dataset & dataset,
const certificate & cert,
const private_key & key,
signature_algorithm algo = signature_algorithm::rsa_sha256 ) -> kcenon::common::VoidResult
staticnodiscard

Sign a DICOM dataset.

Creates a digital signature for the entire dataset and adds the Digital Signature Sequence (0400,0561) to the dataset.

Parameters
datasetThe dataset to sign (modified in place)
certSigner's X.509 certificate
keySigner's private key (must match certificate's public key)
algoSignature algorithm to use (default: RSA-SHA256)
Returns
Result indicating success or error
Note
The dataset is modified to include the signature sequence.
All existing data elements are signed by default.
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 289 of file digital_signature.cpp.

294 {
295 // Get all signable tags
296 auto tags = get_signable_tags(dataset);
297 return sign_tags(dataset, cert, key, tags, algo);
298}
static auto sign_tags(core::dicom_dataset &dataset, const certificate &cert, const private_key &key, std::span< const core::dicom_tag > tags_to_sign, signature_algorithm algo=signature_algorithm::rsa_sha256) -> kcenon::common::VoidResult
Sign specific tags in a DICOM dataset.

◆ sign_mac()

auto kcenon::pacs::security::digital_signature::sign_mac ( std::span< const std::uint8_t > mac_data,
const private_key & key,
signature_algorithm algo ) -> kcenon::common::Result<std::vector<std::uint8_t>>
staticprivate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 637 of file digital_signature.cpp.

641 {
642 if (!key.is_loaded()) {
643 return kcenon::common::make_error<std::vector<std::uint8_t>>(
644 1, "Private key not loaded", "digital_signature");
645 }
646
647 // Get EVP_PKEY from private_key
648 // Note: This requires internal access to the private_key implementation
649 auto* key_impl = key.impl();
650 if (!key_impl) {
651 return kcenon::common::make_error<std::vector<std::uint8_t>>(
652 2, "Invalid private key", "digital_signature");
653 }
654
655 // Access the EVP_PKEY through the impl
656 // In production, this would use a proper internal API
657 EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(const_cast<void*>(
658 static_cast<const void*>(key_impl)));
659
660 const EVP_MD* md = get_evp_md(algo);
661
662 evp_md_ctx_ptr ctx(EVP_MD_CTX_new());
663 if (!ctx) {
664 return kcenon::common::make_error<std::vector<std::uint8_t>>(
665 3, "Failed to create context: " + get_openssl_error(), "digital_signature");
666 }
667
668 if (EVP_DigestSignInit(ctx.get(), nullptr, md, nullptr, pkey) != 1) {
669 return kcenon::common::make_error<std::vector<std::uint8_t>>(
670 4, "Failed to init sign: " + get_openssl_error(), "digital_signature");
671 }
672
673 if (EVP_DigestSignUpdate(ctx.get(), mac_data.data(), mac_data.size()) != 1) {
674 return kcenon::common::make_error<std::vector<std::uint8_t>>(
675 5, "Failed to update sign: " + get_openssl_error(), "digital_signature");
676 }
677
678 // Get signature length
679 size_t sig_len = 0;
680 if (EVP_DigestSignFinal(ctx.get(), nullptr, &sig_len) != 1) {
681 return kcenon::common::make_error<std::vector<std::uint8_t>>(
682 6, "Failed to get signature length: " + get_openssl_error(), "digital_signature");
683 }
684
685 std::vector<std::uint8_t> signature(sig_len);
686 if (EVP_DigestSignFinal(ctx.get(), signature.data(), &sig_len) != 1) {
687 return kcenon::common::make_error<std::vector<std::uint8_t>>(
688 7, "Failed to create signature: " + get_openssl_error(), "digital_signature");
689 }
690
691 signature.resize(sig_len);
692 return signature;
693}

◆ sign_tags()

auto kcenon::pacs::security::digital_signature::sign_tags ( core::dicom_dataset & dataset,
const certificate & cert,
const private_key & key,
std::span< const core::dicom_tag > tags_to_sign,
signature_algorithm algo = signature_algorithm::rsa_sha256 ) -> kcenon::common::VoidResult
staticnodiscard

Sign specific tags in a DICOM dataset.

Creates a digital signature for only the specified tags.

Parameters
datasetThe dataset to sign (modified in place)
certSigner's X.509 certificate
keySigner's private key
tags_to_signList of tags to include in signature
algoSignature algorithm to use
Returns
Result indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 300 of file digital_signature.cpp.

306 {
307 if (!cert.is_loaded()) {
308 return kcenon::common::make_error<std::monostate>(
309 1, "Certificate not loaded", "digital_signature");
310 }
311
312 if (!key.is_loaded()) {
313 return kcenon::common::make_error<std::monostate>(
314 2, "Private key not loaded", "digital_signature");
315 }
316
317 if (!cert.is_valid()) {
318 return kcenon::common::make_error<std::monostate>(
319 3, "Certificate is not valid (expired or not yet valid)", "digital_signature");
320 }
321
322 // Compute MAC of the data
323 auto mac_algo = get_mac_algorithm(algo);
324 auto mac = compute_mac(dataset, tags_to_sign, mac_algo);
325
326 // Sign the MAC
327 auto signature_result = sign_mac(mac, key, algo);
328 if (signature_result.is_err()) {
329 return kcenon::common::make_error<std::monostate>(
330 signature_result.error().code,
331 signature_result.error().message,
332 "digital_signature");
333 }
334
335 const auto& signature_bytes = signature_result.value();
336
337 // Create Digital Signature Sequence item
338 // For simplicity, we'll add the signature data directly to the dataset
339 // In a full implementation, this would create a proper sequence item
340
341 // Generate signature UID
342 std::string sig_uid = generate_signature_uid();
343
344 // Get certificate DER
345 auto cert_der = cert.to_der();
346
347 // Create signed tags list (as AT type - list of tags)
348 std::vector<std::uint8_t> signed_tags_data;
349 for (const auto& tag : tags_to_sign) {
350 uint16_t group = tag.group();
351 uint16_t element = tag.element();
352 signed_tags_data.push_back(static_cast<uint8_t>(group & 0xFF));
353 signed_tags_data.push_back(static_cast<uint8_t>((group >> 8) & 0xFF));
354 signed_tags_data.push_back(static_cast<uint8_t>(element & 0xFF));
355 signed_tags_data.push_back(static_cast<uint8_t>((element >> 8) & 0xFF));
356 }
357
358 // Add signature elements to dataset
359 // Note: In a full DICOM implementation, these would be in a sequence item
360 dataset.set_string(signature_uid_tag, encoding::vr_type::UI, sig_uid);
361 dataset.set_string(signature_datetime_tag, encoding::vr_type::DT, format_dicom_datetime());
362 dataset.set_string(certificate_type_tag, encoding::vr_type::CS, "X509_1993_SIG");
363
364 // Add certificate data
365 dataset.insert(core::dicom_element(
366 certificate_of_signer_tag,
368 cert_der));
369
370 // Add signature
371 dataset.insert(core::dicom_element(
372 signature_tag,
374 signature_bytes));
375
376 // Add MAC algorithm
377 dataset.set_string(mac_algorithm_tag, encoding::vr_type::CS,
378 std::string(to_dicom_uid(mac_algo)));
379
380 // Add signed tags
381 dataset.insert(core::dicom_element(
382 data_elements_signed_tag,
384 signed_tags_data));
385
386 return kcenon::common::ok();
387}
static auto compute_mac(const core::dicom_dataset &dataset, std::span< const core::dicom_tag > tags, mac_algorithm algo) -> std::vector< std::uint8_t >
static auto sign_mac(std::span< const std::uint8_t > mac_data, const private_key &key, signature_algorithm algo) -> kcenon::common::Result< std::vector< std::uint8_t > >
static auto generate_signature_uid() -> std::string
Generate a new Digital Signature UID.
@ OB
Other Byte (variable length)
@ DT
Date Time (26 chars max)
@ UI
Unique Identifier (64 chars max)
@ CS
Code String (16 chars max, uppercase + digits + space + underscore)
@ AT
Attribute Tag (4 bytes)
constexpr std::string_view to_dicom_uid(mac_algorithm algo)
Convert mac_algorithm to DICOM UID string.

References kcenon::pacs::encoding::AT, kcenon::pacs::encoding::CS, kcenon::pacs::encoding::DT, kcenon::pacs::encoding::OB, kcenon::pacs::security::to_dicom_uid(), and kcenon::pacs::encoding::UI.

Here is the call graph for this function:

◆ verify()

auto kcenon::pacs::security::digital_signature::verify ( const core::dicom_dataset & dataset) -> kcenon::common::Result<signature_status>
staticnodiscard

Verify digital signatures in a dataset.

Verifies all digital signatures present in the Digital Signature Sequence (0400,0561).

Parameters
datasetThe dataset to verify
Returns
Result containing signature status or error
Note
Returns signature_status::no_signature if no signatures present.
Returns signature_status::invalid if any signature fails verification.

Definition at line 389 of file digital_signature.cpp.

391 {
392 // Check if signature exists
393 if (!has_signature(dataset)) {
395 }
396
397 // Get signature info
398 auto info = get_signature_info(dataset);
399 if (!info) {
400 return kcenon::common::make_error<signature_status>(
401 1, "Failed to extract signature info", "digital_signature");
402 }
403
404 // Get certificate from dataset
405 const auto* cert_elem = dataset.get(certificate_of_signer_tag);
406 if (!cert_elem) {
407 return kcenon::common::make_error<signature_status>(
408 2, "No certificate in signature", "digital_signature");
409 }
410
411 auto cert_result = certificate::load_from_der(cert_elem->raw_data());
412 if (cert_result.is_err()) {
413 return kcenon::common::make_error<signature_status>(
414 3, "Failed to load certificate: " + cert_result.error().message,
415 "digital_signature");
416 }
417
418 const auto& cert = cert_result.value();
419
420 // Check certificate validity
421 if (cert.is_expired()) {
423 }
424
425 if (!cert.is_valid()) {
427 }
428
429 // Get signed tags
430 const auto* signed_tags_elem = dataset.get(data_elements_signed_tag);
431 std::vector<core::dicom_tag> signed_tags;
432
433 if (signed_tags_elem) {
434 const auto& tag_data = signed_tags_elem->raw_data();
435 for (size_t i = 0; i + 3 < tag_data.size(); i += 4) {
436 uint16_t group = static_cast<uint16_t>(tag_data[i]) |
437 (static_cast<uint16_t>(tag_data[i + 1]) << 8);
438 uint16_t element = static_cast<uint16_t>(tag_data[i + 2]) |
439 (static_cast<uint16_t>(tag_data[i + 3]) << 8);
440 signed_tags.emplace_back(group, element);
441 }
442 } else {
443 // If no signed tags specified, use all non-signature tags
444 signed_tags = get_signable_tags(dataset);
445 }
446
447 // Compute MAC
448 auto mac = compute_mac(dataset, signed_tags, mac_algorithm::sha256);
449
450 // Get signature
451 const auto* sig_elem = dataset.get(signature_tag);
452 if (!sig_elem) {
453 return kcenon::common::make_error<signature_status>(
454 4, "No signature data found", "digital_signature");
455 }
456
457 // Verify signature
459 mac,
460 sig_elem->raw_data(),
461 cert,
462 info->algorithm);
463
465}
static auto verify_mac_signature(std::span< const std::uint8_t > mac_data, std::span< const std::uint8_t > signature, const certificate &cert, signature_algorithm algo) -> bool
@ untrusted_signer
Signer certificate is not trusted.
@ no_signature
No signature present in dataset.
@ valid
Signature is valid and trusted.
@ expired
Signer certificate has expired.
@ invalid
Signature verification failed (tampered data)

References kcenon::pacs::security::expired, kcenon::pacs::security::invalid, kcenon::pacs::security::certificate::load_from_der(), kcenon::pacs::security::no_signature, kcenon::pacs::security::sha256, kcenon::pacs::security::untrusted_signer, and kcenon::pacs::security::valid.

Here is the call graph for this function:

◆ verify_mac_signature()

auto kcenon::pacs::security::digital_signature::verify_mac_signature ( std::span< const std::uint8_t > mac_data,
std::span< const std::uint8_t > signature,
const certificate & cert,
signature_algorithm algo ) -> bool
staticprivate
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 695 of file digital_signature.cpp.

700 {
701 if (!cert.is_loaded()) {
702 return false;
703 }
704
705 // Get X509 from certificate
706 auto* cert_impl = cert.impl();
707 if (!cert_impl) {
708 return false;
709 }
710
711 // Access the X509 through the impl
712 X509* x509 = reinterpret_cast<X509*>(const_cast<void*>(
713 static_cast<const void*>(cert_impl)));
714
715 EVP_PKEY* pkey = X509_get_pubkey(x509);
716 if (!pkey) {
717 return false;
718 }
719
720 const EVP_MD* md = get_evp_md(algo);
721
722 evp_md_ctx_ptr ctx(EVP_MD_CTX_new());
723 if (!ctx) {
724 EVP_PKEY_free(pkey);
725 return false;
726 }
727
728 bool result = false;
729
730 if (EVP_DigestVerifyInit(ctx.get(), nullptr, md, nullptr, pkey) == 1 &&
731 EVP_DigestVerifyUpdate(ctx.get(), mac_data.data(), mac_data.size()) == 1 &&
732 EVP_DigestVerifyFinal(ctx.get(), signature.data(), signature.size()) == 1) {
733 result = true;
734 }
735
736 EVP_PKEY_free(pkey);
737 return result;
738}

◆ verify_with_trust()

auto kcenon::pacs::security::digital_signature::verify_with_trust ( const core::dicom_dataset & dataset,
const std::vector< certificate > & trusted_certs ) -> kcenon::common::Result<signature_status>
staticnodiscard

Verify digital signatures with a trusted certificate store.

Verifies signatures and validates the signer's certificate against a set of trusted certificates.

Parameters
datasetThe dataset to verify
trusted_certsTrusted certificates for validation
Returns
Result containing signature status or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/security/digital_signature.h.

Definition at line 467 of file digital_signature.cpp.

470 {
471 // First do basic verification
472 auto basic_result = verify(dataset);
473 if (basic_result.is_err()) {
474 return basic_result;
475 }
476
477 auto status = basic_result.value();
479 return status;
480 }
481
482 // Get signer certificate
483 const auto* cert_elem = dataset.get(certificate_of_signer_tag);
484 if (!cert_elem) {
486 }
487
488 auto cert_result = certificate::load_from_der(cert_elem->raw_data());
489 if (cert_result.is_err()) {
491 }
492
493 const auto& signer_cert = cert_result.value();
494 std::string signer_thumbprint = signer_cert.thumbprint();
495
496 // Check if signer is in trusted list
497 for (const auto& trusted : trusted_certs) {
498 if (trusted.thumbprint() == signer_thumbprint) {
500 }
501 }
502
504}
static auto verify(const core::dicom_dataset &dataset) -> kcenon::common::Result< signature_status >
Verify digital signatures in a dataset.
constexpr dicom_tag status
Status.

References kcenon::pacs::security::certificate::load_from_der(), kcenon::pacs::security::untrusted_signer, and kcenon::pacs::security::valid.

Here is the call graph for this function:

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