void setXAdESReference() { U_TRACE(5, "Application::setXAdESReference()") // SIGNED PROPERTIES UString signingCertificate(U_CAPACITY); // Compute the digest of the signer certificate UString DigestValue(U_CAPACITY); UServices::generateDigest(alg, 0, X509Certificate, DigestValue, true); signingCertificate.snprintf(U_CONSTANT_TO_PARAM(U_XADES_CERTIFICATE_TEMPLATE), U_STRING_TO_TRACE(digest_algorithm), U_STRING_TO_TRACE(DigestValue), U_STRING_TO_TRACE(X509IssuerName), X509SerialNumber); UString signingTime(100U); if (signing_time) { UString dateTime = UTimeDate::strftime(U_CONSTANT_TO_PARAM("%Y-%m-%dT%H:%M:%SZ"), u_now->tv_sec); signingTime.snprintf(U_CONSTANT_TO_PARAM(U_XADES_SIGNING_TIME_TEMPLATE), U_STRING_TO_TRACE(dateTime)); } UString roleTemplate(U_CAPACITY); if (claimed_role.empty() == false) roleTemplate.snprintf(U_CONSTANT_TO_PARAM(U_XADES_SIGNER_ROLE_TEMPLATE), U_STRING_TO_TRACE(claimed_role)); (void) signedProperties.reserve(U_CONSTANT_SIZE(U_XADES_SIGNED_PROPERTIES_TEMPLATE) + 8192U + signingTime.size()); signedProperties.snprintf(U_CONSTANT_TO_PARAM(U_XADES_SIGNED_PROPERTIES_TEMPLATE), U_STRING_TO_TRACE(signingTime), U_STRING_TO_TRACE(signingCertificate), U_STRING_TO_TRACE(production_place_city), U_STRING_TO_TRACE(production_place_state_or_province), U_STRING_TO_TRACE(production_place_postal_code), U_STRING_TO_TRACE(production_place_country_name), U_STRING_TO_TRACE(roleTemplate), U_STRING_TO_TRACE(DataObjectFormat)); to_digest = UXML2Document::xmlC14N(signedProperties); UString signedPropertiesDigestValue(200U); UServices::generateDigest(alg, 0, to_digest, signedPropertiesDigestValue, true); (void) XAdESReference.reserve(U_CONSTANT_SIZE(U_XADES_REFERENCE_TEMPLATE) + signedPropertiesDigestValue.size()); XAdESReference.snprintf(U_CONSTANT_TO_PARAM(U_XADES_REFERENCE_TEMPLATE), U_STRING_TO_TRACE(digest_algorithm), U_STRING_TO_TRACE(signedPropertiesDigestValue)); }
ULog::ULog(const UString& path, uint32_t _size, const char* dir_log_gz) : UFile(path) { U_TRACE_REGISTER_OBJECT(0, ULog, "%.*S,%u,%S", U_STRING_TO_TRACE(path), _size, dir_log_gz) log_gzip_sz = 0; U_Log_start_stop_msg(this) = false; if (UFile::getPath().equal(U_CONSTANT_TO_PARAM("syslog"))) { lock = 0; ptr_log_data = 0; # ifdef USE_LIBZ buf_path_compress = 0; # endif U_Log_syslog(this) = true; # ifndef __MINGW32__ U_SYSCALL_VOID(openlog, "%S,%d,%d", u_progname, LOG_PID, LOG_LOCAL0); # endif return; } if (UFile::creat(O_RDWR | O_APPEND, 0664) == false) { U_ERROR("cannot creat log file %.*S", U_FILE_TO_TRACE(*this)); return; } ptr_log_data = U_MALLOC_TYPE(log_data); ptr_log_data->file_ptr = 0; if (_size) { uint32_t file_size = UFile::size(); bool bsize = (file_size != _size); U_INTERNAL_DUMP("bsize = %b", bsize) if ((bsize && UFile::ftruncate(_size) == false) || UFile::memmap(PROT_READ | PROT_WRITE) == false) { U_ERROR("cannot init log file %.*S", U_FILE_TO_TRACE(*this)); return; } if (bsize) ptr_log_data->file_ptr = file_size; // append mode else { // NB: we can have a previous crash without resizing the file or we are an other process (apache like log)... char* ptr = (char*) u_find(UFile::map, file_size, U_CONSTANT_TO_PARAM(U_MARK_END)); U_INTERNAL_DUMP("ptr = %p", ptr) if (ptr) { ptr_log_data->file_ptr = ptr - UFile::map; // NB: we can be an other process that manage this file (apache like log)... (void) memcpy(ptr, U_CONSTANT_TO_PARAM(U_MARK_END)); UFile::msync(ptr + U_CONSTANT_SIZE(U_MARK_END), UFile::map, MS_SYNC); } U_INTERNAL_ASSERT_MINOR(ptr_log_data->file_ptr, UFile::st_size) } log_file_sz = UFile::st_size; } U_INTERNAL_DUMP("ptr_log_data->file_ptr = %u UFile::st_size = %u log_gzip_sz = %u", ptr_log_data->file_ptr, UFile::st_size, log_gzip_sz) U_INTERNAL_ASSERT(ptr_log_data->file_ptr <= UFile::st_size) lock = U_NEW(ULock); U_Log_syslog(this) = false; ptr_log_data->gzip_len = 0; ptr_log_data->file_page = ptr_log_data->file_ptr; #ifdef USE_LIBZ char suffix[32]; uint32_t len_suffix = u__snprintf(suffix, sizeof(suffix), ".%4D.gz"); buf_path_compress = U_NEW(UString(MAX_FILENAME_LEN)); char* ptr = buf_path_compress->data(); if (dir_log_gz == 0) { (void) UFile::setPathFromFile(*this, ptr, suffix, len_suffix); buf_path_compress->size_adjust(); index_path_compress = (buf_path_compress->size() - len_suffix + 1); } else { UString name = UFile::getName(); uint32_t len = u__strlen(dir_log_gz, __PRETTY_FUNCTION__), sz = name.size(); U_MEMCPY(ptr, dir_log_gz, len); ptr += len; *ptr++ = '/'; buf_path_compress->size_adjust(len + 1 + sz + len_suffix); U_MEMCPY(ptr, name.data(), sz); ptr += sz; U_MEMCPY(ptr, suffix, len_suffix); index_path_compress = buf_path_compress->distance(ptr) + 1; buf_path_compress->UString::setNullTerminated(); } U_INTERNAL_DUMP("buf_path_compress(%u) = %.*S index_path_compress = %u", buf_path_compress->size(), U_STRING_TO_TRACE(*buf_path_compress), index_path_compress) #endif }
ULog::ULog(const UString& path, uint32_t _size, const char* dir_log_gz) : UFile(path, 0) { U_TRACE_REGISTER_OBJECT(0, ULog, "%V,%u,%S", path.rep, _size, dir_log_gz) lock = 0; ptr_log_data = 0; log_file_sz = log_gzip_sz = 0; U_Log_start_stop_msg(this) = false; #ifdef USE_LIBZ buf_path_compress = 0; index_path_compress = 0; #endif if (UFile::getPath().equal(U_CONSTANT_TO_PARAM("syslog"))) { U_Log_syslog(this) = true; # ifndef _MSWINDOWS_ openlog(u_progname, LOG_PID, LOG_LOCAL0); # endif return; } if (UFile::creat(O_RDWR | O_APPEND, 0664) == false) { # ifndef U_COVERITY_FALSE_POSITIVE U_ERROR("cannot creat log file %.*S", U_FILE_TO_TRACE(*this)); # endif return; } /** * typedef struct log_data { * uint32_t file_ptr; * uint32_t file_page; * uint32_t gzip_len; * sem_t lock_shared; * char spinlock_shared[1]; * // --------------> maybe unnamed array of char for gzip compression... * } log_data; */ ptr_log_data = U_MALLOC_TYPE(log_data); ptr_log_data->file_ptr = 0; if (_size) { uint32_t file_size = UFile::size(); bool bsize = (file_size != _size); if ((bsize && UFile::ftruncate(_size) == false) || UFile::memmap(PROT_READ | PROT_WRITE) == false) { U_ERROR("cannot init log file %.*S", U_FILE_TO_TRACE(*this)); return; } if (bsize) ptr_log_data->file_ptr = file_size; // append mode else { // NB: we can have a previous crash without resizing the file or we are an other process (apache like log)... char* ptr = (char*) u_find(UFile::map, file_size, U_CONSTANT_TO_PARAM(U_MARK_END)); if (ptr) { ptr_log_data->file_ptr = ptr - UFile::map; // NB: we can be an other process that manage this file (apache like log)... u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('\n','\n','\n','\n','\n','\n','\n','\n')); u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('\n','\n','\n','\n','\n','\n','\n','\n')); u_put_unalignedp64(ptr+16, U_MULTICHAR_CONSTANT64('\n','\n','\n','\n','\n','\n','\n','\n')); UFile::msync(ptr + U_CONSTANT_SIZE(U_MARK_END), UFile::map, MS_SYNC); } U_INTERNAL_ASSERT_MINOR(ptr_log_data->file_ptr, UFile::st_size) } log_file_sz = UFile::st_size; } U_INTERNAL_ASSERT(ptr_log_data->file_ptr <= UFile::st_size) lock = U_NEW(ULock); U_Log_syslog(this) = false; ptr_log_data->gzip_len = 0; ptr_log_data->file_page = ptr_log_data->file_ptr; #ifdef USE_LIBZ char suffix[32]; uint32_t len_suffix = u__snprintf(suffix, sizeof(suffix), ".%4D.gz"); buf_path_compress = U_NEW(UString(MAX_FILENAME_LEN)); char* ptr = buf_path_compress->data(); if (dir_log_gz == 0) { # ifndef U_COVERITY_FALSE_POSITIVE // Uninitialized pointer read (UNINIT) (void) UFile::setPathFromFile(*this, ptr, suffix, len_suffix); # endif buf_path_compress->size_adjust(); index_path_compress = (buf_path_compress->size() - len_suffix + 1); } else { UString name = UFile::getName(); uint32_t len = u__strlen(dir_log_gz, __PRETTY_FUNCTION__), sz = name.size(); (void) memcpy(ptr, dir_log_gz, len); ptr += len; *ptr++ = '/'; buf_path_compress->size_adjust(len + 1 + sz + len_suffix); (void) memcpy(ptr, name.data(), sz); ptr += sz; (void) memcpy(ptr, suffix, len_suffix); index_path_compress = buf_path_compress->distance(ptr) + 1; } #endif }
void run(int argc, char* argv[], char* env[]) { U_TRACE(5, "Application::run(%d,%p,%p)", argc, argv, env) UApplication::run(argc, argv, env); U_SYSCALL_VOID_NO_PARAM(xmlInitParser); // init libxml LIBXML_TEST_VERSION // manage options num_args = (argc - optind); U_INTERNAL_DUMP("optind = %d num_args = %d", optind, num_args) if (UApplication::isOptions()) cfg_str = opt['c']; // manage file configuration if (cfg_str.empty()) cfg_str = U_STRING_FROM_CONSTANT("XAdES.ini"); // ---------------------------------------------------------------------------------------------------------------------------------- // XAdES signature - configuration parameters // ---------------------------------------------------------------------------------------------------------------------------------- // DigestAlgorithm md2 | md5 | sha | sha1 | sha224 | sha256 | sha384 | sha512 | mdc2 | ripmed160 // // SigningTime this property contains the time at which the signer claims to have performed the signing process (yes/no) // ClaimedRole this property contains claimed or certified roles assumed by the signer in creating the signature // // this property contains the indication of the purported place where the signer claims to have produced the signature // ------------------------------------------------------------------------------------------------------------------- // ProductionPlaceCity // ProductionPlaceStateOrProvince // ProductionPlacePostalCode // ProductionPlaceCountryName // ------------------------------------------------------------------------------------------------------------------- // // DataObjectFormatMimeType this property identifies the format of a signed data object (when electronic signatures // are not exchanged in a restricted context) to enable the presentation to the verifier or // use by the verifier (text, sound or video) in exactly the same way as intended by the signer // // CAStore // ArchiveTimeStamp the time-stamp token within this property covers the archive validation data // // SignatureTimeStamp the time-stamp token within this property covers the digital signature value element // Schema the pathname XML Schema of XAdES // ---------------------------------------------------------------------------------------------------------------------------------- cfg.UFile::setPath(cfg_str); UString x(U_CAPACITY); UServices::readEOF(STDIN_FILENO, x); if (x.empty()) U_ERROR("cannot read data from <stdin>"); (void) document.reserve(x.size()); UBase64::decode(x, document); if (document.empty()) U_ERROR("decoding data read failed"); // manage arguments... if ( U_DATA_URI && *U_DATA_URI == '\0') { U_ERROR("DATA_URI is mandatory"); } if ( U_X509 && *U_X509 == '\0') { U_ERROR("X509 is mandatory"); } if ( U_KEY_HANDLE && *U_KEY_HANDLE == '\0') { U_ERROR("KEY_HANDLE is mandatory"); } UCertificate cert(UString(U_X509)); if (cert.isValid() == false) U_ERROR("certificate not valid"); U_INTERNAL_DUMP("U_CA_STORE = %S", U_CA_STORE) xades_c = (U_CA_STORE != U_NULLPTR); digest_algorithm = getOptionValue(U_DIGEST_ALGORITHM, "DigestAlgorithm"); alg = u_dgst_get_algoritm(digest_algorithm.c_str()); if (alg == -1) U_ERROR("I can't find the digest algorithm for: %s", digest_algorithm.data()); signing_time = getOptionValue(U_SIGNING_TIME, "SigningTime").strtol(); claimed_role = getOptionValue(U_CLAIMED_ROLE, "ClaimedRole"); production_place_city = getOptionValue(U_PRODUCTION_PLACE_CITY, "ProductionPlaceCity"); production_place_state_or_province = getOptionValue(U_PRODUCTION_PLACE_STATE_OR_PROVINCE, "ProductionPlaceStateOrProvince"); production_place_postal_code = getOptionValue(U_PRODUCTION_PLACE_POSTAL_CODE, "ProductionPlacePostalCode"); production_place_country_name = getOptionValue(U_PRODUCTION_PLACE_COUNTRY_NAME, "ProductionPlaceCountryName"); data_object_format_mimetype = getOptionValue("", "DataObjectFormatMimeType"); if (xades_c == false) num_ca = 0; else { // XAdES-C // ------------------------------------------------------------------------------------------------------------- str_CApath = getOptionValue(U_CA_STORE, "CAStore"); signature_timestamp = getOptionValue(U_SIGNATURE_TIMESTAMP, "SignatureTimeStamp"); if (str_CApath.empty() || UServices::setupOpenSSLStore(U_NULLPTR, str_CApath.c_str()) == false) { U_ERROR("error on setting CA Store: %S", str_CApath.data()); } num_ca = cert.getSignerCertificates(vec_ca, U_NULLPTR, 0); if (UCertificate::verify_result == false) { UServices::setVerifyStatus(); U_ERROR("error on verifying the certificate: %.*s", u_buffer_len, u_buffer); } // ------------------------------------------------------------------------------------------------------------- } u_base64_max_columns = U_OPENSSL_BASE64_MAX_COLUMN; U_line_terminator_len = 2; UString modulus = cert.getModulus(), exponent = cert.getExponent(); X509IssuerName = cert.getIssuerForLDAP(), X509SubjectName = cert.getSubjectForLDAP(), X509Certificate = cert.getEncoded("DER"); X509SerialNumber = cert.getSerialNumber(); UString X509CertificateValue(U_CAPACITY), KeyInfo(U_CAPACITY); UBase64::encode(X509Certificate, X509CertificateValue); u_base64_max_columns = 0; KeyInfo.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_KEYINFO_TEMPLATE), U_STRING_TO_TRACE(modulus), U_STRING_TO_TRACE(exponent), U_STRING_TO_TRACE(X509SubjectName), U_STRING_TO_TRACE(X509IssuerName), X509SerialNumber, U_STRING_TO_TRACE(X509CertificateValue)); UString ObjectDigestValue(200U), Reference(U_CAPACITY), dataObjectFormat(U_CAPACITY), XMLDSIGReference(U_CAPACITY), XMLDSIGReferenceC14N(U_CAPACITY); // --------------------------------------------------------------------------------------------------------------- // check for OOffice or MS-Word document... // --------------------------------------------------------------------------------------------------------------- utility.handlerConfig(cfg); (void) utility.checkDocument(document, U_DATA_URI, true); // --------------------------------------------------------------------------------------------------------------- for (uint32_t i = 0, n = utility.vdocument.size(); i < n; ++i) { uri = utility.vuri[i]; to_digest = utility.vdocument[i]; // --------------------------------------------------------------------------------------------------------------- // 2. Compute the message digest of the text, m = Hash(C). // --------------------------------------------------------------------------------------------------------------- ObjectDigestValue.setEmpty(); UServices::generateDigest(alg, 0, to_digest, ObjectDigestValue, true); // --------------------------------------------------------------------------------------------------------------- Reference.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_REFERENCE_TEMPLATE), uri.c_str(), U_STRING_TO_TRACE(digest_algorithm), U_STRING_TO_TRACE(ObjectDigestValue)); XMLDSIGReference += Reference; XMLDSIGReferenceC14N += UXML2Document::xmlC14N(Reference); if (data_object_format_mimetype.empty() == false) { dataObjectFormat.snprintf(U_CONSTANT_TO_PARAM(U_XADES_DATA_OBJECT_FORMAT_TEMPLATE), uri.c_str(), U_STRING_TO_TRACE(data_object_format_mimetype)); DataObjectFormat += dataObjectFormat; } } setXAdESReference(); // XAdES management // --------------------------------------------------------------------------------------------------------------- // 3. Encapsulate the message digest in an XML <SignedInfo> element, SI, in canonicalized form. // --------------------------------------------------------------------------------------------------------------- UString SignedInfo(U_CONSTANT_SIZE(U_XMLDSIG_SIGNED_INFO_TEMPLATE) + XMLDSIGReference.size() + XAdESReference.size()); SignedInfo.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_SIGNED_INFO_TEMPLATE), U_STRING_TO_TRACE(digest_algorithm), U_STRING_TO_TRACE(XMLDSIGReference), U_STRING_TO_TRACE(XAdESReference)); UString to_sign = UXML2Document::xmlC14N(SignedInfo); // --------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------- // 4. Compute the RSA signatureValue of the canonicalized <SignedInfo> element, SV = RsaSign(Ks, SI). // --------------------------------------------------------------------------------------------------------------- UString SignatureValue(U_CAPACITY), signatureTimeStamp(U_CAPACITY), archiveTimeStamp(U_CAPACITY); u_base64_max_columns = U_OPENSSL_BASE64_MAX_COLUMN; ENGINE* e; # ifdef _MSWINDOWS_ e = UServices::loadEngine("HCSP", ENGINE_METHOD_RSA); x = U_KEY_HANDLE; # else e = U_NULLPTR; x = UFile::contentOf(UString(U_KEY_HANDLE)); if (x.empty() || (u_pkey = UServices::loadKey(x, U_NULLPTR, true, U_NULLPTR, e)) == U_NULLPTR) { U_ERROR("I can't load the private key: %S", U_KEY_HANDLE); } # ifdef HAVE_OPENSSL_98 if (cert.matchPrivateKey(u_pkey) == false) U_ERROR("the private key doesn't matches the public key of the certificate"); # endif x.clear(); # endif UString sign = UServices::getSignatureValue(alg, to_sign, x, UString::getStringNull(), true, e); u_base64_max_columns = 0; SignatureValue.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_SIGNATURE_VALUE_TEMPLATE), U_STRING_TO_TRACE(sign)); if (signature_timestamp.empty() == false) { to_digest = UXML2Document::xmlC14N(SignatureValue); UString token = getTimeStampToken(to_digest, signature_timestamp); signatureTimeStamp.snprintf(U_CONSTANT_TO_PARAM(U_XADES_SIGNATURE_TIMESTAMP_TEMPLATE), U_STRING_TO_TRACE(token)); } // XAdES-C // ------------------------------------------------------------------------------------------------------------- if (xades_c) setXAdESUnsignedSignatureProperties(); // ------------------------------------------------------------------------------------------------------------- (void) XAdESObject.reserve(U_CONSTANT_SIZE(U_XADES_TEMPLATE) + signedProperties.size() + unsignedSignatureProperties.size() + archiveTimeStamp.size() + signatureTimeStamp.size()); XAdESObject.snprintf(U_CONSTANT_TO_PARAM(U_XADES_TEMPLATE), U_STRING_TO_TRACE(signedProperties), U_STRING_TO_TRACE(unsignedSignatureProperties), U_STRING_TO_TRACE(archiveTimeStamp), U_STRING_TO_TRACE(signatureTimeStamp)); // --------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------- // 5. Compose the final XML document including the signatureValue, this time in non-canonicalized form. // --------------------------------------------------------------------------------------------------------------- UString output(U_CONSTANT_SIZE(U_XMLDSIG_TEMPLATE) + 8192U + SignedInfo.size() + SignatureValue.size() + XAdESObject.size()); if (utility.ooffice) { OpenDocumentStart = U_STRING_FROM_CONSTANT("<document-signatures xmlns=\"urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0\">"); OpenDocumentEnd = U_STRING_FROM_CONSTANT("</document-signatures>"); } output.snprintf(U_CONSTANT_TO_PARAM(U_XMLDSIG_TEMPLATE), U_STRING_TO_TRACE(OpenDocumentStart), U_STRING_TO_TRACE(SignedInfo), U_STRING_TO_TRACE(SignatureValue), U_STRING_TO_TRACE(KeyInfo), U_STRING_TO_TRACE(XAdESObject), U_STRING_TO_TRACE(OpenDocumentEnd)); // --------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------- // check for OOffice or MS-Word document... // --------------------------------------------------------------------------------------------------------------- utility.outputDocument(output); // --------------------------------------------------------------------------------------------------------------- }
// ------------------------------------------------------------------------------------------------------------- // XAdES-C // ------------------------------------------------------------------------------------------------------------- void setXAdESUnsignedSignatureProperties() { U_TRACE(5, "Application::setXAdESUnsignedSignatureProperties()") // UNSIGNED SIGNATURE PROPERTIES // <CompleteCertificateRefs>...</CompleteCertificateRefs> UString completeCertificateRef(U_CAPACITY), completeCertificateRefs(U_CAPACITY); uint32_t i, n; UVector<UString> vec_CACertificateValue; UString item(U_CAPACITY), CACertificateValue(U_CAPACITY), CAIssuerName, CACertificate, DigestValue(U_CAPACITY); UCertificate* ca; for (i = 0; i < num_ca; ++i) { ca = vec_ca[i]; CAIssuerName = ca->getIssuerForLDAP(); CACertificate = ca->getEncoded("DER"); DigestValue.setEmpty(); UServices::generateDigest(alg, 0, CACertificate, DigestValue, true); item.snprintf(U_CONSTANT_TO_PARAM(U_XADES_CERTIFICATE_TEMPLATE), U_STRING_TO_TRACE(digest_algorithm), U_STRING_TO_TRACE(DigestValue), U_STRING_TO_TRACE(CAIssuerName), ca->getSerialNumber()); (void) completeCertificateRef.append(item); u_base64_max_columns = U_OPENSSL_BASE64_MAX_COLUMN; UBase64::encode(CACertificate, CACertificateValue); u_base64_max_columns = 0; vec_CACertificateValue.push_back(CACertificateValue); } completeCertificateRefs.snprintf(U_CONSTANT_TO_PARAM(U_XADES_COMPLETE_CERTIFICATE_REFS_TEMPLATE), U_STRING_TO_TRACE(completeCertificateRef)); unsignedSignaturePropertiesC14N += UXML2Document::xmlC14N(completeCertificateRefs); // <CertificateValues>....</CertificateValues> UString certificateValue(U_CAPACITY), certificateValues(U_CAPACITY); for (i = 0, n = vec_CACertificateValue.size(); i < n; ++i) { CACertificateValue = vec_CACertificateValue[i]; item.snprintf(U_CONSTANT_TO_PARAM(U_XADES_ENCAPSULATED_X509_CERTIFICATE_TEMPLATE), U_STRING_TO_TRACE(CACertificateValue)); (void) certificateValue.append(item); } certificateValues.snprintf(U_CONSTANT_TO_PARAM(U_XADES_CERTIFICATE_VALUES_TEMPLATE), U_STRING_TO_TRACE(certificateValue)); unsignedSignaturePropertiesC14N += UXML2Document::xmlC14N(certificateValues); // <CompleteRevocationRefs>...</CompleteRevocationRefs> UString completeRevocationRef(U_CAPACITY), completeRevocationRefs(U_CAPACITY); long CRLNumber; bool crl_exist; UString crlpath; UVector<UString> vec_CRLValue; UString CRLValue(U_CAPACITY), CRLIssuerName, CRL, CRLIssueTime; for (i = 0; i < num_ca; ++i) { ca = vec_ca[i]; crlpath = UCertificate::getFileName(ca->hashCode(), true, &crl_exist); if (crl_exist) { UCrl crl(UFile::contentOf(crlpath)); CRL = crl.getEncoded("DER"); CRLNumber = crl.getNumber(); CRLIssuerName = crl.getIssuerForLDAP(); CRLIssueTime = UTimeDate::strftime(U_CONSTANT_TO_PARAM("%Y-%m-%dT%H:%M:%SZ"), crl.getIssueTime()); DigestValue.setEmpty(); UServices::generateDigest(alg, 0, CRL, DigestValue, true); item.snprintf(U_CONSTANT_TO_PARAM(U_XADES_CRL_TEMPLATE), U_STRING_TO_TRACE(digest_algorithm), U_STRING_TO_TRACE(DigestValue), U_STRING_TO_TRACE(CRLIssuerName), U_STRING_TO_TRACE(CRLIssueTime), CRLNumber); (void) completeRevocationRef.append(item); u_base64_max_columns = U_OPENSSL_BASE64_MAX_COLUMN; UBase64::encode(CRL, CRLValue); u_base64_max_columns = 0; vec_CRLValue.push_back(CRLValue); } } completeRevocationRefs.snprintf(U_CONSTANT_TO_PARAM(U_XADES_COMPLETE_REVOCATION_REFS_TEMPLATE), U_STRING_TO_TRACE(completeRevocationRef)); unsignedSignaturePropertiesC14N += UXML2Document::xmlC14N(completeRevocationRefs); // <RevocationValues>...</RevocationValues> UString revocationValue(U_CAPACITY), revocationValues(U_CAPACITY); for (i = 0, n = vec_CRLValue.size(); i < n; ++i) { CRLValue = vec_CRLValue[i]; item.snprintf(U_CONSTANT_TO_PARAM(U_XADES_ENCAPSULATED_CRL_VALUE_TEMPLATE), U_STRING_TO_TRACE(CRLValue)); (void) revocationValue.append(item); } revocationValues.snprintf(U_CONSTANT_TO_PARAM(U_XADES_REVOCATION_VALUES_TEMPLATE), U_STRING_TO_TRACE(revocationValue)); unsignedSignaturePropertiesC14N += UXML2Document::xmlC14N(revocationValues); (void) unsignedSignatureProperties.reserve(U_CONSTANT_SIZE(U_XADES_UNSIGNED_SIGNATURE_PROPERTIES_TEMPLATE) + completeCertificateRefs.size() + completeRevocationRefs.size() + certificateValues.size() + revocationValues.size()); unsignedSignatureProperties.snprintf(U_CONSTANT_TO_PARAM(U_XADES_UNSIGNED_SIGNATURE_PROPERTIES_TEMPLATE), U_STRING_TO_TRACE(completeCertificateRefs), U_STRING_TO_TRACE(certificateValues), U_STRING_TO_TRACE(completeRevocationRefs), U_STRING_TO_TRACE(revocationValues)); }