/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" #include #include "ExIfcTutorial_Signature.h" #include "IfcModel.h" #include "RxValue.h" #include "daiHeaderSection.h" #define SIGNATURE_STRING_LENGTH 64 using namespace OdIfc; using namespace OdDAI; void printCertificateDescription(const OdCertificateDescription& description) { odPrintConsoleString("Subject: " + description.m_CertSubject + "\n"); odPrintConsoleString("Issuer: " + description.m_CertIssuer + "\n"); odPrintConsoleString("Serial num: " + description.m_CertSerialNum + "\n"); odPrintConsoleString("Valid from: " + description.m_CertValidFrom + "\n"); odPrintConsoleString("Valid to: " + description.m_CertValidTo + "\n"); } Tutorial_SignatureValidation::Tutorial_SignatureValidation(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser .add_param( std::make_shared>(m_ifcFileName, "fileName", "input .ifc file")); m_noWait = false; m_tutorialArgsParser .add_param( std::make_shared(m_noWait, "-NoWait", "disable \"press any key\" on finish.")); } int Tutorial_SignatureValidation::run(const MyServices& svcs, const std::vector& argv, std::ostream& resultStream) { auto parseResult = BaseIfcTutorial::run(svcs, argv, resultStream); if (parseResult != 0) { return parseResult; } OdIfcFilePtr pFile = svcs.createDatabase(); OdResult res = pFile->readFile(m_ifcFileName); if (res == eOk) { odPrintConsoleString(OD_T("\nFile opened successfully\n")); } else { odPrintConsoleString(OD_T("\nFile open error. Press any key to finish...\n")); if (m_noWait == false) { getchar(); } return res; } odPrintConsoleString(OD_T("\nRetrieving signature information\nEach signature is checked after loading the entire file against all previous file contents\n")); RepositoryPtr pRepository = pFile->getRepository(); OdArray& signatureSection = pRepository->getReadSignatureSection(); int number = 1; for (SignatureSection& signature : signatureSection) { odPrintConsoleString(OdString().format(L"\nSignature number: %i\n", number++)); odPrintConsoleString(OdString().format(L"Starting position in the file: %i\n", signature.getPosition())); odPrintConsoleString(OD_T("Signature string:\n")); const OdAnsiString& content = signature.getContent(); for (int i = 0; i < content.getLength(); i += SIGNATURE_STRING_LENGTH) { odPrintConsoleString(OdString(content.mid(i, SIGNATURE_STRING_LENGTH))); odPrintConsoleString(OD_T("\n")); } OdCertificateObjectPtr pCertificateObject = signature.getCertificate(); if (!pCertificateObject.isNull()) { odPrintConsoleString(OD_T("Corresponding certificate description:\n")); OdCertificateDescription description = pCertificateObject->getCertDescription(); printCertificateDescription(description); } else { odPrintConsoleString(OD_T("Certificate is not available\n")); } } odPrintConsoleString(OD_T("\nProcess finished\n")); return eOk; } Tutorial_SignatureSign::Tutorial_SignatureSign(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser .add_param( std::make_shared>(m_inputIfcFileName, "ifcFileName", "input .ifc file")); m_tutorialArgsParser .add_param( std::make_shared>(m_outputIfcFileName, "outFileName", "output .ifc file")); m_tutorialArgsParser .add_param( std::make_shared>(m_subject, "subject", "certificate subject")); m_tutorialArgsParser .add_param( std::make_shared>(m_issuer, "issuer", "certificate issuer")); m_tutorialArgsParser .add_param( std::make_shared>(m_serialNumber, "serialNumber", "certificate serial number")); m_dump = false; m_tutorialArgsParser .add_param( std::make_shared(m_dump, "-Dump", "print all available digital certificates")); m_noWait = false; m_tutorialArgsParser .add_param( std::make_shared(m_noWait, "-NoWait", "disable \"press any key\" on finish.")); } int Tutorial_SignatureSign::run(const MyServices& svcs, const std::vector& argv, std::ostream& resultStream) { auto parseResult = BaseIfcTutorial::run(svcs, argv, resultStream); if (parseResult != 0) { return parseResult; } OdRxClassPtr pService = odrxServiceDictionary()->getAt(OD_T("OdCryptoServices")); if (pService.isNull()) { odPrintConsoleString(OD_T("Crypto services are not available")); return eCryptProviderUnavailable; } OdCryptoServicesPtr pCryptoServices = pService->create(); if (m_dump) { OdArray certDescArray; int certsNumber = 0; certsNumber = pCryptoServices->getPersonalCertsWithTrustedStatus(certDescArray); for (int i = 0; i < certsNumber; i++) { odPrintConsoleString(OdString().format(L"\nCertificate number: %i\n", i + 1)); printCertificateDescription(certDescArray[i]); } return eOk; } OdIfcFilePtr pFile = svcs.createDatabase(); OdResult res = pFile->readFile(m_inputIfcFileName); if (res == eOk) { odPrintConsoleString(OD_T("\nFile opened successfully\n")); } else { odPrintConsoleString(OD_T("\nFile open error. Press any key to finish...\n")); if (m_noWait == false) { getchar(); } return res; } odPrintConsoleString(OD_T("\nRetrieving certificate information\n")); OdCertificateDescription description; description.m_CertSubject = m_subject; description.m_CertIssuer = m_issuer; description.m_CertSerialNum = m_serialNumber; OdCertificateObjectPtr pCertObj = pCryptoServices->getCertObjByShortDesc(description); if (pCertObj.isNull()) { odPrintConsoleString(OD_T("Certificate is not available\n")); return eNotInDatabase; } RepositoryPtr pRepository = pFile->getRepository(); OdArray& signatureSection = pRepository->getWriteSignatureSection(); const int signatureNumber = 2; for (int i = 0; i < signatureNumber; i++) { SignatureSection signature; signature.setCertificate(pCertObj); signature.setAsComment(true); signatureSection.push_back(signature); } // // IFC File Header Policy compliance // OdDAI::OdHeaderSectionPtr header = pRepository->getHeaderSection(); OdDAI::ApplicationInstancePtr file_name = header->getEntityByType(kFileName); file_name->putAttr("organization", OdAnsiString("Open Design Alliance")); OdAnsiString originating_system = OdAnsiString("Open Design Alliance - ExIfcTutorials - ") + TD_SHORT_STRING_VER_S; file_name->putAttr("originating_system", originating_system); res = pFile->writeFile(m_outputIfcFileName); if (res == eOk) { odPrintConsoleString(OD_T("\nFile written successfully\n")); } else { odPrintConsoleString(OD_T("\nFile write error. Press any key to finish...\n")); if (m_noWait == false) { getchar(); } return res; } int number = 1; for (SignatureSection& signature : signatureSection) { odPrintConsoleString(OdString().format(L"\nSignature number: %i\n", number++)); odPrintConsoleString(OD_T("Signature string:\n")); const OdAnsiString& content = signature.getContent(); for (int i = 0; i < content.getLength(); i += SIGNATURE_STRING_LENGTH) { odPrintConsoleString(OdString(content.mid(i, SIGNATURE_STRING_LENGTH))); odPrintConsoleString(OD_T("\n")); } OdCertificateObjectPtr pCertificateObject = signature.getCertificate(); if (!pCertificateObject.isNull()) { odPrintConsoleString(OD_T("Corresponding certificate description:\n")); OdCertificateDescription description = pCertificateObject->getCertDescription(); printCertificateDescription(description); } else { odPrintConsoleString(OD_T("Certificate is not available\n")); } } odPrintConsoleString(OD_T("\nProcess finished\n")); return eOk; }