KeyInfo * new_option() { options.push_back(KeyInfo()); in_option = true; return &options.back();}
KeyInfo NKey::Info(const std::string& ns_separator) const { KeyInfo::splited_namespaces_t tokens; common::Tokenize(key_, ns_separator, &tokens); return KeyInfo(tokens, ns_separator); }
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); // --------------------------------------------------------------------------------------------------------------- }