/** * Parses X.509 PEM formatted certificate from file. * NB! This struct must be freed using X509_free() function from OpenSSL or * with X509_scope struct. * * @param path PEM formatted X.509 certificate file path. * @return returns certificate parsed from file. * @throws IOException throws exception if the file does not contain X.509 * PEM formatted certificate. */ X509* digidoc::X509Cert::loadX509(const std::string& path) throw(IOException) { // Initialize OpenSSL file. BIO* file = BIO_new(BIO_s_file()); BIO_scope fileScope(&file); if(file == NULL) { THROW_IOEXCEPTION("Failed to open X.509 certificate file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } if(BIO_read_filename(file, path.c_str()) <= 0) { THROW_IOEXCEPTION("Failed to open X.509 certificate file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } // Parse X.509 certificate from file. X509* cert = PEM_read_bio_X509(file, NULL, NULL, NULL); if(cert == NULL) { THROW_IOEXCEPTION("Failed to load X.509 certificate from file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } return cert; }
/** * Parses X.509 PEM formatted certificates from file. The file can contain multiple * certificates. You can just use 'cat' command in linux to add multiple PEM formatted * X.509 certificates to one file (e.g. <code>cat cert1.pem cert2.pem > certs.pem</code>). * NB! This struct must be freed using sk_X509_free() function from OpenSSL or * with X509Stack_scope struct. * * @param path PEM formatted X.509 certificates file path. * @return returns stack of parsed X.509 certificates. * @throws IOException throws exception if the file does not contain X.509 * PEM formatted certificate(s). */ STACK_OF(X509)* digidoc::X509Cert::loadX509Stack(const std::string& path) throw(IOException) { // Create an empty X.509 stack. STACK_OF(X509)* stack = sk_X509_new_null(); if(stack == NULL) { THROW_IOEXCEPTION("Failed to create X.509 certificate stack."); } // Initialize OpenSSL file. BIO* file = BIO_new(BIO_s_file()); BIO_scope fileScope(&file); if(file == NULL) { THROW_IOEXCEPTION("Failed to open X.509 certificates file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } // Open file, which can contain multiple X.509 certificates. if(BIO_read_filename(file, path.c_str()) <= 0) { THROW_IOEXCEPTION("Failed to open X.509 certificates file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } // Read certificates info from the file. STACK_OF(X509_INFO)* certsInfo = PEM_X509_INFO_read_bio(file, NULL, NULL, NULL); if(certsInfo == NULL) { THROW_IOEXCEPTION("Failed to read X.509 certificates from file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } // Put all found certificates to the stack. for(int i = 0; i < sk_X509_INFO_num(certsInfo); i++) { X509_INFO* xi = sk_X509_INFO_value(certsInfo, i); if(xi->x509 != NULL) { sk_X509_push(stack, xi->x509); xi->x509 = NULL; } } // Release resources. sk_X509_INFO_pop_free(certsInfo, X509_INFO_free); return stack; }
X509* bdoc::X509Cert::loadX509(const std::string& path) { BIO* file = BIO_new(BIO_s_file()); BIO_scope fileScope(&file); if (file == NULL) { THROW_STACK_EXCEPTION("Failed to open X.509 certificate file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } if (BIO_read_filename(file, path.c_str()) <= 0) { THROW_STACK_EXCEPTION("Failed to open X.509 certificate file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } // Parse X.509 certificate from file. return PEM_read_bio_X509(file, NULL, NULL, NULL); }
/** * Loads RSA private key from file. * NB! This struct must be freed using RSA_free() function from OpenSSL or * with RSA_scope struct. * * @param path PEM formatted RSA private key file path. * @return returns RSA private key parsed from file. * @throws IOException throws exception if the file does not contain RSA private key. */ RSA* digidoc::RSACrypt::loadRSAPrivateKey(const std::string& path) throw(IOException) { // Initialize OpenSSL file. BIO* file = BIO_new_file(path.c_str(), "rb"); BIO_scope fileScope(&file); if(file == NULL) { THROW_IOEXCEPTION("Failed to open RSA private key file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } // Parse RSA private key from file. RSA* key = PEM_read_bio_RSAPrivateKey(file, NULL, NULL, NULL); if(key == NULL) { THROW_IOEXCEPTION("Failed to load RSA private key from file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } return key; }
STACK_OF(X509)* bdoc::X509Cert::loadX509Stack(const std::string& path) { STACK_OF(X509)* stack = sk_X509_new_null(); if (stack == NULL) { THROW_STACK_EXCEPTION("Failed to create X.509 certificate stack."); } BIO* file = BIO_new(BIO_s_file()); BIO_scope fileScope(&file); if (file == NULL) { THROW_STACK_EXCEPTION("Failed to open X.509 certificates file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } if (BIO_read_filename(file, path.c_str()) <= 0) { THROW_STACK_EXCEPTION("Failed to open X.509 certificates file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } STACK_OF(X509_INFO)* certsInfo = PEM_X509_INFO_read_bio(file, NULL, NULL, NULL); if (certsInfo == NULL) { THROW_STACK_EXCEPTION("Failed to read X.509 certificates from file '%s': %s", path.c_str(), ERR_reason_error_string(ERR_get_error())); } for (int i = 0; i < sk_X509_INFO_num(certsInfo); i++) { X509_INFO* xi = sk_X509_INFO_value(certsInfo, i); if (xi->x509 != NULL) { sk_X509_push(stack, xi->x509); xi->x509 = NULL; } } sk_X509_INFO_pop_free(certsInfo, X509_INFO_free); return stack; }
bool ClangIndexer::diagnose() { if (!mClangUnit) { return false; } List<String> compilationErrors; const unsigned diagnosticCount = clang_getNumDiagnostics(mClangUnit); Map<Location, XmlEntry> xmlEntries; for (unsigned i=0; i<diagnosticCount; ++i) { CXDiagnostic diagnostic = clang_getDiagnostic(mClangUnit, i); const CXSourceLocation diagLoc = clang_getDiagnosticLocation(diagnostic); const Location loc = createLocation(diagLoc, 0); const uint32_t fileId = loc.fileId(); if (mData->visited.value(fileId)) { const String msg = RTags::eatString(clang_getDiagnosticSpelling(diagnostic)); const CXDiagnosticSeverity sev = clang_getDiagnosticSeverity(diagnostic); XmlEntry::Type type = XmlEntry::None; switch (sev) { case CXDiagnostic_Warning: type = XmlEntry::Warning; break; case CXDiagnostic_Error: case CXDiagnostic_Fatal: type = XmlEntry::Error; break; default: break; } if (type != XmlEntry::None) { const unsigned rangeCount = clang_getDiagnosticNumRanges(diagnostic); bool ok = false; for (unsigned rangePos = 0; rangePos < rangeCount; ++rangePos) { const CXSourceRange range = clang_getDiagnosticRange(diagnostic, rangePos); const CXSourceLocation start = clang_getRangeStart(range); const CXSourceLocation end = clang_getRangeEnd(range); unsigned startOffset, endOffset; clang_getSpellingLocation(start, 0, 0, 0, &startOffset); clang_getSpellingLocation(end, 0, 0, 0, &endOffset); if (!rangePos && !startOffset && !endOffset) { // huh, range invalid? fall back to diag location break; } else { unsigned int line, column; clang_getPresumedLocation(start, 0, &line, &column); const Location key(loc.fileId(), line, column); xmlEntries[key] = XmlEntry(type, msg, endOffset - startOffset); ok = true; break; } } if (!ok) { unsigned line, column; clang_getPresumedLocation(diagLoc, 0, &line, &column); const Location key(loc.fileId(), line, column); xmlEntries[key] = XmlEntry(type, msg); // no length } } // logDirect(RTags::CompilationError, msg.constData()); const unsigned fixItCount = clang_getDiagnosticNumFixIts(diagnostic); for (unsigned f=0; f<fixItCount; ++f) { CXSourceRange range; const CXStringScope stringScope = clang_getDiagnosticFixIt(diagnostic, f, &range); CXSourceLocation start = clang_getRangeStart(range); unsigned line, column; CXString file; clang_getPresumedLocation(start, &file, &line, &column); CXStringScope fileScope(file); const Location loc = createLocation(clang_getCString(file), line, column); if (mData->visited.value(loc.fileId())) { unsigned int startOffset, endOffset; CXSourceLocation end = clang_getRangeEnd(range); clang_getSpellingLocation(start, 0, 0, 0, &startOffset); clang_getSpellingLocation(end, 0, 0, 0, &endOffset); const char *string = clang_getCString(stringScope); error("Fixit for %s:%d:%d: Replace %d characters with [%s]", loc.path().constData(), line, column, endOffset - startOffset, string); XmlEntry &entry = xmlEntries[Location(loc.fileId(), line, column)]; entry.type = XmlEntry::Fixit; if (entry.message.isEmpty()) { entry.message = String::format<64>("did you mean '%s'?", string); } entry.length = endOffset - startOffset; mData->fixIts[loc.fileId()].insert(FixIt(line, column, endOffset - startOffset, string)); } } } clang_disposeDiagnostic(diagnostic); } mData->xmlDiagnostics = "<?xml version=\"1.0\" encoding=\"utf-8\"?><checkstyle>"; if (!xmlEntries.isEmpty()) { Map<Location, XmlEntry>::const_iterator entry = xmlEntries.begin(); const Map<Location, XmlEntry>::const_iterator end = xmlEntries.end(); const char *severities[] = { "none", "warning", "error", "fixit" }; uint32_t lastFileId = 0; while (entry != end) { const Location &loc = entry->first; const XmlEntry &xmlEntry = entry->second; if (loc.fileId() != lastFileId) { if (lastFileId) mData->xmlDiagnostics += "</file>"; lastFileId = loc.fileId(); mData->xmlDiagnostics += String::format<128>("<file name=\"%s\">", loc.path().constData()); } mData->xmlDiagnostics += String::format("<error line=\"%d\" column=\"%d\" %sseverity=\"%s\" message=\"%s\"/>", loc.line(), loc.column(), (xmlEntry.length <= 0 ? "" : String::format<32>("length=\"%d\" ", xmlEntry.length).constData()), severities[xmlEntry.type], xmlEscape(xmlEntry.message).constData()); ++entry; } if (lastFileId) mData->xmlDiagnostics += "</file>"; } for (Hash<uint32_t, bool>::const_iterator it = mData->visited.begin(); it != mData->visited.end(); ++it) { if (it->second) { const Map<Location, XmlEntry>::const_iterator x = xmlEntries.lower_bound(Location(it->first, 0, 0)); if (x == xmlEntries.end() || x->first.fileId() != it->first) { const String fn = Location::path(it->first); mData->xmlDiagnostics += String::format("<file name=\"%s\"/>", fn.constData()); } } } mData->xmlDiagnostics += "</checkstyle>"; return true; }