mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-26 12:24:32 +00:00
Enhance PE Authenticode
This commit is contained in:
parent
5b587ea88f
commit
634c2fc98e
24
.github/deploy.py
vendored
24
.github/deploy.py
vendored
@ -105,7 +105,7 @@ else:
|
||||
CI_PRETTY_NAME = pretty_ci_name(CURRENT_CI)
|
||||
logger.info("CI: %s", CI_PRETTY_NAME)
|
||||
|
||||
ALLOWED_BRANCHES = {"master", "deploy", "devel"}
|
||||
ALLOWED_BRANCHES = {"master", "deploy", "devel", "enhancement/pe-authenticode"}
|
||||
BRANCH_NAME = get_branch(CURRENT_CI)
|
||||
logger.info("Branch: %s", BRANCH_NAME)
|
||||
if BRANCH_NAME not in ALLOWED_BRANCHES:
|
||||
@ -175,13 +175,29 @@ if DEPLOY_IV is None:
|
||||
# Clone package repo
|
||||
#####################
|
||||
target_branch = "gh-pages" if BRANCH_NAME == "master" else "packages-{}".format(BRANCH_NAME)
|
||||
new_branch = False
|
||||
if not LIEF_PACKAGE_DIR.is_dir():
|
||||
cmd = "{} clone --branch={} -j8 --single-branch {} {}".format(GIT, target_branch, LIEF_PACKAGE_REPO, LIEF_PACKAGE_DIR)
|
||||
p = subprocess.Popen(cmd, shell=True, cwd=REPODIR, stderr=subprocess.STDOUT)
|
||||
p.wait()
|
||||
|
||||
if p.returncode:
|
||||
sys.exit(1)
|
||||
cmd = "{} clone --branch=master -j8 --single-branch {} {}".format(GIT, LIEF_PACKAGE_REPO, LIEF_PACKAGE_DIR)
|
||||
pmaster = subprocess.Popen(cmd, shell=True, cwd=REPODIR, stderr=subprocess.STDOUT)
|
||||
pmaster.wait()
|
||||
if pmaster.returncode:
|
||||
sys.exit(1)
|
||||
new_branch = True
|
||||
|
||||
cmd = "{} checkout --orphan {}".format(GIT, target_branch)
|
||||
pmaster = subprocess.Popen(cmd, shell=True, cwd=LIEF_PACKAGE_DIR, stderr=subprocess.STDOUT)
|
||||
pmaster.wait()
|
||||
if pmaster.returncode:
|
||||
sys.exit(1)
|
||||
|
||||
cmd = "{} reset --hard".format(GIT)
|
||||
pmaster = subprocess.Popen(cmd, shell=True, cwd=LIEF_PACKAGE_DIR, stderr=subprocess.STDOUT)
|
||||
pmaster.wait()
|
||||
|
||||
SDK_PACKAGE_DIR.mkdir(exist_ok=True)
|
||||
PYPI_PACKAGE_DIR.mkdir(exist_ok=True)
|
||||
@ -261,10 +277,6 @@ html = Template(INDEX_TEMPLATE).render(names=fnames, base_url=BASE_URL, base="pa
|
||||
with open((SDK_PACKAGE_DIR / "index.html").as_posix(), "w") as f:
|
||||
f.write(html)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if not SSH_DIR.is_dir():
|
||||
SSH_DIR.mkdir(mode=0o700)
|
||||
|
||||
|
@ -106,6 +106,8 @@ set(LIBLIEF_SOURCE_FILES
|
||||
"${mbedtls_src_x509}"
|
||||
"${mbedtls_src_tls}"
|
||||
"${LIBFUZZER_SRC_FILES}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/errors.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/hash_stream.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/logging.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/exception.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/iostream.cpp"
|
||||
@ -121,6 +123,7 @@ set(LIBLIEF_SOURCE_FILES
|
||||
# Grouping basic headers together
|
||||
# ===============================
|
||||
set(LIEF_INC_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/errors.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/Abstract.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/exception.hpp"
|
||||
@ -139,6 +142,7 @@ set(LIEF_INC_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/BinaryStream/BinaryStream.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/BinaryStream/VectorStream.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/BinaryStream/Convert.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/hash_stream.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/frozen.hpp")
|
||||
|
||||
set(LIEF_VISITOR_INCLUDE_FILES
|
||||
@ -284,10 +288,9 @@ list(APPEND LIEF_PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include/")
|
||||
|
||||
list(APPEND LIEF_PRIVATE_INCLUDE_DIR "${LIEF_PUBLIC_INCLUDE_DIR}"
|
||||
"${LIBRANG_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_BINARY_DIR}")
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src" "${CMAKE_BINARY_DIR}")
|
||||
|
||||
configure_file(${PROJECT_SOURCE_DIR}/LIEF.pc.in ${PROJECT_BINARY_DIR}/LIEF.pc
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/LIEF.pc.in ${CMAKE_CURRENT_BINARY_DIR}/LIEF.pc
|
||||
@ONLY)
|
||||
|
||||
# Grouping external projects
|
||||
@ -322,6 +325,15 @@ if(LIEF_FROZEN_ENABLED)
|
||||
add_dependencies(LIB_LIEF lief_frozen)
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/boost/leaf/all.hpp
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${LEAF_INCLUDE_DIR}/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/
|
||||
DEPENDS lief_leaf)
|
||||
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/boost/leaf/all.hpp)
|
||||
|
||||
add_dependencies(LIB_LIEF lief_spdlog lief_mbed_tls)
|
||||
|
||||
# Flags definition
|
||||
@ -351,7 +363,8 @@ target_compile_definitions(LIB_LIEF PUBLIC -D_GLIBCXX_USE_CXX11_ABI=1)
|
||||
# SpcSpAgencyInfo Critical Extension, which mbed TLS doesn't support, so set
|
||||
# MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION to have it skip this
|
||||
# extension.
|
||||
add_definitions(-DMBEDTLS_MD2_C -DMBEDTLS_MD4_C
|
||||
add_definitions(-DMBEDTLS_MD2_C -DMBEDTLS_MD4_C -DMBEDTLS_PEM_PARSE_C
|
||||
-DMBEDTLS_X509_CRT_PARSE_C -DMBEDTLS_PEM_WRITE_C
|
||||
-DMBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
|
||||
|
||||
# ASAN - LSAN - TSAN - USAN
|
||||
@ -496,6 +509,7 @@ endif()
|
||||
|
||||
# Tests
|
||||
# ======================
|
||||
|
||||
if(LIEF_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tests")
|
||||
@ -584,7 +598,7 @@ install(
|
||||
COMPONENT config)
|
||||
|
||||
install(
|
||||
FILES ${PROJECT_BINARY_DIR}/LIEF.pc
|
||||
FILES ${CMAKE_BINARY_DIR}/LIEF.pc
|
||||
DESTINATION lib/pkgconfig
|
||||
COMPONENT libraries)
|
||||
|
||||
|
@ -181,8 +181,8 @@ void create<Binary>(py::module& m) {
|
||||
|
||||
.def("xref",
|
||||
&Binary::xref,
|
||||
"Return all **virtual address** that *use* the ``address`` given in parameter"
|
||||
"virtual_address"_a)
|
||||
"Return all **virtual addresses** that *use* the ``address`` given in parameter",
|
||||
"virtual_address"_a)
|
||||
|
||||
.def("__str__",
|
||||
[] (const Binary& binary)
|
||||
|
@ -16,12 +16,6 @@ set(LIEF_PYTHON_PE_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/resources/pyResourceStringTable.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/resources/pyResourceAccelerator.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pySignerInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pyAuthenticatedAttributes.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pyx509.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pyContentInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pySignature.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeIntegrity.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataDirectory.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDosHeader.cpp"
|
||||
@ -62,6 +56,6 @@ target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_PE_SRC}" "${LIEF_PYTHON_PE_HDR}")
|
||||
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/objects/LoadConfigurations/CMakeLists.txt")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/objects/signature/CMakeLists.txt")
|
||||
|
||||
|
||||
|
@ -132,8 +132,8 @@ void create<Binary>(py::module& m) {
|
||||
.def_property_readonly("has_configuration", &Binary::has_configuration,
|
||||
"``True`` if the current binary has " RST_CLASS_REF(lief.PE.LoadConfiguration) "")
|
||||
|
||||
.def_property_readonly("has_signature", &Binary::has_signature,
|
||||
"``True`` if the binary is signed (" RST_CLASS_REF(lief.PE.Signature) ")")
|
||||
.def_property_readonly("has_signatures", &Binary::has_signatures,
|
||||
"``True`` if the binary has signatures (" RST_CLASS_REF(lief.PE.Signature) ")")
|
||||
|
||||
.def_property_readonly("is_reproducible_build", &Binary::is_reproducible_build,
|
||||
"``True`` if the binary was compiled with a reproducible build directive (" RST_CLASS_REF(lief.PE.Debug) ")")
|
||||
@ -151,11 +151,69 @@ void create<Binary>(py::module& m) {
|
||||
"Try to predict the RVA of the given function name in the given import library name",
|
||||
"library"_a, "function"_a)
|
||||
|
||||
.def_property_readonly("signature",
|
||||
static_cast<const Signature& (Binary::*)(void) const>(&Binary::signature),
|
||||
"Return the " RST_CLASS_REF(lief.PE.Signature) " object",
|
||||
.def_property_readonly("signatures",
|
||||
static_cast<it_const_signatures (Binary::*)(void) const>(&Binary::signatures),
|
||||
"Return an iterator over the " RST_CLASS_REF(lief.PE.Signature) " objects",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("authentihash",
|
||||
[] (const Binary& bin, ALGORITHMS algo) {
|
||||
const std::vector<uint8_t>& data = bin.authentihash(algo);
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"Compute the authentihash according to the " RST_CLASS_REF(lief.PE.ALGORITHMS) " "
|
||||
"given in the first parameter",
|
||||
"algorithm"_a)
|
||||
|
||||
.def("verify_signature",
|
||||
static_cast<Signature::VERIFICATION_FLAGS(Binary::*)() const>(&Binary::verify_signature),
|
||||
R"delim(
|
||||
Verify the binary against the embedded signature(s) (if any)
|
||||
Firstly, it checks that the embedded signatures are correct (c.f. :meth:`lief.PE.Signature.check`)
|
||||
and then it checks that the authentihash matches :attr:`lief.PE.ContentInfo.digest`
|
||||
)delim")
|
||||
|
||||
.def("verify_signature",
|
||||
static_cast<Signature::VERIFICATION_FLAGS(Binary::*)(const Signature&) const>(&Binary::verify_signature),
|
||||
R"delim(
|
||||
Verify the binary with the Signature object provided in the first parameter
|
||||
It can be used to verify a detached signature:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
detached = lief.PE.Signature.parse("sig.pkcs7")
|
||||
binary.verify_signature(detached)
|
||||
)delim",
|
||||
"signature"_a)
|
||||
|
||||
.def_property_readonly("authentihash_md5",
|
||||
[] (const Binary& bin) {
|
||||
const std::vector<uint8_t>& data = bin.authentihash(ALGORITHMS::MD5);
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"Authentihash **MD5** value")
|
||||
|
||||
.def_property_readonly("authentihash_sha1",
|
||||
[] (const Binary& bin) {
|
||||
const std::vector<uint8_t>& data = bin.authentihash(ALGORITHMS::SHA_1);
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"Authentihash **SHA1** value")
|
||||
|
||||
.def_property_readonly("authentihash_sha256",
|
||||
[] (const Binary& bin) {
|
||||
const std::vector<uint8_t>& data = bin.authentihash(ALGORITHMS::SHA_256);
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"Authentihash **SHA-256** value")
|
||||
|
||||
.def_property_readonly("authentihash_sha512",
|
||||
[] (const Binary& bin) {
|
||||
const std::vector<uint8_t>& data = bin.authentihash(ALGORITHMS::SHA_512);
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"Authentihash **SHA-512** value")
|
||||
|
||||
.def_property_readonly("debug",
|
||||
static_cast<debug_entries_t& (Binary::*)(void)>(&Binary::debug),
|
||||
"Return the " RST_CLASS_REF(lief.PE.Debug) "",
|
||||
|
14
api/python/PE/objects/signature/CMakeLists.txt
Normal file
14
api/python/PE/objects/signature/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
set(LIEF_PYTHON_PE_SIG_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pySignerInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyAttribute.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyx509.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyContentInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pySignature.cpp"
|
||||
)
|
||||
|
||||
source_group("Header Files\\PE\\signature" FILES ${LIEF_PYTHON_PE_SIG_SRC})
|
||||
|
||||
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
|
||||
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_PE_SIG_SRC})
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/attributes/CMakeLists.txt")
|
19
api/python/PE/objects/signature/attributes/CMakeLists.txt
Normal file
19
api/python/PE/objects/signature/attributes/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
set(LIEF_PYTHON_PE_SIG_ATTR_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyMsCounterSign.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyContentType.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyGenericType.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pySpcSpOpusInfo.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyMsSpcStatementType.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyMsSpcNestedSignature.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyPKCS9SigningTime.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyPKCS9MessageDigest.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyPKCS9AtSequenceNumber.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/pyPKCS9CounterSignature.cpp"
|
||||
)
|
||||
|
||||
source_group("Header Files\\PE\\signature\\attributes" FILES ${LIEF_PYTHON_PE_SIG_ATTR_SRC})
|
||||
|
||||
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
|
||||
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_PE_SIG_ATTR_SRC})
|
50
api/python/PE/objects/signature/attributes/pyContentType.cpp
Normal file
50
api/python/PE/objects/signature/attributes/pyContentType.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/ContentType.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (ContentType::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (ContentType::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<ContentType>(py::module& m) {
|
||||
py::class_<ContentType, Attribute>(m, "ContentType")
|
||||
.def_property_readonly("oid",
|
||||
&ContentType::oid)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const ContentType& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &ContentType::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
53
api/python/PE/objects/signature/attributes/pyGenericType.cpp
Normal file
53
api/python/PE/objects/signature/attributes/pyGenericType.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/GenericType.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (GenericType::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (GenericType::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<GenericType>(py::module& m) {
|
||||
py::class_<GenericType, Attribute>(m, "GenericType")
|
||||
.def_property_readonly("oid",
|
||||
&GenericType::oid)
|
||||
|
||||
.def_property_readonly("raw_content",
|
||||
&GenericType::raw_content)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const GenericType& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &GenericType::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/MsCounterSign.hpp"
|
||||
|
||||
#include "pyPE.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/MsSpcNestedSignature.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (MsSpcNestedSignature::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (MsSpcNestedSignature::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<MsSpcNestedSignature>(py::module& m) {
|
||||
py::class_<MsSpcNestedSignature, Attribute>(m, "MsSpcNestedSignature")
|
||||
.def_property_readonly("signature",
|
||||
&MsSpcNestedSignature::sig,
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const MsSpcNestedSignature& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &MsSpcNestedSignature::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/MsSpcStatementType.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (MsSpcStatementType::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (MsSpcStatementType::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<MsSpcStatementType>(py::module& m) {
|
||||
py::class_<MsSpcStatementType, Attribute>(m, "MsSpcStatementType")
|
||||
.def_property_readonly("oid",
|
||||
&MsSpcStatementType::oid)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const MsSpcStatementType& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &MsSpcStatementType::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9AtSequenceNumber.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (PKCS9AtSequenceNumber::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (PKCS9AtSequenceNumber::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<PKCS9AtSequenceNumber>(py::module& m) {
|
||||
py::class_<PKCS9AtSequenceNumber, Attribute>(m, "PKCS9AtSequenceNumber")
|
||||
.def_property_readonly("number",
|
||||
&PKCS9AtSequenceNumber::number)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const PKCS9AtSequenceNumber& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &PKCS9AtSequenceNumber::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9CounterSignature.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (PKCS9CounterSignature::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (PKCS9CounterSignature::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<PKCS9CounterSignature>(py::module& m) {
|
||||
py::class_<PKCS9CounterSignature, Attribute>(m, "PKCS9CounterSignature")
|
||||
.def_property_readonly("signers",
|
||||
&PKCS9CounterSignature::signers)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const PKCS9CounterSignature& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &PKCS9CounterSignature::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9MessageDigest.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (PKCS9MessageDigest::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (PKCS9MessageDigest::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<PKCS9MessageDigest>(py::module& m) {
|
||||
py::class_<PKCS9MessageDigest, Attribute>(m, "PKCS9MessageDigest")
|
||||
.def_property_readonly("digest",
|
||||
[] (const PKCS9MessageDigest& digest) -> py::object {
|
||||
const std::vector<uint8_t>& data = digest.digest();
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
})
|
||||
|
||||
.def("__hash__",
|
||||
[] (const PKCS9MessageDigest& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
|
||||
.def("__str__", &PKCS9MessageDigest::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9SigningTime.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (PKCS9SigningTime::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (PKCS9SigningTime::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<PKCS9SigningTime>(py::module& m) {
|
||||
py::class_<PKCS9SigningTime, Attribute>(m, "PKCS9SigningTime")
|
||||
.def_property_readonly("time",
|
||||
&PKCS9SigningTime::time)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const PKCS9SigningTime& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &PKCS9SigningTime::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes/SpcSpOpusInfo.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (SpcSpOpusInfo::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (SpcSpOpusInfo::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<SpcSpOpusInfo>(py::module& m) {
|
||||
py::class_<SpcSpOpusInfo, Attribute>(m, "SpcSpOpusInfo")
|
||||
.def_property_readonly("program_name",
|
||||
[] (const SpcSpOpusInfo& info) {
|
||||
return safe_string_converter(info.program_name());
|
||||
})
|
||||
|
||||
.def_property_readonly("more_info",
|
||||
[] (const SpcSpOpusInfo& info) {
|
||||
return safe_string_converter(info.more_info());
|
||||
})
|
||||
|
||||
.def("__hash__",
|
||||
[] (const SpcSpOpusInfo& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__", &SpcSpOpusInfo::print);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
51
api/python/PE/objects/signature/pyAttribute.cpp
Normal file
51
api/python/PE/objects/signature/pyAttribute.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (Attribute::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (Attribute::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<Attribute>(py::module& m) {
|
||||
py::class_<Attribute, Object>(m, "Attribute")
|
||||
.def_property_readonly("type",
|
||||
&Attribute::type)
|
||||
|
||||
|
||||
.def("__str__", [] (const Attribute& attr)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
//stream << config;
|
||||
//std::string str = stream.str();
|
||||
return stream.str();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/utils.hpp"
|
||||
#include "LIEF/PE/signature/AuthenticatedAttributes.hpp"
|
||||
|
||||
#include "pyPE.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (AuthenticatedAttributes::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (AuthenticatedAttributes::*)(T);
|
||||
|
||||
|
||||
template<>
|
||||
void create<AuthenticatedAttributes>(py::module& m) {
|
||||
|
||||
py::class_<AuthenticatedAttributes, LIEF::Object>(m, "AuthenticatedAttributes")
|
||||
|
||||
.def_property_readonly("content_type",
|
||||
&AuthenticatedAttributes::content_type,
|
||||
"Should return the ``messageDigest`` OID")
|
||||
|
||||
.def_property_readonly("message_digest",
|
||||
&AuthenticatedAttributes::message_digest,
|
||||
"Return an hash of the signed attributes")
|
||||
|
||||
.def_property_readonly("program_name",
|
||||
[] (const AuthenticatedAttributes& authenticated_attributes) {
|
||||
return safe_string_converter(LIEF::u16tou8(authenticated_attributes.program_name()));
|
||||
},
|
||||
"Return the program description (if any)")
|
||||
|
||||
.def_property_readonly("more_info",
|
||||
[] (const AuthenticatedAttributes& obj) {
|
||||
return safe_string_converter(obj.more_info());
|
||||
},
|
||||
"Return an URL to website with more information about the signer")
|
||||
|
||||
.def_property_readonly("raw",
|
||||
&AuthenticatedAttributes::raw,
|
||||
"Return the raw bytes associated with the AuthenticatedAttributes")
|
||||
|
||||
.def("__str__",
|
||||
[] (const AuthenticatedAttributes& authenticated_attributes)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << authenticated_attributes;
|
||||
std::string str = stream.str();
|
||||
return str;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -40,21 +40,23 @@ void create<ContentInfo>(py::module& m) {
|
||||
&ContentInfo::content_type,
|
||||
"OID of the content type. This value should match ``SPC_INDIRECT_DATA_OBJID``")
|
||||
|
||||
.def_property_readonly("type",
|
||||
&ContentInfo::type)
|
||||
|
||||
.def_property_readonly("digest_algorithm",
|
||||
.def_property_readonly("digest_algorithm",
|
||||
&ContentInfo::digest_algorithm,
|
||||
"Algorithm (OID) used to hash the file. This value should match SignerInfo.digest_algorithm and Signature.digest_algorithm")
|
||||
|
||||
"Algorithm (" RST_CLASS_REF(lief.PE.ALGORITHMS) ") used to hash the file. "
|
||||
"This value should match " RST_ATTR_REF_FULL(SignerInfo.digest_algorithm) " and "
|
||||
"" RST_ATTR_REF_FULL(Signature.digest_algorithm) "")
|
||||
|
||||
.def_property_readonly("digest",
|
||||
&ContentInfo::digest,
|
||||
"The digest")
|
||||
[] (const ContentInfo& info) -> py::bytes {
|
||||
const std::vector<uint8_t>& dg = info.digest();
|
||||
return py::bytes(reinterpret_cast<const char*>(dg.data()), dg.size());
|
||||
},
|
||||
"The digest as ``bytes`` ")
|
||||
|
||||
.def_property_readonly("raw",
|
||||
&ContentInfo::raw,
|
||||
"Return the raw bytes associated with the ContentInfo")
|
||||
.def("__hash__",
|
||||
[] (const ContentInfo& info) {
|
||||
return Hash::hash(info);
|
||||
})
|
||||
|
||||
.def("__str__",
|
||||
[] (const ContentInfo& content_info)
|
||||
|
@ -16,8 +16,11 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "enums_wrapper.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/Signature.hpp"
|
||||
#include "LIEF/PE/signature/SignatureParser.hpp"
|
||||
|
||||
#include "pyPE.hpp"
|
||||
|
||||
@ -34,7 +37,42 @@ using setter_t = void (Signature::*)(T);
|
||||
template<>
|
||||
void create<Signature>(py::module& m) {
|
||||
|
||||
py::class_<Signature, LIEF::Object>(m, "Signature")
|
||||
py::class_<Signature, LIEF::Object> signature(m, "Signature");
|
||||
LIEF::enum_<Signature::VERIFICATION_FLAGS>(signature, "VERIFICATION_FLAGS", py::arithmetic())
|
||||
.value("OK", Signature::VERIFICATION_FLAGS::OK)
|
||||
.value("INVALID_SIGNER", Signature::VERIFICATION_FLAGS::INVALID_SIGNER)
|
||||
.value("UNSUPPORTED_ALGORITHM", Signature::VERIFICATION_FLAGS::UNSUPPORTED_ALGORITHM)
|
||||
.value("INCONSISTENT_DIGEST_ALGORITHM", Signature::VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM)
|
||||
.value("CERT_NOT_FOUND", Signature::VERIFICATION_FLAGS::CERT_NOT_FOUND)
|
||||
.value("CORRUPTED_CONTENT_INFO", Signature::VERIFICATION_FLAGS::CORRUPTED_CONTENT_INFO)
|
||||
.value("CORRUPTED_AUTH_DATA", Signature::VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA)
|
||||
.value("MISSING_PKCS9_MESSAGE_DIGEST", Signature::VERIFICATION_FLAGS::MISSING_PKCS9_MESSAGE_DIGEST)
|
||||
.value("BAD_DIGEST", Signature::VERIFICATION_FLAGS::BAD_DIGEST)
|
||||
.value("BAD_SIGNATURE", Signature::VERIFICATION_FLAGS::BAD_SIGNATURE)
|
||||
.value("NO_SIGNATURE", Signature::VERIFICATION_FLAGS::NO_SIGNATURE);
|
||||
|
||||
signature
|
||||
.def_static("parse",
|
||||
[] (const std::string& path) -> py::object {
|
||||
auto sig = SignatureParser::parse(path);
|
||||
if (not sig) {
|
||||
return py::none();
|
||||
}
|
||||
return py::cast(sig.value());
|
||||
},
|
||||
"Parse the DER PKCS #7 signature from the file path given in the first parameter",
|
||||
"path"_a)
|
||||
|
||||
.def_static("parse",
|
||||
[] (const std::vector<uint8_t>& raw, bool skip_header) -> py::object {
|
||||
auto sig = SignatureParser::parse(raw, skip_header);
|
||||
if (not sig) {
|
||||
return py::none();
|
||||
}
|
||||
return py::cast(sig.value());
|
||||
},
|
||||
"Parse the raw (DER) PKCS #7 signature given in the first parameter",
|
||||
"raw"_a, "skip_header"_a = false)
|
||||
|
||||
.def_property_readonly("version",
|
||||
&Signature::version,
|
||||
@ -42,7 +80,8 @@ void create<Signature>(py::module& m) {
|
||||
|
||||
.def_property_readonly("digest_algorithm",
|
||||
&Signature::digest_algorithm,
|
||||
"Return the algorithm (OID) used to sign the content of " RST_CLASS_REF(lief.PE.ContentInfo) "")
|
||||
"Return the algorithm (" RST_CLASS_REF(lief.PE.ALGORITHMS) ") \
|
||||
used to sign the content of " RST_CLASS_REF(lief.PE.ContentInfo) "")
|
||||
|
||||
|
||||
.def_property_readonly("content_info",
|
||||
@ -57,24 +96,34 @@ void create<Signature>(py::module& m) {
|
||||
py::return_value_policy::reference)
|
||||
|
||||
|
||||
.def_property_readonly("signer_info",
|
||||
&Signature::signer_info,
|
||||
"Return the " RST_CLASS_REF(lief.PE.SignerInfo) "",
|
||||
.def_property_readonly("signers",
|
||||
&Signature::signers,
|
||||
"Return an iterator over the signers: " RST_CLASS_REF(lief.PE.SignerInfo) "",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("check",
|
||||
&Signature::check,
|
||||
"Check the integrity of the signature and return a " RST_CLASS_REF(lief.PE.Signature.VERIFICATION_FLAGS) "")
|
||||
|
||||
.def_property_readonly("original_signature",
|
||||
&Signature::original_signature,
|
||||
"Return the raw original signature")
|
||||
.def_property_readonly("raw_der",
|
||||
[] (const Signature& sig) {
|
||||
const std::vector<uint8_t>& raw = sig.raw_der();
|
||||
return py::bytes(reinterpret_cast<const char*>(raw.data()), raw.size());
|
||||
},
|
||||
"Return the raw original signature",
|
||||
py::return_value_policy::reference_internal)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const Signature& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__",
|
||||
[] (const Signature& signature)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << signature;
|
||||
std::string str = stream.str();
|
||||
return str;
|
||||
return stream.str();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -40,31 +40,68 @@ void create<SignerInfo>(py::module& m) {
|
||||
&SignerInfo::version,
|
||||
"Should be 1")
|
||||
|
||||
.def_property_readonly("serial_number",
|
||||
[] (const SignerInfo& info) -> py::bytes {
|
||||
const std::vector<uint8_t>& data = info.serial_number();
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"The X509 serial number used to sign the signed-data")
|
||||
|
||||
.def_property_readonly("issuer",
|
||||
[] (const SignerInfo& object) {
|
||||
const issuer_t& issuer = object.issuer();
|
||||
return std::pair<py::object, std::vector<uint8_t>>{safe_string_converter(std::get<0>(issuer)), std::get<1>(issuer)};
|
||||
return safe_string_converter(object.issuer());
|
||||
},
|
||||
"Issuer and serial number",
|
||||
py::return_value_policy::copy)
|
||||
|
||||
.def_property_readonly("digest_algorithm",
|
||||
&SignerInfo::digest_algorithm,
|
||||
"Algorithm (OID) used to hash the file. This value should match ContentInfo.digest_algorithm and Signature.digest_algorithm")
|
||||
"Algorithm (" RST_CLASS_REF(lief.PE.ALGORITHMS) ") used to hash the file. "
|
||||
"This value should match " RST_ATTR_REF_FULL(ContentInfo.digest_algorithm) " "
|
||||
"and " RST_ATTR_REF_FULL(Signature.digest_algorithm) "")
|
||||
|
||||
.def_property_readonly("signature_algorithm",
|
||||
&SignerInfo::signature_algorithm,
|
||||
"Return the signature algorithm (OID)")
|
||||
.def_property_readonly("encryption_algorithm",
|
||||
&SignerInfo::encryption_algorithm,
|
||||
"Return algorithm (" RST_CLASS_REF(lief.PE.ALGORITHMS) ") used to encrypt the digest")
|
||||
|
||||
.def_property_readonly("encrypted_digest",
|
||||
&SignerInfo::encrypted_digest,
|
||||
[] (const SignerInfo& info) {
|
||||
const std::vector<uint8_t>& data = info.encrypted_digest();
|
||||
return py::bytes(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
},
|
||||
"Return the signature created by the signing certificate's private key")
|
||||
|
||||
.def_property_readonly("authenticated_attributes",
|
||||
&SignerInfo::authenticated_attributes,
|
||||
"Return the " RST_CLASS_REF(lief.PE.AuthenticatedAttributes) " object",
|
||||
"Return an iterator over the authenticated attributes ("
|
||||
"" RST_CLASS_REF(lief.PE.Attribute) ")",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def_property_readonly("unauthenticated_attributes",
|
||||
&SignerInfo::unauthenticated_attributes,
|
||||
"Return an iterator over the unauthenticated attributes ("
|
||||
"" RST_CLASS_REF(lief.PE.Attribute) ")",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("get_attribute",
|
||||
&SignerInfo::get_attribute,
|
||||
"Return the authenticated or un-authenticated attribute matching the "
|
||||
"given " RST_CLASS_REF(lief.PE.SIG_ATTRIBUTE_TYPES) " \n\n"
|
||||
"It returns **the first** entry that matches the given type. If it can't be "
|
||||
"found, it returns a nullptr",
|
||||
"type"_a,
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def_property_readonly("cert",
|
||||
static_cast<x509*(SignerInfo::*)()>(&SignerInfo::cert),
|
||||
"" RST_CLASS_REF(lief.PE.x509) " certificate used by this signer. If it can't be found, it returns None",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const SignerInfo& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__",
|
||||
[] (const SignerInfo& signer_info)
|
||||
{
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "enums_wrapper.hpp"
|
||||
|
||||
#include "LIEF/PE/hash.hpp"
|
||||
#include "LIEF/PE/signature/x509.hpp"
|
||||
|
||||
@ -34,14 +36,54 @@ using setter_t = void (x509::*)(T);
|
||||
template<>
|
||||
void create<x509>(py::module& m) {
|
||||
|
||||
py::class_<x509, LIEF::Object>(m, "x509")
|
||||
py::class_<x509, LIEF::Object> cls_x509(m, "x509");
|
||||
|
||||
LIEF::enum_<x509::VERIFICATION_FLAGS>(cls_x509, "VERIFICATION_FLAGS", py::arithmetic(),
|
||||
"Verification flags associated with " RST_METH_REF(lief.PE.x509.verify) "")
|
||||
.value("OK", x509::VERIFICATION_FLAGS::OK, "The verification succeed")
|
||||
.value("BADCERT_EXPIRED", x509::VERIFICATION_FLAGS::BADCERT_EXPIRED, "The certificate validity has expired")
|
||||
.value("BADCERT_REVOKED", x509::VERIFICATION_FLAGS::BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)")
|
||||
.value("BADCERT_CN_MISMATCH", x509::VERIFICATION_FLAGS::BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN.")
|
||||
.value("BADCERT_NOT_TRUSTED", x509::VERIFICATION_FLAGS::BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA.")
|
||||
.value("BADCRL_NOT_TRUSTED", x509::VERIFICATION_FLAGS::BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA.")
|
||||
.value("BADCRL_EXPIRED", x509::VERIFICATION_FLAGS::BADCRL_EXPIRED, "The CRL is expired.")
|
||||
.value("BADCERT_MISSING", x509::VERIFICATION_FLAGS::BADCERT_MISSING, "Certificate was missing.")
|
||||
.value("BADCERT_SKIP_VERIFY", x509::VERIFICATION_FLAGS::BADCERT_SKIP_VERIFY, "Certificate verification was skipped.")
|
||||
.value("BADCERT_OTHERNATURE", x509::VERIFICATION_FLAGS::BADCERT_OTHER, "Other reason")
|
||||
.value("BADCERT_FUTURE", x509::VERIFICATION_FLAGS::BADCERT_FUTURE, "The certificate validity starts in the future.")
|
||||
.value("BADCRL_FUTURE", x509::VERIFICATION_FLAGS::BADCRL_FUTURE, "The CRL is from the future")
|
||||
.value("BADCERT_KEY_USAGE", x509::VERIFICATION_FLAGS::BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension.")
|
||||
.value("BADCERT_EXT_KEY_USAGE", x509::VERIFICATION_FLAGS::BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension.")
|
||||
.value("BADCERT_NS_CERT_TYPE", x509::VERIFICATION_FLAGS::BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension.")
|
||||
.value("BADCERT_BAD_MD", x509::VERIFICATION_FLAGS::BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash.")
|
||||
.value("BADCERT_BAD_PK", x509::VERIFICATION_FLAGS::BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA).")
|
||||
.value("BADCERT_BAD_KEY", x509::VERIFICATION_FLAGS::BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short).")
|
||||
.value("BADCRL_BAD_MD", x509::VERIFICATION_FLAGS::BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash.")
|
||||
.value("BADCRL_BAD_PK", x509::VERIFICATION_FLAGS::BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA).")
|
||||
.value("BADCRL_BAD_KEY", x509::VERIFICATION_FLAGS::BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short).");
|
||||
|
||||
cls_x509
|
||||
.def_static("parse",
|
||||
static_cast<x509::certificates_t(*)(const std::string&)>(&x509::parse),
|
||||
"Parse " RST_CLASS_REF(lief.PE.x509) " certificate(s) from a file path given in the first parameter.\n"
|
||||
"It returns a **list** of " RST_CLASS_REF(lief.PE.x509) " objects",
|
||||
"path"_a)
|
||||
|
||||
.def_static("parse",
|
||||
static_cast<x509::certificates_t(*)(const std::vector<uint8_t>&)>(&x509::parse),
|
||||
"Parse " RST_CLASS_REF(lief.PE.x509) " certificate(s) from a raw blob given in the first parameter.\n"
|
||||
"It returns a **list** of " RST_CLASS_REF(lief.PE.x509) " objects",
|
||||
"raw"_a)
|
||||
|
||||
.def_property_readonly("version",
|
||||
&x509::version,
|
||||
"X.509 version. (1=v1, 2=v2, 3=v3)")
|
||||
|
||||
.def_property_readonly("serial_number",
|
||||
&x509::serial_number,
|
||||
[] (const x509& crt) -> py::bytes {
|
||||
const std::vector<uint8_t>& sn = crt.serial_number();
|
||||
return py::bytes(reinterpret_cast<const char*>(sn.data()), sn.size());
|
||||
},
|
||||
"Unique id for certificate issued by a specific CA.")
|
||||
|
||||
.def_property_readonly("signature_algorithm",
|
||||
@ -58,14 +100,12 @@ void create<x509>(py::module& m) {
|
||||
&x509::valid_to,
|
||||
"End time of certificate validity")
|
||||
|
||||
|
||||
.def_property_readonly("issuer",
|
||||
[] (const x509& object) {
|
||||
return safe_string_converter(object.issuer());
|
||||
},
|
||||
"Issuer informations")
|
||||
|
||||
|
||||
.def_property_readonly("subject",
|
||||
[] (const x509& object) {
|
||||
return safe_string_converter(object.subject());
|
||||
@ -73,16 +113,35 @@ void create<x509>(py::module& m) {
|
||||
"Subject informations")
|
||||
|
||||
.def_property_readonly("raw",
|
||||
&x509::raw,
|
||||
[] (const x509& crt) -> py::bytes {
|
||||
const std::vector<uint8_t>& raw = crt.raw();
|
||||
return py::bytes(reinterpret_cast<const char*>(raw.data()), raw.size());
|
||||
},
|
||||
"The raw bytes associated with this x509 cert (DER encoded)")
|
||||
|
||||
.def("verify",
|
||||
static_cast<x509::VERIFICATION_FLAGS(x509::*)(const x509&) const>(&x509::verify),
|
||||
"Verify that this certificate has been used **to trust** the given certificate (" RST_CLASS_REF(lief.PE.x509) " object) "
|
||||
"It returns a set of flags defined by " RST_CLASS_REF(lief.PE.x509.VERIFICATION_FLAGS) "",
|
||||
"ca"_a)
|
||||
|
||||
.def("is_trusted_by",
|
||||
&x509::is_trusted_by,
|
||||
"Verify this certificate against a list of root CA (list of " RST_CLASS_REF(lief.PE.x509) " object) "
|
||||
"It returns a set of flags defined by " RST_CLASS_REF(lief.PE.x509.VERIFICATION_FLAGS) "",
|
||||
"ca_list"_a)
|
||||
|
||||
.def("__hash__",
|
||||
[] (const x509& obj) {
|
||||
return Hash::hash(obj);
|
||||
})
|
||||
|
||||
.def("__str__",
|
||||
[] (const x509& x509_crt)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << x509_crt;
|
||||
std::string str = stream.str();
|
||||
return str;
|
||||
return safe_string_converter(stream.str());
|
||||
});
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -78,10 +78,19 @@ void init_objects(py::module& m) {
|
||||
CREATE(ResourceAccelerator, m);
|
||||
CREATE(Signature, m);
|
||||
CREATE(x509, m);
|
||||
CREATE(SignerInfo, m);
|
||||
CREATE(ContentInfo, m);
|
||||
CREATE(AuthenticatedAttributes, m);
|
||||
CREATE(SignerInfo, m);
|
||||
CREATE(CodeIntegrity, m);
|
||||
CREATE(Attribute, m);
|
||||
CREATE(ContentType, m);
|
||||
CREATE(GenericType, m);
|
||||
CREATE(MsSpcNestedSignature, m);
|
||||
CREATE(MsSpcStatementType, m);
|
||||
CREATE(PKCS9AtSequenceNumber, m);
|
||||
CREATE(PKCS9CounterSignature, m);
|
||||
CREATE(PKCS9MessageDigest, m);
|
||||
CREATE(PKCS9SigningTime, m);
|
||||
CREATE(SpcSpOpusInfo, m);
|
||||
|
||||
CREATE(LoadConfiguration, m);
|
||||
CREATE(LoadConfigurationV0, m);
|
||||
|
@ -81,13 +81,23 @@ SPECIALIZE_CREATE(ResourceStringTable);
|
||||
SPECIALIZE_CREATE(ResourceDialog);
|
||||
SPECIALIZE_CREATE(ResourceDialogItem);
|
||||
SPECIALIZE_CREATE(ResourceAccelerator);
|
||||
|
||||
SPECIALIZE_CREATE(Signature);
|
||||
SPECIALIZE_CREATE(x509);
|
||||
SPECIALIZE_CREATE(SignerInfo);
|
||||
SPECIALIZE_CREATE(Attribute);
|
||||
SPECIALIZE_CREATE(ContentInfo);
|
||||
SPECIALIZE_CREATE(AuthenticatedAttributes);
|
||||
SPECIALIZE_CREATE(CodeIntegrity);
|
||||
SPECIALIZE_CREATE(ContentType);
|
||||
SPECIALIZE_CREATE(GenericType);
|
||||
SPECIALIZE_CREATE(MsSpcNestedSignature);
|
||||
SPECIALIZE_CREATE(MsSpcStatementType);
|
||||
SPECIALIZE_CREATE(PKCS9AtSequenceNumber);
|
||||
SPECIALIZE_CREATE(PKCS9CounterSignature);
|
||||
SPECIALIZE_CREATE(PKCS9MessageDigest);
|
||||
SPECIALIZE_CREATE(PKCS9SigningTime);
|
||||
SPECIALIZE_CREATE(SpcSpOpusInfo);
|
||||
|
||||
SPECIALIZE_CREATE(CodeIntegrity);
|
||||
SPECIALIZE_CREATE(LoadConfiguration);
|
||||
SPECIALIZE_CREATE(LoadConfigurationV0);
|
||||
SPECIALIZE_CREATE(LoadConfigurationV1);
|
||||
|
@ -56,10 +56,13 @@ void init_LIEF_iterators(py::module& m) {
|
||||
init_ref_iterator<LIEF::PE::it_export_entries>(m);
|
||||
init_ref_iterator<LIEF::PE::it_pogo_entries>(m);
|
||||
init_ref_iterator<LIEF::PE::it_symbols>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_crt>(m);
|
||||
init_ref_iterator<LIEF::PE::it_childs>(m);
|
||||
init_ref_iterator<LIEF::PE::it_rich_entries>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_dialog_items>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_crt>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_signatures>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_signers_t>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_attributes_t>(m);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -33,6 +33,9 @@
|
||||
#define RST_ATTR_REF(X) ":attr:`~"#X"`"
|
||||
#define RST_ATTR_REF_FULL(X) ":attr:`"#X"`"
|
||||
|
||||
#define RST_METH_REF(X) ":class:`~"#X"`"
|
||||
#define RST_METH_REF_FULL(X) ":class:`"#X"`"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
using namespace pybind11::literals;
|
||||
|
@ -6,8 +6,8 @@ set(__add_lief_dependencies ON)
|
||||
# Json
|
||||
# ----
|
||||
if (LIEF_ENABLE_JSON)
|
||||
set(LIBJSON_VERSION 3.7.3)
|
||||
set(LIBJSON_SHA256 SHA256=e46d26550e8cafc7d7d2564fdf09d20bd14a72c417396bf7ca815b94894d1631)
|
||||
set(LIBJSON_VERSION 3.9.1)
|
||||
set(LIBJSON_SHA256 SHA256=5db3b7b3356a0742e06b27b6ee744f8ee487ed9c0f8cf3f9778a2076e7a933ba)
|
||||
set(LIBJSON_URL "${THIRD_PARTY_DIRECTORY}/json-${LIBJSON_VERSION}.zip" CACHE STRING "URL to the JSON lib repo")
|
||||
ExternalProject_Add(lief_libjson
|
||||
URL ${LIBJSON_URL}
|
||||
@ -29,8 +29,8 @@ endif()
|
||||
|
||||
# mbed TLS
|
||||
# --------
|
||||
set(MBED_TLS_VERSION 2.23.0)
|
||||
set(MBED_TLS_SHA256 SHA256=bbf9c3cc6b7603f2f15bbba7badcf6cf188a9d5aaa63c4df2d61213f459c2f5f)
|
||||
set(MBED_TLS_VERSION 2.7.17)
|
||||
set(MBED_TLS_SHA256 SHA256=a009059b0b4b882b884e8ef7013ff068b1254d8a2d98243e000c67b1737956b6)
|
||||
set(MBED_TLS_URL "${THIRD_PARTY_DIRECTORY}/mbedtls-${MBED_TLS_VERSION}.zip" CACHE STRING "URL to MbedTLS")
|
||||
set(MBED_TLS_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/mbed_tls")
|
||||
|
||||
@ -53,7 +53,6 @@ set(mbedtls_src_crypto
|
||||
"${MBEDTLS_SOURCE_DIR}/library/aes.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/aesni.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/arc4.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/aria.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/asn1parse.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/asn1write.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/base64.c"
|
||||
@ -61,13 +60,10 @@ set(mbedtls_src_crypto
|
||||
"${MBEDTLS_SOURCE_DIR}/library/blowfish.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/camellia.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ccm.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/chacha20.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/chachapoly.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/cipher.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/cipher_wrap.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/cmac.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ctr_drbg.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/debug.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/des.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/dhm.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ecdh.c"
|
||||
@ -80,15 +76,13 @@ set(mbedtls_src_crypto
|
||||
"${MBEDTLS_SOURCE_DIR}/library/error.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/gcm.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/havege.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/hkdf.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/hmac_drbg.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/md.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/md2.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/md4.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/md5.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/md_wrap.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/memory_buffer_alloc.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/net_sockets.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/nist_kw.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/oid.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/padlock.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/pem.c"
|
||||
@ -99,8 +93,6 @@ set(mbedtls_src_crypto
|
||||
"${MBEDTLS_SOURCE_DIR}/library/pkparse.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/pkwrite.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/platform.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/platform_util.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/poly1305.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ripemd160.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/rsa.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/rsa_internal.c"
|
||||
@ -112,19 +104,6 @@ set(mbedtls_src_crypto
|
||||
"${MBEDTLS_SOURCE_DIR}/library/version.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/version_features.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/xtea.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/aria.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/chacha20.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/chachapoly.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/hkdf.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/nist_kw.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/platform_util.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/poly1305.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/psa_crypto.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/psa_crypto_se.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/psa_crypto_slot_management.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/psa_crypto_storage.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/psa_its_file.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/rsa_internal.c"
|
||||
)
|
||||
|
||||
set(mbedtls_src_x509
|
||||
@ -149,7 +128,6 @@ set(mbedtls_src_tls
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ssl_srv.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ssl_ticket.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ssl_tls.c"
|
||||
"${MBEDTLS_SOURCE_DIR}/library/ssl_msg.c"
|
||||
)
|
||||
|
||||
#set_source_files_properties("${MBEDTLS_SOURCE_DIR}/library/bignum.c" PROPERTIES COMPILE_FLAGS -Wno-overlength-strings)
|
||||
@ -170,18 +148,18 @@ set(SPDLOG_SOURCE_DIR "${SOURCE_DIR}")
|
||||
|
||||
# Fuzzing
|
||||
# ~~~~~~~
|
||||
set(FUZZING_FLAGS -fno-omit-frame-pointer -g -O1)
|
||||
set(FUZZING_FLAGS -fno-omit-frame-pointer -g -O2)
|
||||
set(FUZZING_LINKER_FLAGS)
|
||||
|
||||
list(APPEND FUZZING_FLAGS -fsanitize=address -fsanitize-coverage=trace-pc-guard)
|
||||
list(APPEND FUZZING_LINKER_FLAGS -fsanitize=address -fsanitize-coverage=trace-pc-guard)
|
||||
list(APPEND FUZZING_FLAGS -fsanitize=address,fuzzer)
|
||||
list(APPEND FUZZING_LINKER_FLAGS -fsanitize=address,fuzzer)
|
||||
|
||||
set(LIBFUZZER_SRC_FILES)
|
||||
if (LIEF_FUZZING)
|
||||
message(STATUS "Fuzzing Enabled")
|
||||
|
||||
set(LIBFUZZER_VERSION 8ff5640b48c4c4a3b974daa10a5f445e86ed7428)
|
||||
set(LIBFUZZER_SHA256 SHA256=ed067ebc72b993571854edb113e9f3ef74367dfb8bab1a252009aff72e287614)
|
||||
set(LIBFUZZER_VERSION 6f13445)
|
||||
set(LIBFUZZER_SHA256 SHA256=cf9a4f5025beb9005181b9136a88e142f1360a3f8ccd490ec1b8f773cefc51e1)
|
||||
set(LIBFUZZER_URL "${THIRD_PARTY_DIRECTORY}/LibFuzzer-${LIBFUZZER_VERSION}.zip")
|
||||
ExternalProject_Add(lief_libfuzzer
|
||||
URL ${LIBFUZZER_URL}
|
||||
@ -195,36 +173,32 @@ if (LIEF_FUZZING)
|
||||
set(LIBFUZZER_SOURCE_DIR "${SOURCE_DIR}")
|
||||
|
||||
set(LIBFUZZER_SRC_FILES
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerSHA1.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilLinux.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerIO.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerMain.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerShmemWindows.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilWindows.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtil.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtFunctionsDlsym.cpp"
|
||||
#${LIBFUZZER_SOURCE_DIR}/afl/afl_driver.cpp
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerShmemPosix.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilDarwin.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerIOWindows.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtFunctionsDlsymWin.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerCrossOver.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerDataFlowTrace.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerDriver.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtFunctionsDlsym.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtFunctionsWeak.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilPosix.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtFunctionsWeakAlias.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerIOPosix.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerMerge.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerTracePC.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerMutate.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtFunctionsWindows.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerExtraCounters.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerFork.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerIO.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerIOPosix.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerIOWindows.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerLoop.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerClangCounters.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerMerge.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerMutate.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerSHA1.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerTracePC.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtil.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilDarwin.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilFuchsia.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilLinux.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilPosix.cpp"
|
||||
"${LIBFUZZER_SOURCE_DIR}/FuzzerUtilWindows.cpp"
|
||||
)
|
||||
list(APPEND LIBLIEF_SOURCE_FILES ${LIBFUZZER_SRC_FILES})
|
||||
|
||||
set_source_files_properties(${LIBFUZZER_SRC_FILES} PROPERTIES GENERATED TRUE)
|
||||
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/fuzzing")
|
||||
endif()
|
||||
|
||||
@ -251,3 +225,19 @@ if (LIEF_SUPPORT_CXX14 AND NOT LIEF_DISABLE_FROZEN)
|
||||
set(FROZEN_INCLUDE_DIR "${SOURCE_DIR}/include")
|
||||
endif()
|
||||
|
||||
|
||||
# Boost leaf
|
||||
# ----------
|
||||
set(LEAF_VERSION 0.3.0)
|
||||
set(LEAF_SHA256 SHA256=0a256cba80d9ec53adece74d231c28a79ddb7d96e8f79daeed72cad0c7855dfe )
|
||||
set(LEAF_URL "${THIRD_PARTY_DIRECTORY}/leaf-${LEAF_VERSION}.zip" CACHE STRING "URL to Leaf")
|
||||
ExternalProject_Add(lief_leaf # :)
|
||||
URL ${LEAF_URL}
|
||||
URL_HASH ${LEAF_SHA256}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
ExternalProject_get_property(lief_leaf SOURCE_DIR)
|
||||
set(LEAF_INCLUDE_DIR "${SOURCE_DIR}/include")
|
||||
|
@ -8,7 +8,7 @@ elseif(NOT SPHINX_FOUND)
|
||||
elseif(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
|
||||
message(STATUS "You have to build the doc in another directory !")
|
||||
else()
|
||||
|
||||
message(STATUS "Sphinx: ${SPHINX_EXECUTABLE}")
|
||||
add_custom_target(lief-doxygen
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env
|
||||
@ -23,7 +23,7 @@ else()
|
||||
|
||||
add_custom_target(lief-sphinx
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
"PYTHONPATH=${PROJECT_BINARY_DIR}/api/python:$ENV{PYTHONPATH}"
|
||||
"PYTHONPATH=${CMAKE_SOURCE_DIR}:${CMAKE_BINARY_DIR}/../:${CMAKE_BINARY_DIR}/api/python:$ENV{PYTHONPATH}"
|
||||
"LIEF_DOXYGEN_XML=${CMAKE_CURRENT_BINARY_DIR}/doxygen/xml/"
|
||||
${SPHINX_EXECUTABLE} -a -E -j4 -w ${CMAKE_BINARY_DIR}/sphinx-warn.log ${CMAKE_SOURCE_DIR}/doc/sphinx sphinx-doc
|
||||
DEPENDS pyLIEF lief-doxygen
|
||||
@ -37,7 +37,7 @@ else()
|
||||
|
||||
add_custom_target(lief-quick-sphinx
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
"PYTHONPATH=${PROJECT_BINARY_DIR}/api/python:$ENV{PYTHONPATH}"
|
||||
"PYTHONPATH=${CMAKE_SOURCE_DIR}:${CMAKE_BINARY_DIR}/../:${CMAKE_BINARY_DIR}/api/python:$ENV{PYTHONPATH}"
|
||||
"LIEF_DOXYGEN_XML=${CMAKE_CURRENT_BINARY_DIR}/doxygen/xml/"
|
||||
"FORCE_RTD_THEME=0"
|
||||
${SPHINX_EXECUTABLE} -j4 -w ${CMAKE_BINARY_DIR}/sphinx-warn.log ${CMAKE_SOURCE_DIR}/doc/sphinx sphinx-doc
|
||||
|
@ -153,15 +153,113 @@ Signature
|
||||
|
||||
----------
|
||||
|
||||
AuthenticatedAttributes
|
||||
***********************
|
||||
Signature Attribute
|
||||
*******************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::AuthenticatedAttributes
|
||||
.. doxygenclass:: LIEF::PE::Attribute
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
Signature ContentType
|
||||
*********************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::ContentType
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
Signature GenericType
|
||||
*********************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::GenericType
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
Signature MsSpcNestedSignature
|
||||
*******************************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::MsSpcNestedSignature
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature MsSpcStatementType
|
||||
****************************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::MsSpcStatementType
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature PKCS9AtSequenceNumber
|
||||
*******************************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::PKCS9AtSequenceNumber
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature PKCS9CounterSignature
|
||||
*******************************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::PKCS9CounterSignature
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature PKCS9MessageDigest
|
||||
****************************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::PKCS9MessageDigest
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature PKCS9SigningTime
|
||||
**************************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::PKCS9SigningTime
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature SpcSpOpusInfo
|
||||
***********************
|
||||
|
||||
.. doxygenclass:: LIEF::PE::SpcSpOpusInfo
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
RsaInfo
|
||||
*******
|
||||
|
||||
.. doxygenclass:: LIEF::PE::RsaInfo
|
||||
:project: lief
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
x509
|
||||
****
|
||||
|
||||
@ -171,6 +269,7 @@ x509
|
||||
|
||||
----------
|
||||
|
||||
|
||||
ContentInfo
|
||||
***********
|
||||
|
||||
@ -526,5 +625,8 @@ Enums
|
||||
.. doxygenenum:: LIEF::PE::GUARD_CF_FLAGS
|
||||
:project: lief
|
||||
|
||||
.. doxygenenum:: LIEF::PE::POGO_SIGNATURES
|
||||
.. doxygenenum:: LIEF::PE::ALGORITHMS
|
||||
:project: lief
|
||||
|
||||
.. doxygenenum:: LIEF::PE::SIG_ATTRIBUTE_TYPES
|
||||
:project: lief
|
||||
|
@ -162,10 +162,91 @@ Signature
|
||||
|
||||
----------
|
||||
|
||||
AuthenticatedAttributes
|
||||
***********************
|
||||
Signature Attribute
|
||||
*******************
|
||||
|
||||
.. autoclass:: lief.PE.AuthenticatedAttributes
|
||||
.. autoclass:: lief.PE.Attribute
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Signature ContentType
|
||||
*********************
|
||||
|
||||
.. autoclass:: lief.PE.ContentType
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature GenericType
|
||||
*********************
|
||||
|
||||
.. autoclass:: lief.PE.GenericType
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature MsSpcNestedSignature
|
||||
******************************
|
||||
|
||||
.. autoclass:: lief.PE.MsSpcNestedSignature
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature MsSpcStatementType
|
||||
****************************
|
||||
|
||||
.. autoclass:: lief.PE.MsSpcStatementType
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature PKCS9AtSequenceNumber
|
||||
*******************************
|
||||
|
||||
.. autoclass:: lief.PE.PKCS9AtSequenceNumber
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature PKCS9CounterSignature
|
||||
*******************************
|
||||
|
||||
.. autoclass:: lief.PE.PKCS9CounterSignature
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature PKCS9MessageDigest
|
||||
****************************
|
||||
|
||||
.. autoclass:: lief.PE.PKCS9MessageDigest
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Signature PKCS9SigningTime
|
||||
**************************
|
||||
|
||||
.. autoclass:: lief.PE.PKCS9SigningTime
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
@ -831,3 +912,21 @@ POGO_SIGNATURES
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
ALGORITHMS
|
||||
~~~~~~~~~~
|
||||
|
||||
.. autoclass:: lief.PE.ALGORITHMS
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
SIG_ATTRIBUTE_TYPES
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: lief.PE.SIG_ATTRIBUTE_TYPES
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
@ -20,6 +20,7 @@ Changelog
|
||||
* Bug fix in the symbols table reconstruction (ELF)
|
||||
|
||||
:PE:
|
||||
* Enhance PE Authenticode. See `PE Authenticode <tutorials/13_pe_authenticode.html>`_
|
||||
* :attr:`~lief.PE.LangCodeItem.items` now returns a dictionary whose values are **bytes** (instead of
|
||||
``str`` object). This change is related to ``utf-16`` support.
|
||||
* :github_user:`kohnakagawa` fixed wrong enums values: :commit:`c03125045e32a9cd65c613585eb4d0385350c6d2`, :commit:`6ee808a1e4611d09c6cf0aea82a612be69584db9`, :commit:`cd05f34bae681fc8af4b5e7cc28eaef816802b6f`
|
||||
@ -38,7 +39,7 @@ Changelog
|
||||
* Upgrade ``mbedtls`` to 2.16.6
|
||||
|
||||
:Documentation:
|
||||
* :github_user:`aguinet` updated the `bin2lib tutorial <https://lief.quarkslab.com/doc/latest/tutorials/08_elf_bin2lib.html>`_ with the support
|
||||
* :github_user:`aguinet` updated the `bin2lib tutorial <tutorials/08_elf_bin2lib.html>`_ with the support
|
||||
of the new glibc versions (:commit:`7884e57aa1d103f3bd37682e47f412bfe7a3aa34`)
|
||||
* Global update and enable to build the documentation out-of-tree
|
||||
* Changing the theme
|
||||
|
@ -25,7 +25,7 @@ Welcome to LIEF's documentation!
|
||||
tutorials/10_android_formats
|
||||
tutorials/11_macho_modification
|
||||
tutorials/12_elf_coredump
|
||||
|
||||
tutorials/13_pe_authenticode
|
||||
|
||||
.. toctree::
|
||||
:caption: API
|
||||
|
48
doc/sphinx/tutorials/13_pe_authenticode.rst
Normal file
48
doc/sphinx/tutorials/13_pe_authenticode.rst
Normal file
@ -0,0 +1,48 @@
|
||||
13 - PE Authenticode
|
||||
--------------------
|
||||
|
||||
This tutorial introduces the new API deal with PE Authenticode processing.
|
||||
|
||||
By Romain Thomas - `@rh0main <https://twitter.com/rh0main>`_
|
||||
|
||||
------
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. TODO
|
||||
|
||||
|
||||
|
||||
.. rubric:: References
|
||||
|
||||
|
||||
.. TODO
|
||||
|
||||
|
||||
.. rubric:: API
|
||||
|
||||
* :meth:`lief.PE.Binary.verify_signature`
|
||||
* :meth:`lief.PE.Binary.authentihash`
|
||||
* :attr:`lief.PE.Binary.authentihash_md5`
|
||||
* :attr:`lief.PE.Binary.authentihash_sha1`
|
||||
* :attr:`lief.PE.Binary.authentihash_sha256`
|
||||
* :attr:`lief.PE.Binary.authentihash_sha512`
|
||||
* :attr:`lief.PE.Binary.signatures`
|
||||
|
||||
* :class:`lief.PE.Signature`
|
||||
* :class:`lief.PE.x509`
|
||||
* :class:`lief.PE.ContentInfo`
|
||||
* :class:`lief.PE.SignerInfo`
|
||||
* :class:`lief.PE.Attribute`
|
||||
* :class:`lief.PE.ContentType`
|
||||
* :class:`lief.PE.GenericType`
|
||||
* :class:`lief.PE.MsCounterSign`
|
||||
* :class:`lief.PE.MsSpcNestedSignature`
|
||||
* :class:`lief.PE.MsSpcStatementType`
|
||||
* :class:`lief.PE.PKCS9AtSequenceNumber`
|
||||
* :class:`lief.PE.PKCS9CounterSignature`
|
||||
* :class:`lief.PE.PKCS9MessageDigest`
|
||||
* :class:`lief.PE.PKCS9SigningTime`
|
||||
* :class:`lief.PE.SpcSpOpusInfo`
|
||||
|
@ -100,13 +100,10 @@ int main(int argc, char **argv) {
|
||||
std::cout << binary->resources_manager() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
if (binary->has_signature()) {
|
||||
for (const Signature& sig : binary->signatures()) {
|
||||
std::cout << "== Signature ==" << std::endl;
|
||||
std::cout << binary->signature() << std::endl;
|
||||
std::cout << sig << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -298,45 +298,8 @@ def print_debug(binary):
|
||||
def print_signature(binary):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
signature = binary.signature
|
||||
print("== Signature ==")
|
||||
print(format_dec.format("Version:", signature.version))
|
||||
print(format_str.format("Digest Algorithm:", oid_to_string(signature.digest_algorithm)))
|
||||
print("")
|
||||
|
||||
print("-- Content Info --")
|
||||
content_info = signature.content_info
|
||||
print(format_str.format("Content Type:", oid_to_string(content_info.content_type)))
|
||||
print(format_str.format("Type:", oid_to_string(content_info.type)))
|
||||
print(format_str.format("Digest Algorithm:", oid_to_string(content_info.digest_algorithm)))
|
||||
print("")
|
||||
|
||||
print("-- Certificates --")
|
||||
certificates = signature.certificates
|
||||
|
||||
for crt in certificates:
|
||||
sn_str = ":".join(map(lambda e : "{:02x}".format(e), crt.serial_number))
|
||||
valid_from_str = "-".join(map(str, crt.valid_from[:3])) + " " + ":".join(map(str, crt.valid_from[3:]))
|
||||
valid_to_str = "-".join(map(str, crt.valid_to[:3])) + " " + ":".join(map(str, crt.valid_to[3:]))
|
||||
print(format_dec.format("Version:", crt.version))
|
||||
print(format_str.format("Serial Number:", sn_str))
|
||||
print(format_str.format("Signature Algorithm:", oid_to_string(crt.signature_algorithm)))
|
||||
print(format_str.format("Valid from:", valid_from_str))
|
||||
print(format_str.format("Valid to:", valid_to_str))
|
||||
print(format_str.format("Issuer:", crt.issuer))
|
||||
print(format_str.format("Subject:", crt.subject))
|
||||
print("")
|
||||
|
||||
print("-- Signer Info --")
|
||||
signer_info = signature.signer_info
|
||||
print(format_dec.format("Version:", signer_info.version))
|
||||
print(format_str.format("Issuer:", signer_info.issuer[0]))
|
||||
print(format_str.format("Digest Algorithm:", oid_to_string(signer_info.digest_algorithm)))
|
||||
print(format_str.format("Signature algorithm:", oid_to_string(signer_info.signature_algorithm)))
|
||||
print(format_str.format("Program name:", signer_info.authenticated_attributes.program_name))
|
||||
print(format_str.format("Url:", signer_info.authenticated_attributes.more_info))
|
||||
print("")
|
||||
for signature in binary.signatures:
|
||||
print(signature)
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_rich_header(binary):
|
||||
@ -616,7 +579,7 @@ def main():
|
||||
if (args.show_debug or args.show_all) and binary.has_debug:
|
||||
print_debug(binary)
|
||||
|
||||
if (args.show_signature or args.show_all) and binary.has_signature:
|
||||
if (args.show_signature or args.show_all) and binary.has_signatures:
|
||||
print_signature(binary)
|
||||
|
||||
if (args.show_richheader or args.show_all) and binary.has_rich_header:
|
||||
|
54
examples/python/pe_sign/authenticode.py
Normal file
54
examples/python/pe_sign/authenticode.py
Normal file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
import lief
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Parse PE file
|
||||
pe = lief.parse(sys.argv[1])
|
||||
|
||||
# Get authenticode
|
||||
print(pe.authentihash_md5.hex(":")) # 1c:a0:91:53:dc:9a:3a:5f:34:1d:7f:9b:b9:56:69:4d
|
||||
print(pe.authentihash(lief.PE.ALGORITHMS.SHA_1).hex(":")) # 1e:ad:dc:29:1e:db:41:a2:69:c2:ba:ae:4b:fb:9d:31:e7:bb:ab:59
|
||||
|
||||
# Check signature according to PKCS #7 and Microsoft documentation
|
||||
print(pe.verify_signature()) # Return VERIFICATION_FLAGS.OK
|
||||
|
||||
bin_ca = None
|
||||
# Look for the root CA in the PE file
|
||||
for crt in pe.signatures[0].certificates:
|
||||
if crt.issuer == "C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA":
|
||||
bin_ca = crt
|
||||
|
||||
# Verify CA chain
|
||||
bundle_path = os.getenv("LIEF_CA_BUNDLE", None) # Path to CA bundle (one can use those from signify:
|
||||
# signify/certs/authenticode-bundle.pem)
|
||||
if bundle_path is not None:
|
||||
# Parse cert bundle and return a list of lief.PE.x509 objects
|
||||
bundle = lief.PE.x509.parse(bundle_path)
|
||||
print(bin_ca.is_trusted_by(bundle)) # VERIFICATION_FLAGS.OK
|
||||
|
||||
|
||||
# Get the certificate used by the signer
|
||||
cert_signer = pe.signatures[0].signers[0].cert
|
||||
print(cert_signer)
|
||||
bin_ca.verify(cert_signer) # Verify that cert_signer is signed the the CA
|
||||
|
||||
# running with:
|
||||
# LIEF_CA_BUNDLE=signify/signify/certs/authenticode-bundle.pem python ./authenticode.py avast_free_antivirus_setup_online.exe
|
||||
#
|
||||
# 1c:a0:91:53:dc:9a:3a:5f:34:1d:7f:9b:b9:56:69:4d
|
||||
# 1e:ad:dc:29:1e:db:41:a2:69:c2:ba:ae:4b:fb:9d:31:e7:bb:ab:59
|
||||
# VERIFICATION_FLAGS.OK
|
||||
# cert. version : 3
|
||||
# serial number : 04:09:18:1B:5F:D5:BB:66:75:53:43:B5:6F:95:50:08
|
||||
# issuer name : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
|
||||
# subject name : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Assured ID Code Signing CA
|
||||
# issued on : 2013-10-22 12:00:00
|
||||
# expires on : 2028-10-22 12:00:00
|
||||
# signed using : RSA with SHA-256
|
||||
# RSA key size : 2048 bits
|
||||
# basic constraints : CA=true, max_pathlen=0
|
||||
# key usage : Digital Signature, Key Cert Sign, CRL Sign
|
||||
# ext key usage : Code Signing
|
||||
#
|
||||
# VERIFICATION_FLAGS.OK
|
62
examples/python/pe_sign/sig_info.py
Normal file
62
examples/python/pe_sign/sig_info.py
Normal file
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
import lief
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from prettyprinter import pprint
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("pe_file")
|
||||
|
||||
# Logging setup
|
||||
logger_group = parser.add_argument_group('Logger')
|
||||
verbosity = logger_group.add_mutually_exclusive_group()
|
||||
|
||||
verbosity.add_argument('--debug',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LOGGING_LEVEL.DEBUG)
|
||||
|
||||
verbosity.add_argument('--trace',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LOGGING_LEVEL.TRACE)
|
||||
|
||||
verbosity.add_argument('--info',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LOGGING_LEVEL.INFO)
|
||||
|
||||
verbosity.add_argument('--warn',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LOGGING_LEVEL.WARNING)
|
||||
|
||||
verbosity.add_argument('--err',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LOGGING_LEVEL.ERROR)
|
||||
|
||||
verbosity.add_argument('--critical',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LOGGING_LEVEL.CRITICAL)
|
||||
|
||||
parser.set_defaults(main_verbosity=lief.logging.LOGGING_LEVEL.WARNING)
|
||||
|
||||
args = parser.parse_args()
|
||||
lief.logging.set_level(args.main_verbosity)
|
||||
|
||||
binary = None
|
||||
try:
|
||||
binary = lief.PE.parse(args.pe_file)
|
||||
except lief.exception as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
for sig in binary.signatures:
|
||||
print(sig)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -4,6 +4,7 @@ set(LIEF_FUZZER_SRC
|
||||
pe_fuzzer.cpp
|
||||
macho_fuzzer.cpp
|
||||
pme_fuzzer.cpp
|
||||
pkcs7_signature.cpp
|
||||
)
|
||||
|
||||
foreach(fuzzer ${LIEF_FUZZER_SRC})
|
||||
@ -35,7 +36,8 @@ ExternalProject_Add(lief_fuzzer_corpus
|
||||
INSTALL_COMMAND ""
|
||||
GIT_REPOSITORY ${SAMPLES_GIT_URL}
|
||||
GIT_TAG ${SAMPLES_TAG}
|
||||
#UPDATE_COMMAND ${GIT_EXECUTABLE} pull
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
UPDATE_COMMAND ""
|
||||
LOG_DOWNLOAD 1
|
||||
)
|
||||
@ -119,4 +121,18 @@ add_custom_target("fuzz-macho"
|
||||
COMMENT "Run MachO fuzzer")
|
||||
|
||||
|
||||
# PKCS7-Signature parsing
|
||||
# =======================
|
||||
set(PKCS7_WORKING_DIR ${CMAKE_CURRENT_BINARY_DIR}/pkcs7-output)
|
||||
set(PKCS7_NEW_CASES ${PKCS7_WORKING_DIR}/new_cases)
|
||||
|
||||
add_custom_target(build-pkcs7-fuzz-output
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PKCS7_WORKING_DIR} ${PKCS7_NEW_CASES})
|
||||
|
||||
add_custom_target("fuzz-pkcs7"
|
||||
COMMAND ${CMAKE_COMMAND} -E env ASAN_OPTIONS="${ASAN_OPTIONS}" ${CMAKE_CURRENT_BINARY_DIR}/pkcs7_signature ${LIB_FUZZER_ARGS} ${LIEF_CORUPUS_DIRECTORY}/pkcs7 ${PKCS7_NEW_CASES}
|
||||
DEPENDS pkcs7_signature LIB_LIEF build-pkcs7-fuzz-output lief_fuzzer_corpus
|
||||
WORKING_DIRECTORY ${PKCS7_WORKING_DIR}
|
||||
COMMENT "Run PKCS7 fuzzer")
|
||||
|
||||
|
||||
|
12
fuzzing/pkcs7_signature.cpp
Normal file
12
fuzzing/pkcs7_signature.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "LIEF/PE/signature/SignatureParser.hpp"
|
||||
#include "LIEF/logging.hpp"
|
||||
|
||||
__attribute__((constructor)) void foo(){
|
||||
LIEF::logging::disable();
|
||||
}
|
||||
|
||||
LIEF_API extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
LIEF::PE::SignatureParser::parse({data, data + size});
|
||||
return 0; // Non-zero return values are reserved for future use.
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ class Symbol;
|
||||
class Section;
|
||||
class Relocation;
|
||||
|
||||
using sections_t = std::vector<Section*>;
|
||||
using it_sections = ref_iterator<sections_t>;
|
||||
using it_const_sections = const_ref_iterator<sections_t>;
|
||||
using sections_t = std::vector<Section*>; ///< Default container for abstract sections
|
||||
using it_sections = ref_iterator<sections_t>; ///< Iterator over abstract sections
|
||||
using it_const_sections = const_ref_iterator<sections_t>; ///< **Const** iterator over abstract sections
|
||||
|
||||
using symbols_t = std::vector<Symbol*>;
|
||||
using it_symbols = ref_iterator<symbols_t>;
|
||||
using it_const_symbols = const_ref_iterator<symbols_t>;
|
||||
using symbols_t = std::vector<Symbol*>; ///< Default container for abstract symbols
|
||||
using it_symbols = ref_iterator<symbols_t>; ///< Iterator over abstract symbols
|
||||
using it_const_symbols = const_ref_iterator<symbols_t>; ///< Iterator over abstract symbols
|
||||
|
||||
using relocations_t = std::vector<Relocation*>; ///< Container used to transfert abstract relocations from binary formats
|
||||
using it_relocations = ref_iterator<relocations_t>; ///< Iterator over Abstract LIEF::Relocation (read only)
|
||||
|
@ -24,6 +24,11 @@
|
||||
#include <memory>
|
||||
|
||||
#include "LIEF/BinaryStream/Convert.hpp"
|
||||
#include "LIEF/errors.hpp"
|
||||
|
||||
struct mbedtls_x509_crt;
|
||||
struct mbedtls_x509_time;
|
||||
|
||||
namespace LIEF {
|
||||
class BinaryStream {
|
||||
public:
|
||||
@ -100,6 +105,19 @@ class BinaryStream {
|
||||
|
||||
void set_endian_swap(bool swap);
|
||||
|
||||
// ASN1 related functions
|
||||
virtual result<size_t> asn1_read_tag(int tag) = 0;
|
||||
virtual result<size_t> asn1_read_len() = 0;
|
||||
virtual result<std::string> asn1_read_alg() = 0;
|
||||
virtual result<std::string> asn1_read_oid() = 0;
|
||||
virtual result<int32_t> asn1_read_int() = 0;
|
||||
virtual result<std::vector<uint8_t>> asn1_read_bitstring() = 0;
|
||||
virtual result<std::vector<uint8_t>> asn1_read_octet_string() = 0;
|
||||
virtual result<std::unique_ptr<mbedtls_x509_crt>> asn1_read_cert() = 0;
|
||||
virtual result<std::string> x509_read_names() = 0;
|
||||
virtual result<std::vector<uint8_t>> x509_read_serial() = 0;
|
||||
virtual result<std::unique_ptr<mbedtls_x509_time>> x509_read_time() = 0;
|
||||
|
||||
protected:
|
||||
virtual const void* read_at(uint64_t offset, uint64_t size, bool throw_error = true) const = 0;
|
||||
mutable size_t pos_{0};
|
||||
|
@ -31,6 +31,36 @@ class VectorStream : public BinaryStream {
|
||||
|
||||
const std::vector<uint8_t>& content(void) const;
|
||||
|
||||
inline uint8_t* p() {
|
||||
return this->binary_.data() + this->pos();
|
||||
}
|
||||
|
||||
inline const uint8_t* p() const {
|
||||
return this->binary_.data() + this->pos();
|
||||
}
|
||||
|
||||
|
||||
inline uint8_t* end() {
|
||||
return this->binary_.data() + this->binary_.size();
|
||||
}
|
||||
|
||||
inline const uint8_t* end() const {
|
||||
return this->binary_.data() + this->binary_.size();
|
||||
}
|
||||
|
||||
virtual result<size_t> asn1_read_tag(int tag) override;
|
||||
virtual result<size_t> asn1_read_len() override;
|
||||
result<size_t> asn1_peek_len();
|
||||
virtual result<std::string> asn1_read_alg() override;
|
||||
virtual result<std::string> asn1_read_oid() override;
|
||||
virtual result<int32_t> asn1_read_int() override;
|
||||
virtual result<std::vector<uint8_t>> asn1_read_bitstring() override;
|
||||
virtual result<std::vector<uint8_t>> asn1_read_octet_string() override;
|
||||
virtual result<std::unique_ptr<mbedtls_x509_crt>> asn1_read_cert() override;
|
||||
virtual result<std::string> x509_read_names() override;
|
||||
virtual result<std::vector<uint8_t>> x509_read_serial() override;
|
||||
virtual result<std::unique_ptr<mbedtls_x509_time>> x509_read_time() override;
|
||||
|
||||
protected:
|
||||
virtual const void* read_at(uint64_t offset, uint64_t size, bool throw_error = true) const override;
|
||||
std::vector<uint8_t> binary_;
|
||||
|
@ -31,7 +31,7 @@ class Parser;
|
||||
class Builder;
|
||||
class Binary;
|
||||
|
||||
//! Class representing the ".note.android.ident" section
|
||||
//! Class representing the ``.note.android.ident`` section
|
||||
//!
|
||||
//! @see: https://android.googlesource.com/platform/ndk/+/ndk-release-r16/sources/crt/crtbrand.S#39
|
||||
class LIEF_API NoteAbi : public NoteDetails {
|
||||
|
@ -62,7 +62,8 @@
|
||||
#include "LIEF/PE/AuxiliarySymbol.hpp"
|
||||
#include "LIEF/PE/CodeIntegrity.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/AuthenticatedAttributes.hpp"
|
||||
#include "LIEF/PE/signature/attributes.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/ContentInfo.hpp"
|
||||
#include "LIEF/PE/signature/OIDToString.hpp"
|
||||
#include "LIEF/PE/signature/Signature.hpp"
|
||||
|
@ -111,8 +111,8 @@ class LIEF_API Binary : public LIEF::Binary {
|
||||
//! @see Import
|
||||
bool has_imports(void) const;
|
||||
|
||||
//! Check if the current binary is signed
|
||||
bool has_signature(void) const;
|
||||
//! Check if the current binary conatains signatures
|
||||
bool has_signatures(void) const;
|
||||
|
||||
//! Check if the current binary has exports.
|
||||
//!
|
||||
@ -138,11 +138,31 @@ class LIEF_API Binary : public LIEF::Binary {
|
||||
|
||||
//! Check if the current binary has been built has reproducible, replacing timestamps by a compile hash.
|
||||
//!
|
||||
//! @see Debug
|
||||
//! @see Debug
|
||||
bool is_reproducible_build(void) const;
|
||||
|
||||
//! Return the Signature object if the bianry is signed
|
||||
const Signature& signature(void) const;
|
||||
//! Return the Signature object(s) if the bianry is signed
|
||||
it_const_signatures signatures(void) const;
|
||||
|
||||
//! Verify the binary against the embedded signature(s) (if any)
|
||||
//! Firstly, it checks that the embedded signatures are correct (c.f. Signature::check)
|
||||
//! and then it checks that the authentihash matches ContentInfo::digest
|
||||
Signature::VERIFICATION_FLAGS verify_signature() const;
|
||||
|
||||
//! Verify the binary with the Signature object provided in the first parameter
|
||||
//! It can be used to verify a detached signature:
|
||||
//!
|
||||
//! \code{.cpp}
|
||||
//! result<Signature> detached = LIEF::PE::SignatureParser::parse("sig.pkcs7")
|
||||
//! if (detached) {
|
||||
//! binary->verify_signature(detached.value());
|
||||
//! }
|
||||
//! \endcode
|
||||
Signature::VERIFICATION_FLAGS verify_signature(const Signature& sig) const;
|
||||
|
||||
//! Compute the authentihash according to the algorithm provided in the first
|
||||
//! parameter
|
||||
std::vector<uint8_t> authentihash(ALGORITHMS algo) const;
|
||||
|
||||
//! Try to predict the RVA of the function `function` in the import library `library`
|
||||
//!
|
||||
@ -411,27 +431,26 @@ class LIEF_API Binary : public LIEF::Binary {
|
||||
void update_lookup_address_table_offset(void);
|
||||
void update_iat(void);
|
||||
|
||||
PE_TYPE type_;
|
||||
DosHeader dos_header_;
|
||||
RichHeader rich_header_;
|
||||
Header header_;
|
||||
OptionalHeader optional_header_;
|
||||
PE_TYPE type_;
|
||||
DosHeader dos_header_;
|
||||
RichHeader rich_header_;
|
||||
Header header_;
|
||||
OptionalHeader optional_header_;
|
||||
|
||||
int32_t available_sections_space_;
|
||||
int32_t available_sections_space_;
|
||||
|
||||
bool has_rich_header_;
|
||||
bool has_tls_;
|
||||
bool has_imports_;
|
||||
bool has_signature_;
|
||||
bool has_exports_;
|
||||
bool has_resources_;
|
||||
bool has_exceptions_;
|
||||
bool has_relocations_;
|
||||
bool has_debug_;
|
||||
bool has_configuration_;
|
||||
bool is_reproducible_build_;
|
||||
bool has_rich_header_;
|
||||
bool has_tls_;
|
||||
bool has_imports_;
|
||||
bool has_exports_;
|
||||
bool has_resources_;
|
||||
bool has_exceptions_;
|
||||
bool has_relocations_;
|
||||
bool has_debug_;
|
||||
bool has_configuration_;
|
||||
bool is_reproducible_build_;
|
||||
|
||||
Signature signature_;
|
||||
signatures_t signatures_;
|
||||
TLS tls_;
|
||||
sections_t sections_;
|
||||
data_directories_t data_directories_;
|
||||
@ -442,8 +461,10 @@ class LIEF_API Binary : public LIEF::Binary {
|
||||
imports_t imports_;
|
||||
Export export_;
|
||||
debug_entries_t debug_;
|
||||
uint64_t overlay_offset_ = 0;
|
||||
std::vector<uint8_t> overlay_;
|
||||
std::vector<uint8_t> dos_stub_;
|
||||
std::vector<uint8_t> section_offset_padding_;
|
||||
|
||||
LoadConfiguration* load_configuration_{nullptr};
|
||||
|
||||
|
@ -67,6 +67,9 @@ LIEF_API const char* to_string(GUARD_CF_FLAGS e);
|
||||
LIEF_API const char* to_string(ACCELERATOR_FLAGS e);
|
||||
LIEF_API const char* to_string(ACCELERATOR_VK_CODES e);
|
||||
|
||||
LIEF_API const char* to_string(ALGORITHMS e);
|
||||
LIEF_API const char* to_string(SIG_ATTRIBUTE_TYPES e);
|
||||
|
||||
} // namespace PE
|
||||
} // namespace LIEF
|
||||
#endif
|
||||
|
@ -58,6 +58,9 @@ class LIEF_API Section : public LIEF::Section {
|
||||
// LIEF::Section implementation
|
||||
// ============================
|
||||
virtual std::vector<uint8_t> content(void) const override;
|
||||
inline const std::vector<uint8_t>& padding() const {
|
||||
return this->padding_;
|
||||
}
|
||||
|
||||
|
||||
uint32_t pointerto_raw_data(void) const;
|
||||
@ -100,14 +103,15 @@ class LIEF_API Section : public LIEF::Section {
|
||||
private:
|
||||
std::vector<uint8_t>& content_ref(void);
|
||||
|
||||
uint32_t virtualSize_;
|
||||
std::vector<uint8_t> content_;
|
||||
uint32_t pointerToRelocations_;
|
||||
uint32_t pointerToLineNumbers_;
|
||||
uint16_t numberOfRelocations_;
|
||||
uint16_t numberOfLineNumbers_;
|
||||
uint32_t characteristics_;
|
||||
std::set<PE_SECTION_TYPES> types_;
|
||||
std::vector<uint8_t> content_;
|
||||
std::vector<uint8_t> padding_;
|
||||
uint32_t virtual_size_ = 0;
|
||||
uint32_t pointer_to_relocations_ = 0;
|
||||
uint32_t pointer_to_linenumbers_ = 0;
|
||||
uint16_t number_of_relocations_ = 0;
|
||||
uint16_t number_of_linenumbers_ = 0;
|
||||
uint32_t characteristics_ = 0;
|
||||
std::set<PE_SECTION_TYPES> types_ = {PE_SECTION_TYPES::UNKNOWN};
|
||||
};
|
||||
|
||||
} // namespace PE
|
||||
|
@ -11,7 +11,7 @@ namespace PE {
|
||||
@LIEF_PE_ENUMS@
|
||||
|
||||
|
||||
// Common section type
|
||||
//! Common section type
|
||||
enum class PE_SECTION_TYPES : uint8_t {
|
||||
TEXT = 0,
|
||||
TLS = 1,
|
||||
@ -31,6 +31,51 @@ enum class PE_TYPE : uint16_t {
|
||||
PE32_PLUS = 0x20b ///< 64 bits
|
||||
};
|
||||
|
||||
//! Cryptography algorithms
|
||||
enum class ALGORITHMS {
|
||||
UNKNOWN = 0,
|
||||
SHA_512,
|
||||
SHA_384,
|
||||
SHA_256,
|
||||
SHA_1,
|
||||
|
||||
MD5,
|
||||
MD4,
|
||||
MD2,
|
||||
|
||||
RSA,
|
||||
EC,
|
||||
|
||||
MD5_RSA,
|
||||
SHA1_DSA,
|
||||
SHA1_RSA,
|
||||
SHA_256_RSA,
|
||||
SHA_384_RSA,
|
||||
SHA_512_RSA,
|
||||
SHA1_ECDSA,
|
||||
SHA_256_ECDSA,
|
||||
SHA_384_ECDSA,
|
||||
SHA_512_ECDSA,
|
||||
};
|
||||
|
||||
//! Typed enum for LIEF::PE::Attribute
|
||||
enum class SIG_ATTRIBUTE_TYPES {
|
||||
UNKNOWN = 0,
|
||||
CONTENT_TYPE,
|
||||
GENERIC_TYPE,
|
||||
|
||||
SPC_SP_OPUS_INFO,
|
||||
|
||||
MS_COUNTER_SIGN,
|
||||
MS_SPC_NESTED_SIGN,
|
||||
MS_SPC_STATEMENT_TYPE,
|
||||
|
||||
PKCS9_AT_SEQUENCE_NUMBER,
|
||||
PKCS9_COUNTER_SIGNATURE,
|
||||
PKCS9_MESSAGE_DIGEST,
|
||||
PKCS9_SIGNING_TIME,
|
||||
};
|
||||
|
||||
|
||||
static const RESOURCE_TYPES resource_types_array[] = {
|
||||
RESOURCE_TYPES::CURSOR,
|
||||
|
@ -60,7 +60,18 @@ class ResourceAccelerator;
|
||||
class Signature;
|
||||
class x509;
|
||||
class SignerInfo;
|
||||
class AuthenticatedAttributes;
|
||||
class ContentInfo;
|
||||
class Attribute;
|
||||
class ContentType;
|
||||
class GenericType;
|
||||
//class MsCounterSign;
|
||||
class MsSpcNestedSignature;
|
||||
class MsSpcStatementType;
|
||||
class PKCS9AtSequenceNumber;
|
||||
class PKCS9CounterSignature;
|
||||
class PKCS9MessageDigest;
|
||||
class PKCS9SigningTime;
|
||||
class SpcSpOpusInfo;
|
||||
class CodeIntegrity;
|
||||
class LoadConfiguration;
|
||||
class LoadConfigurationV0;
|
||||
@ -120,19 +131,28 @@ class LIEF_API Hash : public LIEF::Hash {
|
||||
virtual void visit(const Signature& signature) override;
|
||||
virtual void visit(const x509& x509) override;
|
||||
virtual void visit(const SignerInfo& signerinfo) override;
|
||||
//virtual void visit(const ContentInfo& contentinfo) override;
|
||||
virtual void visit(const AuthenticatedAttributes& auth) override;
|
||||
virtual void visit(const ContentInfo& contentinfo) override;
|
||||
virtual void visit(const Attribute& attr) override;
|
||||
virtual void visit(const ContentType& attr) override;
|
||||
virtual void visit(const GenericType& attr) override;
|
||||
//virtual void visit(const MsCounterSign& attr) override;
|
||||
virtual void visit(const MsSpcNestedSignature& attr) override;
|
||||
virtual void visit(const MsSpcStatementType& attr) override;
|
||||
virtual void visit(const PKCS9AtSequenceNumber& attr) override;
|
||||
virtual void visit(const PKCS9CounterSignature& attr) override;
|
||||
virtual void visit(const PKCS9MessageDigest& attr) override;
|
||||
virtual void visit(const PKCS9SigningTime& attr) override;
|
||||
virtual void visit(const SpcSpOpusInfo& attr) override;
|
||||
virtual void visit(const CodeIntegrity& code_integrity) override;
|
||||
|
||||
virtual void visit(const LoadConfiguration& config) override;
|
||||
virtual void visit(const LoadConfigurationV0& config) override;
|
||||
virtual void visit(const LoadConfigurationV1& config) override;
|
||||
virtual void visit(const LoadConfigurationV2& config) override;
|
||||
virtual void visit(const LoadConfigurationV3& config) override;
|
||||
virtual void visit(const LoadConfigurationV4& config) override;
|
||||
virtual void visit(const LoadConfigurationV5& config) override;
|
||||
virtual void visit(const LoadConfigurationV6& config) override;
|
||||
virtual void visit(const LoadConfigurationV7& config) override;
|
||||
virtual void visit(const LoadConfiguration& config) override;
|
||||
virtual void visit(const LoadConfigurationV0& config) override;
|
||||
virtual void visit(const LoadConfigurationV1& config) override;
|
||||
virtual void visit(const LoadConfigurationV2& config) override;
|
||||
virtual void visit(const LoadConfigurationV3& config) override;
|
||||
virtual void visit(const LoadConfigurationV4& config) override;
|
||||
virtual void visit(const LoadConfigurationV5& config) override;
|
||||
virtual void visit(const LoadConfigurationV6& config) override;
|
||||
virtual void visit(const LoadConfigurationV7& config) override;
|
||||
|
||||
virtual void visit(const Pogo& pogo) override;
|
||||
virtual void visit(const PogoEntry& entry) override;
|
||||
|
@ -65,7 +65,17 @@ class Signature;
|
||||
class x509;
|
||||
class SignerInfo;
|
||||
class ContentInfo;
|
||||
class AuthenticatedAttributes;
|
||||
class Attribute;
|
||||
class ContentType;
|
||||
class GenericType;
|
||||
//class MsCounterSign;
|
||||
class MsSpcNestedSignature;
|
||||
class MsSpcStatementType;
|
||||
class PKCS9AtSequenceNumber;
|
||||
class PKCS9CounterSignature;
|
||||
class PKCS9MessageDigest;
|
||||
class PKCS9SigningTime;
|
||||
class SpcSpOpusInfo;
|
||||
class CodeIntegrity;
|
||||
class LoadConfiguration;
|
||||
class LoadConfigurationV0;
|
||||
@ -124,18 +134,27 @@ class LIEF_API JsonVisitor : public LIEF::JsonVisitor {
|
||||
virtual void visit(const x509& x509) override;
|
||||
virtual void visit(const SignerInfo& signerinfo) override;
|
||||
virtual void visit(const ContentInfo& contentinfo) override;
|
||||
virtual void visit(const AuthenticatedAttributes& auth) override;
|
||||
virtual void visit(const Attribute& attr) override;
|
||||
virtual void visit(const ContentType& attr) override;
|
||||
virtual void visit(const GenericType& attr) override;
|
||||
//virtual void visit(const MsCounterSign& attr) override;
|
||||
virtual void visit(const MsSpcNestedSignature& attr) override;
|
||||
virtual void visit(const MsSpcStatementType& attr) override;
|
||||
virtual void visit(const PKCS9AtSequenceNumber& attr) override;
|
||||
virtual void visit(const PKCS9CounterSignature& attr) override;
|
||||
virtual void visit(const PKCS9MessageDigest& attr) override;
|
||||
virtual void visit(const PKCS9SigningTime& attr) override;
|
||||
virtual void visit(const SpcSpOpusInfo& attr) override;
|
||||
virtual void visit(const CodeIntegrity& code_integrity) override;
|
||||
|
||||
virtual void visit(const LoadConfiguration& config) override;
|
||||
virtual void visit(const LoadConfigurationV0& config) override;
|
||||
virtual void visit(const LoadConfigurationV1& config) override;
|
||||
virtual void visit(const LoadConfigurationV2& config) override;
|
||||
virtual void visit(const LoadConfigurationV3& config) override;
|
||||
virtual void visit(const LoadConfigurationV4& config) override;
|
||||
virtual void visit(const LoadConfigurationV5& config) override;
|
||||
virtual void visit(const LoadConfigurationV6& config) override;
|
||||
virtual void visit(const LoadConfigurationV7& config) override;
|
||||
virtual void visit(const LoadConfiguration& config) override;
|
||||
virtual void visit(const LoadConfigurationV0& config) override;
|
||||
virtual void visit(const LoadConfigurationV1& config) override;
|
||||
virtual void visit(const LoadConfigurationV2& config) override;
|
||||
virtual void visit(const LoadConfigurationV3& config) override;
|
||||
virtual void visit(const LoadConfigurationV4& config) override;
|
||||
virtual void visit(const LoadConfigurationV5& config) override;
|
||||
virtual void visit(const LoadConfigurationV6& config) override;
|
||||
virtual void visit(const LoadConfigurationV7& config) override;
|
||||
|
||||
virtual void visit(const Pogo& pogo) override;
|
||||
virtual void visit(const PogoEntry& entry) override;
|
||||
|
65
include/LIEF/PE/signature/Attribute.hpp
Normal file
65
include/LIEF/PE/signature/Attribute.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_H_
|
||||
#define LIEF_PE_ATTRIBUTES_H_
|
||||
#include <memory>
|
||||
#include "LIEF/Object.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/enums.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over PKCS #7 attribute
|
||||
class LIEF_API Attribute : public Object {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
Attribute(void);
|
||||
Attribute(const Attribute&);
|
||||
Attribute& operator=(const Attribute&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const = 0;
|
||||
|
||||
//! Concrete type of the attribute
|
||||
inline virtual SIG_ATTRIBUTE_TYPES type() const {
|
||||
return this->type_;
|
||||
}
|
||||
|
||||
//! Print information about the underlying attribute
|
||||
virtual std::string print() const = 0;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~Attribute();
|
||||
|
||||
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Attribute& Attribute);
|
||||
|
||||
protected:
|
||||
Attribute(SIG_ATTRIBUTE_TYPES type);
|
||||
SIG_ATTRIBUTE_TYPES type_ = SIG_ATTRIBUTE_TYPES::UNKNOWN;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,75 +0,0 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_AUTHENTICATED_ATTRIBUTES_H_
|
||||
#define LIEF_PE_AUTHENTICATED_ATTRIBUTES_H_
|
||||
|
||||
#include "LIEF/Object.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/signature/types.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
class LIEF_API AuthenticatedAttributes : public Object {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
AuthenticatedAttributes(void);
|
||||
AuthenticatedAttributes(const AuthenticatedAttributes&);
|
||||
AuthenticatedAttributes& operator=(const AuthenticatedAttributes&);
|
||||
|
||||
//! @brief Should return the ``messageDigest`` OID
|
||||
const oid_t& content_type(void) const;
|
||||
|
||||
//! @brief Return an hash of the signed attributes
|
||||
const std::vector<uint8_t>& message_digest(void) const;
|
||||
|
||||
//! @brief Return the program description (if any)
|
||||
const std::u16string& program_name(void) const;
|
||||
|
||||
//! @brief Return an URL to website with more information about the signer
|
||||
const std::string& more_info(void) const;
|
||||
|
||||
//! @brief Return the raw bytes associated with the AuthenticatedAttributes
|
||||
const std::vector<uint8_t>& raw(void) const;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~AuthenticatedAttributes(void);
|
||||
|
||||
LIEF_API friend std::ostream& operator<<(std::ostream& os, const AuthenticatedAttributes& authenticated_attributes);
|
||||
|
||||
private:
|
||||
oid_t content_type_; // should holds 1.2.840.113549.1.9.4
|
||||
|
||||
std::vector<uint8_t> message_digest_;
|
||||
|
||||
std::u16string program_name_;
|
||||
std::string more_info_;
|
||||
std::vector<uint8_t> raw_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/signature/types.hpp"
|
||||
#include "LIEF/PE/enums.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
@ -27,6 +28,44 @@ namespace PE {
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
/** ContentInfo as described in the RFC2315 (https://tools.ietf.org/html/rfc2315#section-7)
|
||||
*
|
||||
* ```raw
|
||||
* ContentInfo ::= SEQUENCE {
|
||||
* contentType ContentType,
|
||||
* content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
|
||||
* }
|
||||
*
|
||||
* ContentType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* In the case of PE signature, ContentType **must** be set to SPC_INDIRECT_DATA_OBJID
|
||||
* OID: ``1.3.6.1.4.1.311.2.1.4`` and content is defined by the structure: ``SpcIndirectDataContent``
|
||||
*
|
||||
* SpcIndirectDataContent ::= SEQUENCE {
|
||||
* data SpcAttributeTypeAndOptionalValue,
|
||||
* messageDigest DigestInfo
|
||||
* }
|
||||
*
|
||||
* SpcAttributeTypeAndOptionalValue ::= SEQUENCE {
|
||||
* type ObjectID,
|
||||
* value [0] EXPLICIT ANY OPTIONAL
|
||||
* }
|
||||
*
|
||||
* For PE signature, ``SpcAttributeTypeAndOptionalValue.type``
|
||||
* is set to ``SPC_PE_IMAGE_DATAOBJ`` (OID: ``1.3.6.1.4.1.311.2.1.15``) and the value is defined by
|
||||
* ``SpcPeImageData``
|
||||
*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm AlgorithmIdentifier,
|
||||
* digest OCTETSTRING
|
||||
* }
|
||||
*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm ObjectID,
|
||||
* parameters [0] EXPLICIT ANY OPTIONAL
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class LIEF_API ContentInfo : public Object {
|
||||
|
||||
friend class Parser;
|
||||
@ -37,21 +76,29 @@ class LIEF_API ContentInfo : public Object {
|
||||
ContentInfo(const ContentInfo&);
|
||||
ContentInfo& operator=(const ContentInfo&);
|
||||
|
||||
//! @brief OID of the content type.
|
||||
//! This value should match ``SPC_INDIRECT_DATA_OBJID``
|
||||
const oid_t& content_type(void) const;
|
||||
//! Return the OID that describes the content wrapped by this object.
|
||||
//! It should match SPC_INDIRECT_DATA_OBJID (1.3.6.1.4.1.311.2.1.4)
|
||||
inline oid_t content_type() const {
|
||||
return content_type_;
|
||||
}
|
||||
|
||||
const oid_t& type(void) const;
|
||||
//! Digest used to hash the file
|
||||
//!
|
||||
//! It should match LIEF::PE::SignerInfo::digest_algorithm
|
||||
inline ALGORITHMS digest_algorithm() const {
|
||||
return this->digest_algorithm_;
|
||||
}
|
||||
|
||||
//! @brief Algorithm (OID) used to hash the file.
|
||||
//! This value should match SignerInfo::digest_algorithm and Signature::digest_algorithm
|
||||
const oid_t& digest_algorithm(void) const;
|
||||
//! PE's authentihash
|
||||
//!
|
||||
//! @see LIEF::PE::Binary::authentihash
|
||||
inline const std::vector<uint8_t>& digest() const {
|
||||
return this->digest_;
|
||||
}
|
||||
|
||||
//! @brief The digest
|
||||
const std::vector<uint8_t>& digest(void) const;
|
||||
|
||||
//! @brief Return the raw bytes associated with the ContentInfo
|
||||
const std::vector<uint8_t>& raw(void) const;
|
||||
inline const std::string& file() const {
|
||||
return this->file_;
|
||||
}
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
@ -60,14 +107,11 @@ class LIEF_API ContentInfo : public Object {
|
||||
LIEF_API friend std::ostream& operator<<(std::ostream& os, const ContentInfo& content_info);
|
||||
|
||||
private:
|
||||
oid_t content_type_; // SPC_INDIRECT_DATA_OBJID
|
||||
|
||||
oid_t type_; // SPC_PE_IMAGE_DATAOBJ
|
||||
//TODO: value
|
||||
|
||||
oid_t digest_algorithm_; // algorithm used to hash the file (should match Signature::digest_algorithms_)
|
||||
std::vector<uint8_t> digest_; //hash value
|
||||
std::vector<uint8_t> raw_; // raw bytes
|
||||
oid_t content_type_;
|
||||
std::string file_;
|
||||
uint8_t flags_ = 0;
|
||||
ALGORITHMS digest_algorithm_ = ALGORITHMS::UNKNOWN;
|
||||
std::vector<uint8_t> digest_;
|
||||
|
||||
};
|
||||
|
||||
|
65
include/LIEF/PE/signature/RsaInfo.hpp
Normal file
65
include/LIEF/PE/signature/RsaInfo.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_SIGNATURE_RSA_INFO_H_
|
||||
#define LIEF_PE_SIGNATURE_RSA_INFO_H_
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
#include "LIEF/types.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
class x509;
|
||||
|
||||
class LIEF_API RsaInfo {
|
||||
friend class x509;
|
||||
|
||||
public:
|
||||
using rsa_ctx_handle = void*;
|
||||
using bignum_wrapper_t = std::vector<uint8_t>;
|
||||
|
||||
public:
|
||||
RsaInfo(const RsaInfo& other);
|
||||
RsaInfo(RsaInfo&& other);
|
||||
RsaInfo& operator=(RsaInfo other);
|
||||
|
||||
bool has_public_key(void) const;
|
||||
bool has_private_key(void) const;
|
||||
|
||||
bignum_wrapper_t N(void) const;
|
||||
bignum_wrapper_t E(void) const;
|
||||
|
||||
bignum_wrapper_t D(void) const;
|
||||
bignum_wrapper_t P(void) const;
|
||||
bignum_wrapper_t Q(void) const;
|
||||
|
||||
void swap(RsaInfo& other);
|
||||
operator bool() const;
|
||||
|
||||
LIEF_API friend std::ostream& operator<<(std::ostream& os, const RsaInfo& info);
|
||||
|
||||
~RsaInfo(void);
|
||||
|
||||
private:
|
||||
RsaInfo(void);
|
||||
RsaInfo(const rsa_ctx_handle ctx);
|
||||
rsa_ctx_handle ctx_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -24,64 +24,112 @@
|
||||
#include "LIEF/PE/signature/ContentInfo.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/types.hpp"
|
||||
#include "LIEF/PE/enums.hpp"
|
||||
#include "LIEF/enums.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
class SignatureParser;
|
||||
class Binary;
|
||||
|
||||
//! Main interface for the PKCS #7 signature scheme
|
||||
class LIEF_API Signature : public Object {
|
||||
|
||||
friend class SignatureParser;
|
||||
friend class Parser;
|
||||
friend class Binary;
|
||||
|
||||
public:
|
||||
//! Hash the input given the algorithm
|
||||
static std::vector<uint8_t> hash(const std::vector<uint8_t>& input, ALGORITHMS algo);
|
||||
|
||||
public:
|
||||
//! Flags returned by verification fonctions
|
||||
enum class VERIFICATION_FLAGS {
|
||||
OK = 0,
|
||||
INVALID_SIGNER = 1 << 0,
|
||||
UNSUPPORTED_ALGORITHM = 1 << 1,
|
||||
INCONSISTENT_DIGEST_ALGORITHM = 1 << 2,
|
||||
CERT_NOT_FOUND = 1 << 3,
|
||||
CORRUPTED_CONTENT_INFO = 1 << 4,
|
||||
CORRUPTED_AUTH_DATA = 1 << 5,
|
||||
MISSING_PKCS9_MESSAGE_DIGEST = 1 << 6,
|
||||
BAD_DIGEST = 1 << 7,
|
||||
BAD_SIGNATURE = 1 << 8,
|
||||
NO_SIGNATURE = 1 << 9,
|
||||
};
|
||||
|
||||
Signature(void);
|
||||
Signature(const Signature&);
|
||||
Signature& operator=(const Signature&);
|
||||
|
||||
//! @brief Should be 1
|
||||
//! Should be 1
|
||||
uint32_t version(void) const;
|
||||
|
||||
//! @brief Return the algorithm (OID) used to
|
||||
//! sign the content of ContentInfo
|
||||
const oid_t& digest_algorithm(void) const;
|
||||
//! Algorithm used to *digest* the file.
|
||||
//!
|
||||
//! It should match SignerInfo::digest_algorithm
|
||||
inline ALGORITHMS digest_algorithm() const {
|
||||
return this->digest_algorithm_;
|
||||
}
|
||||
|
||||
//! @brief Return the ContentInfo
|
||||
//! Return the ContentInfo
|
||||
const ContentInfo& content_info(void) const;
|
||||
|
||||
//! @brief Return an iterator over x509 certificates
|
||||
//! Return an iterator over x509 certificates
|
||||
it_const_crt certificates(void) const;
|
||||
|
||||
//! @brief Return the SignerInfo object
|
||||
const SignerInfo& signer_info(void) const;
|
||||
//! Return an iterator over the signers (SignerInfo) defined in the PKCS #7 signature
|
||||
it_const_signers_t signers(void) const;
|
||||
|
||||
//! @brief Return the raw original signature
|
||||
const std::vector<uint8_t>& original_signature(void) const;
|
||||
//! Return the raw original PKCS7 signature
|
||||
const std::vector<uint8_t>& raw_der(void) const;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
//! Check if this signature is valid according to the Authenticode/PKCS #7 verification scheme
|
||||
//!
|
||||
//! 1. It must contain only **one** signer info
|
||||
//! 2. Signature::digest_algorithm must match:
|
||||
//! * ContentInfo::digest_algorithm
|
||||
//! * SignerInfo::digest_algorithm
|
||||
//! 3. The x509 certificate specified by SignerInfo::serial_number **and** SignerInfo::issuer
|
||||
//! must exists within Signature::certificates
|
||||
//! 4. Given the x509 certificate, compare SignerInfo::encrypted_digest against either:
|
||||
//! * hash of authenticated attributes if present there are authenticated attributes
|
||||
//! * hash ContentInfo
|
||||
//! 5. If the are Authenticated attributes, check that a PKCS9_MESSAGE_DIGEST attribute exists
|
||||
//! and that its value matches hash of ContentInfo
|
||||
VERIFICATION_FLAGS check() const;
|
||||
|
||||
virtual ~Signature(void);
|
||||
|
||||
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Signature& signature);
|
||||
|
||||
private:
|
||||
|
||||
uint32_t version_;
|
||||
oid_t digest_algorithm_;
|
||||
ContentInfo content_info_;
|
||||
std::vector<x509> certificates_;
|
||||
SignerInfo signer_info_;
|
||||
uint32_t version_ = 0;
|
||||
ALGORITHMS digest_algorithm_ = ALGORITHMS::UNKNOWN;
|
||||
ContentInfo content_info_;
|
||||
std::vector<x509> certificates_;
|
||||
std::vector<SignerInfo> signers_;
|
||||
|
||||
uint64_t content_info_start_ = 0;
|
||||
uint64_t content_info_end_ = 0;
|
||||
|
||||
uint64_t auth_start_ = 0;
|
||||
uint64_t auth_end_ = 0;
|
||||
|
||||
std::vector<uint8_t> original_raw_signature_;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ENABLE_BITMASK_OPERATORS(LIEF::PE::Signature::VERIFICATION_FLAGS);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -17,6 +17,9 @@
|
||||
#define LIEF_PE_SIGNATURE_PARSER_H_
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
#include "LIEF/errors.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/Signature.hpp"
|
||||
#include "LIEF/PE/signature/OIDToString.hpp"
|
||||
@ -26,41 +29,64 @@ class VectorStream;
|
||||
|
||||
namespace PE {
|
||||
class Parser;
|
||||
class Attribute;
|
||||
|
||||
class LIEF_API SignatureParser {
|
||||
|
||||
friend class Parser;
|
||||
struct SpcPeImageData {
|
||||
uint32_t flags;
|
||||
std::string file;
|
||||
};
|
||||
|
||||
struct SpcSpOpusInfo {
|
||||
std::string program_name;
|
||||
std::string more_info;
|
||||
};
|
||||
struct range_t {
|
||||
uint64_t start = 0;
|
||||
uint64_t end = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
static Signature parse(const std::vector<uint8_t>& data);
|
||||
using attributes_t = std::vector<std::unique_ptr<Attribute>>;
|
||||
using signer_infos_t = std::vector<SignerInfo>;
|
||||
using x509_certificates_t = std::vector<x509>;
|
||||
using time_t = std::array<int32_t, 6>;
|
||||
|
||||
//! Parse a PKCS #7 signature given a raw blob
|
||||
static result<Signature> parse(std::vector<uint8_t> data, bool skip_header = false);
|
||||
|
||||
//! Parse a PKCS #7 signature from a file path
|
||||
static result<Signature> parse(const std::string& path);
|
||||
|
||||
private:
|
||||
SignatureParser(const std::vector<uint8_t>& data);
|
||||
~SignatureParser(void);
|
||||
SignatureParser(void);
|
||||
SignatureParser(std::vector<uint8_t> data);
|
||||
~SignatureParser();
|
||||
SignatureParser();
|
||||
|
||||
void parse_signature(void);
|
||||
result<Signature> parse_signature();
|
||||
|
||||
void parse_header(void);
|
||||
int32_t get_signed_data_version(void);
|
||||
std::string get_signed_data_digest_algorithms(void);
|
||||
result<ContentInfo> parse_content_info(VectorStream& stream, range_t& range);
|
||||
result<x509_certificates_t> parse_certificates(VectorStream& stream);
|
||||
result<signer_infos_t> parse_signer_infos(VectorStream& stream, range_t& auth_attr);
|
||||
result<attributes_t> parse_attributes(VectorStream& stream);
|
||||
result<std::unique_ptr<Attribute>> parse_content_type(VectorStream& stream);
|
||||
|
||||
ContentInfo parse_content_info(void);
|
||||
std::string get_content_info_type(void);
|
||||
|
||||
void parse_certificates(void);
|
||||
|
||||
SignerInfo get_signer_info(void);
|
||||
AuthenticatedAttributes get_authenticated_attributes(void);
|
||||
result<signer_infos_t> parse_pkcs9_counter_sign(VectorStream& stream);
|
||||
result<std::vector<uint8_t>> parse_pkcs9_message_digest(VectorStream& stream);
|
||||
result<int32_t> parse_pkcs9_at_sequence_number(VectorStream& stream);
|
||||
result<time_t> parse_pkcs9_signing_time(VectorStream& stream);
|
||||
|
||||
result<void> parse_ms_counter_sign(VectorStream& stream);
|
||||
result<Signature> parse_ms_spc_nested_signature(VectorStream& stream);
|
||||
result<oid_t> parse_ms_spc_statement_type(VectorStream& stream);
|
||||
|
||||
result<SpcSpOpusInfo> parse_spc_sp_opus_info(VectorStream& stream);
|
||||
result<std::string> parse_spc_string(VectorStream& stream);
|
||||
result<std::string> parse_spc_link(VectorStream& stream);
|
||||
result<SpcPeImageData> parse_spc_pe_image_data(VectorStream& stream);
|
||||
size_t current_offset(void) const;
|
||||
Signature signature_;
|
||||
uint8_t* p_{nullptr};
|
||||
const uint8_t* end_{nullptr};
|
||||
const uint8_t* signature_ptr_{nullptr};
|
||||
std::unique_ptr<VectorStream> stream_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -15,19 +15,22 @@
|
||||
*/
|
||||
#ifndef LIEF_PE_SIGNER_INFO_H_
|
||||
#define LIEF_PE_SIGNER_INFO_H_
|
||||
#include <memory>
|
||||
|
||||
#include "LIEF/Object.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/signature/AuthenticatedAttributes.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/types.hpp"
|
||||
#include "LIEF/PE/enums.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
class Attribute;
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
class x509;
|
||||
|
||||
class LIEF_API SignerInfo : public Object {
|
||||
|
||||
@ -35,29 +38,71 @@ class LIEF_API SignerInfo : public Object {
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
using encrypted_digest_t = std::vector<uint8_t>;
|
||||
SignerInfo(void);
|
||||
SignerInfo(const SignerInfo&);
|
||||
SignerInfo& operator=(const SignerInfo&);
|
||||
|
||||
//! @brief Should be 1
|
||||
SignerInfo(const SignerInfo& signinfo);
|
||||
SignerInfo& operator=(SignerInfo signinfo);
|
||||
|
||||
SignerInfo(SignerInfo&&);
|
||||
SignerInfo& operator=(SignerInfo&&);
|
||||
|
||||
void swap(SignerInfo& other);
|
||||
|
||||
//! Should be 1
|
||||
uint32_t version(void) const;
|
||||
|
||||
//! @brief Issuer and serial number
|
||||
const issuer_t& issuer(void) const;
|
||||
//! Return the serial number associated with the x509 certificate
|
||||
//! used by this signer.
|
||||
//!
|
||||
//! @see
|
||||
//! LIEF::PE::x509::serial_number
|
||||
//! SignerInfo::issuer
|
||||
inline const std::vector<uint8_t>& serial_number() const {
|
||||
return this->serialno_;
|
||||
}
|
||||
|
||||
//! @brief Algorithm (OID) used to hash the file.
|
||||
//! This value should match ContentInfo::digest_algorithm and Signature::digest_algorithm
|
||||
const oid_t& digest_algorithm(void) const;
|
||||
//! Return the x509::issuer used by this signer
|
||||
inline const std::string& issuer() const {
|
||||
return this->issuer_;
|
||||
};
|
||||
|
||||
//! @brief Return the AuthenticatedAttributes object
|
||||
const AuthenticatedAttributes& authenticated_attributes(void) const;
|
||||
//! Algorithm (OID) used to hash the file.
|
||||
//!
|
||||
//! This value should match LIEF::PE::ContentInfo::digest_algorithm and
|
||||
//! LIEF::PE::Signature::digest_algorithm
|
||||
ALGORITHMS digest_algorithm(void) const;
|
||||
|
||||
//! @brief Return the signature algorithm (OID)
|
||||
const oid_t& signature_algorithm(void) const;
|
||||
//! Return the (public-key) algorithm used to encrypt
|
||||
//! the signature
|
||||
ALGORITHMS encryption_algorithm(void) const;
|
||||
|
||||
//! @brief Return the signature created by the signing
|
||||
//! Return the signature created by the signing
|
||||
//! certificate's private key
|
||||
const std::vector<uint8_t>& encrypted_digest(void) const;
|
||||
const encrypted_digest_t& encrypted_digest(void) const;
|
||||
|
||||
//! Iterator over LIEF::PE::Attribute for **authenticated** attributes
|
||||
it_const_attributes_t authenticated_attributes() const;
|
||||
|
||||
//! Iterator over LIEF::PE::Attribute for **unauthenticated** attributes
|
||||
it_const_attributes_t unauthenticated_attributes() const;
|
||||
|
||||
//! Return the authenticated or un-authenticated attribute matching the
|
||||
//! given PE::SIG_ATTRIBUTE_TYPES.
|
||||
//!
|
||||
//! It returns **the first** entry that matches the given type. If it can't be
|
||||
//! found, it returns a nullptr.
|
||||
const Attribute* get_attribute(PE::SIG_ATTRIBUTE_TYPES type) const;
|
||||
|
||||
//! x509 certificate used by this signer. If it can't be found, it returns a nullptr
|
||||
inline const x509* cert() const {
|
||||
return this->cert_.get();
|
||||
}
|
||||
|
||||
//! x509 certificate used by this signer. If it can't be found, it returns a nullptr
|
||||
inline x509* cert() {
|
||||
return this->cert_.get();
|
||||
}
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
@ -66,13 +111,18 @@ class LIEF_API SignerInfo : public Object {
|
||||
LIEF_API friend std::ostream& operator<<(std::ostream& os, const SignerInfo& signer_info);
|
||||
|
||||
private:
|
||||
uint32_t version_;
|
||||
issuer_t issuer_;
|
||||
oid_t digest_algorithm_;
|
||||
uint32_t version_;
|
||||
std::string issuer_;
|
||||
std::vector<uint8_t> serialno_;
|
||||
|
||||
AuthenticatedAttributes authenticated_attributes_;
|
||||
oid_t signature_algorithm_;
|
||||
std::vector<uint8_t> encrypted_digest_;
|
||||
ALGORITHMS digest_algorithm_ = ALGORITHMS::UNKNOWN;
|
||||
ALGORITHMS digest_enc_algorithm_ = ALGORITHMS::UNKNOWN;
|
||||
|
||||
encrypted_digest_t encrypted_digest_;
|
||||
std::vector<std::unique_ptr<Attribute>> authenticated_attributes_;
|
||||
std::vector<std::unique_ptr<Attribute>> unauthenticated_attributes_;
|
||||
|
||||
std::unique_ptr<x509> cert_;
|
||||
|
||||
};
|
||||
|
||||
|
14
include/LIEF/PE/signature/attributes.hpp
Normal file
14
include/LIEF/PE/signature/attributes.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef LIEF_PE_SIGNATURE_ATTRIBUTES_H_
|
||||
#define LIEF_PE_SIGNATURE_ATTRIBUTES_H_
|
||||
#include "LIEF/PE/signature/attributes/ContentType.hpp"
|
||||
#include "LIEF/PE/signature/attributes/GenericType.hpp"
|
||||
#include "LIEF/PE/signature/attributes/MsCounterSign.hpp"
|
||||
#include "LIEF/PE/signature/attributes/MsSpcNestedSignature.hpp"
|
||||
#include "LIEF/PE/signature/attributes/MsSpcStatementType.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9AtSequenceNumber.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9CounterSignature.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9MessageDigest.hpp"
|
||||
#include "LIEF/PE/signature/attributes/PKCS9SigningTime.hpp"
|
||||
#include "LIEF/PE/signature/attributes/SpcSpOpusInfo.hpp"
|
||||
#endif
|
||||
|
71
include/LIEF/PE/signature/attributes/ContentType.hpp
Normal file
71
include/LIEF/PE/signature/attributes/ContentType.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_CONTENT_TYPE_H_
|
||||
#define LIEF_PE_ATTRIBUTES_CONTENT_TYPE_H_
|
||||
#include <memory>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.2.840.113549.1.9.3`` (PKCS #9)
|
||||
//!
|
||||
//! The internal structure is described in the
|
||||
//! [RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0](https://tools.ietf.org/html/rfc2985)
|
||||
//!
|
||||
//! ```raw
|
||||
//! ContentType ::= OBJECT IDENTIFIER
|
||||
//! ```
|
||||
class LIEF_API ContentType : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
ContentType();
|
||||
ContentType(oid_t oid);
|
||||
ContentType(const ContentType&);
|
||||
ContentType& operator=(const ContentType&);
|
||||
|
||||
//! OID as described in RFC #2985
|
||||
inline const oid_t& oid() const {
|
||||
return this->oid_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
virtual ~ContentType();
|
||||
|
||||
private:
|
||||
oid_t oid_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
71
include/LIEF/PE/signature/attributes/GenericType.hpp
Normal file
71
include/LIEF/PE/signature/attributes/GenericType.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_GENERIC_TYPE_H_
|
||||
#define LIEF_PE_ATTRIBUTES_GENERIC_TYPE_H_
|
||||
#include <memory>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over an attribute whose the internal structure is not supported by LIEF
|
||||
class LIEF_API GenericType : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
GenericType();
|
||||
GenericType(oid_t oid, std::vector<uint8_t> raw);
|
||||
GenericType(const GenericType&);
|
||||
GenericType& operator=(const GenericType&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! OID of the original attribute
|
||||
inline const oid_t& oid() const {
|
||||
return this->oid_;
|
||||
}
|
||||
|
||||
//! Original DER blob of the attribute
|
||||
inline const std::vector<uint8_t>& raw_content() const {
|
||||
return this->raw_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~GenericType();
|
||||
|
||||
private:
|
||||
oid_t oid_;
|
||||
std::vector<uint8_t> raw_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,73 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_MS_SPC_NESTED_SIG_H_
|
||||
#define LIEF_PE_ATTRIBUTES_MS_SPC_NESTED_SIG_H_
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/Signature.hpp"
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.3.6.1.4.1.311.2.4.1``
|
||||
//!
|
||||
//! The internal structure is not documented but we can infer the following structure:
|
||||
//!
|
||||
//! ```raw
|
||||
//! MsSpcNestedSignature ::= SET OF SignedData
|
||||
//! ```
|
||||
//!
|
||||
//! ``SignedData`` is the structure described in PKCS #7 RFC (LIEF::PE::Signature)
|
||||
class LIEF_API MsSpcNestedSignature : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
MsSpcNestedSignature();
|
||||
MsSpcNestedSignature(Signature sig);
|
||||
MsSpcNestedSignature(const MsSpcNestedSignature&);
|
||||
MsSpcNestedSignature& operator=(const MsSpcNestedSignature&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! Underlying Signature object
|
||||
inline const Signature& sig() const {
|
||||
return this->sig_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~MsSpcNestedSignature();
|
||||
|
||||
private:
|
||||
Signature sig_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
72
include/LIEF/PE/signature/attributes/MsSpcStatementType.hpp
Normal file
72
include/LIEF/PE/signature/attributes/MsSpcStatementType.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_MS_SPC_STATEMENT_TYPE_H_
|
||||
#define LIEF_PE_ATTRIBUTES_MS_SPC_STATEMENT_TYPE_H_
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.3.6.1.4.1.311.2.1.11``
|
||||
//!
|
||||
//! The internal structure is described in the official document:
|
||||
//! [Windows Authenticode Portable Executable Signature Format](http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx)
|
||||
//!
|
||||
//! ```raw
|
||||
//! SpcStatementType ::= SEQUENCE of OBJECT IDENTIFIER
|
||||
//! ```
|
||||
class LIEF_API MsSpcStatementType : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
MsSpcStatementType();
|
||||
MsSpcStatementType(oid_t oid);
|
||||
MsSpcStatementType(const MsSpcStatementType&);
|
||||
MsSpcStatementType& operator=(const MsSpcStatementType&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! According to the documentation:
|
||||
//! > The SpcStatementType MUST contain one Object Identifier with either
|
||||
//! > the value ``1.3.6.1.4.1.311.2.1.21 (SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID)`` or
|
||||
//! > ``1.3.6.1.4.1.311.2.1.22 (SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID)``.
|
||||
inline const oid_t& oid() const {
|
||||
return this->oid_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
virtual ~MsSpcStatementType();
|
||||
|
||||
private:
|
||||
oid_t oid_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,76 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_PKCS9_AT_SEQUENCE_NUMBER_H_
|
||||
#define LIEF_PE_ATTRIBUTES_PKCS9_AT_SEQUENCE_NUMBER_H_
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.2.840.113549.1.9.25.4`` (PKCS #9)
|
||||
//!
|
||||
//! The internal structure is described in the
|
||||
//! [RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0](https://tools.ietf.org/html/rfc2985)
|
||||
//!
|
||||
//! ```raw
|
||||
//! sequenceNumber ATTRIBUTE ::= {
|
||||
//! WITH SYNTAX SequenceNumber
|
||||
//! EQUALITY MATCHING RULE integerMatch
|
||||
//! SINGLE VALUE TRUE
|
||||
//! ID pkcs-9-at-sequenceNumber
|
||||
//! }
|
||||
//!
|
||||
//! SequenceNumber ::= INTEGER (1..MAX)
|
||||
//! ```
|
||||
class LIEF_API PKCS9AtSequenceNumber : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
PKCS9AtSequenceNumber();
|
||||
PKCS9AtSequenceNumber(uint32_t num);
|
||||
PKCS9AtSequenceNumber(const PKCS9AtSequenceNumber&);
|
||||
PKCS9AtSequenceNumber& operator=(const PKCS9AtSequenceNumber&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! Number as described in the RFC
|
||||
inline uint32_t number() const {
|
||||
return this->number_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
virtual ~PKCS9AtSequenceNumber();
|
||||
|
||||
private:
|
||||
uint32_t number_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,76 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_PKCS9_COUNTER_SIG_H_
|
||||
#define LIEF_PE_ATTRIBUTES_PKCS9_COUNTER_SIG_H_
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/SignerInfo.hpp"
|
||||
#include "LIEF/PE/signature/types.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
|
||||
//! Interface over the structure described by the OID ``1.2.840.113549.1.9.6`` (PKCS #9)
|
||||
//!
|
||||
//! The internal structure is described in the
|
||||
//! [RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0](https://tools.ietf.org/html/rfc2985)
|
||||
//!
|
||||
//! ```raw
|
||||
//! counterSignature ATTRIBUTE ::= {
|
||||
//! WITH SYNTAX SignerInfo
|
||||
//! ID pkcs-9-at-counterSignature
|
||||
//! }
|
||||
//! ```
|
||||
class LIEF_API PKCS9CounterSignature : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
PKCS9CounterSignature();
|
||||
PKCS9CounterSignature(std::vector<SignerInfo> signers);
|
||||
PKCS9CounterSignature(const PKCS9CounterSignature&);
|
||||
PKCS9CounterSignature& operator=(const PKCS9CounterSignature&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! Iterator over the SignerInfo as described in the RFC
|
||||
inline it_const_signers_t signers() const {
|
||||
return this->signers_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~PKCS9CounterSignature();
|
||||
|
||||
private:
|
||||
std::vector<SignerInfo> signers_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
77
include/LIEF/PE/signature/attributes/PKCS9MessageDigest.hpp
Normal file
77
include/LIEF/PE/signature/attributes/PKCS9MessageDigest.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_PKCS9_MESSAGE_DIGEST_H_
|
||||
#define LIEF_PE_ATTRIBUTES_PKCS9_MESSAGE_DIGEST_H_
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.2.840.113549.1.9.4`` (PKCS #9)
|
||||
//!
|
||||
//! The internal structure is described in the
|
||||
//! [RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0](https://tools.ietf.org/html/rfc2985)
|
||||
//!
|
||||
//! ```raw
|
||||
//! messageDigest ATTRIBUTE ::= {
|
||||
//! WITH SYNTAX MessageDigest
|
||||
//! EQUALITY MATCHING RULE octetStringMatch
|
||||
//! SINGLE VALUE TRUE
|
||||
//! ID pkcs-9-at-messageDigest
|
||||
//! }
|
||||
//!
|
||||
//! MessageDigest ::= OCTET STRING
|
||||
//! ```
|
||||
class LIEF_API PKCS9MessageDigest : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
PKCS9MessageDigest();
|
||||
PKCS9MessageDigest(std::vector<uint8_t> digest);
|
||||
PKCS9MessageDigest(const PKCS9MessageDigest&);
|
||||
PKCS9MessageDigest& operator=(const PKCS9MessageDigest&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! Message digeset as a blob of bytes as described in the RFC
|
||||
inline const std::vector<uint8_t>& digest() const {
|
||||
return this->digest_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~PKCS9MessageDigest();
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> digest_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
81
include/LIEF/PE/signature/attributes/PKCS9SigningTime.hpp
Normal file
81
include/LIEF/PE/signature/attributes/PKCS9SigningTime.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_PKCS9_SIGNING_TIME_H_
|
||||
#define LIEF_PE_ATTRIBUTES_PKCS9_SIGNING_TIME_H_
|
||||
#include <array>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.2.840.113549.1.9.5`` (PKCS #9)
|
||||
//!
|
||||
//! The internal structure is described in the
|
||||
//! [RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0](https://tools.ietf.org/html/rfc2985)
|
||||
//!
|
||||
//! ```raw
|
||||
//! signingTime ATTRIBUTE ::= {
|
||||
//! WITH SYNTAX SigningTime
|
||||
//! EQUALITY MATCHING RULE signingTimeMatch
|
||||
//! SINGLE VALUE TRUE
|
||||
//! ID pkcs-9-at-signingTime
|
||||
//! }
|
||||
//!
|
||||
//! SigningTime ::= Time -- imported from ISO/IEC 9594-8
|
||||
//! ```
|
||||
class LIEF_API PKCS9SigningTime : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
//! Time as an array [year, month, day, hour, min, sec]
|
||||
using time_t = std::array<int32_t, 6>;
|
||||
|
||||
PKCS9SigningTime();
|
||||
PKCS9SigningTime(time_t time);
|
||||
PKCS9SigningTime(const PKCS9SigningTime&);
|
||||
PKCS9SigningTime& operator=(const PKCS9SigningTime&);
|
||||
|
||||
//! Time as an array [year, month, day, hour, min, sec]
|
||||
const time_t& time() const {
|
||||
return this->time_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
virtual ~PKCS9SigningTime();
|
||||
|
||||
private:
|
||||
time_t time_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
82
include/LIEF/PE/signature/attributes/SpcSpOpusInfo.hpp
Normal file
82
include/LIEF/PE/signature/attributes/SpcSpOpusInfo.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_ATTRIBUTES_SPC_SP_OPUS_INFO_H_
|
||||
#define LIEF_PE_ATTRIBUTES_SPC_SP_OPUS_INFO_H_
|
||||
#include <memory>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/errors.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
class VectorStream;
|
||||
namespace PE {
|
||||
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
//! Interface over the structure described by the OID ``1.3.6.1.4.1.311.2.1.12``
|
||||
//!
|
||||
//! The internal structure is described in the official document:
|
||||
//! [Windows Authenticode Portable Executable Signature Format](http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx)
|
||||
//!
|
||||
//! ```raw
|
||||
//! SpcSpOpusInfo ::= SEQUENCE {
|
||||
//! programName [0] EXPLICIT SpcString OPTIONAL,
|
||||
//! moreInfo [1] EXPLICIT SpcLink OPTIONAL
|
||||
//! }
|
||||
//! ```
|
||||
class LIEF_API SpcSpOpusInfo : public Attribute {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
SpcSpOpusInfo();
|
||||
SpcSpOpusInfo(std::string program_name, std::string more_info);
|
||||
SpcSpOpusInfo(const SpcSpOpusInfo&);
|
||||
SpcSpOpusInfo& operator=(const SpcSpOpusInfo&);
|
||||
|
||||
virtual std::unique_ptr<Attribute> clone(void) const override;
|
||||
|
||||
//! Program description provided by the publisher
|
||||
inline const std::string& program_name() const {
|
||||
return this->program_name_;
|
||||
}
|
||||
|
||||
//! Other information such as an url
|
||||
inline const std::string& more_info() const {
|
||||
return this->more_info_;
|
||||
}
|
||||
|
||||
//! Print information about the attribute
|
||||
virtual std::string print() const override;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~SpcSpOpusInfo();
|
||||
|
||||
private:
|
||||
std::string program_name_;
|
||||
std::string more_info_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -24,10 +24,13 @@
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
class x509;
|
||||
class SignerInfo;
|
||||
class Attribute;
|
||||
|
||||
using oid_t = std::string;
|
||||
using issuer_t = std::pair<std::string, std::vector<uint8_t>>;
|
||||
using it_const_crt = const_ref_iterator<const std::vector<x509>&>;
|
||||
using oid_t = std::string;
|
||||
using it_const_crt = const_ref_iterator<const std::vector<x509>&>;
|
||||
using it_const_signers_t = const_ref_iterator<const std::vector<SignerInfo>&>;
|
||||
using it_const_attributes_t = const_ref_iterator<std::vector<Attribute*>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,18 @@
|
||||
*/
|
||||
#ifndef LIEF_PE_X509_H_
|
||||
#define LIEF_PE_X509_H_
|
||||
#include <tuple>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "LIEF/Object.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/enums.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/types.hpp"
|
||||
|
||||
#include "LIEF/enums.hpp"
|
||||
|
||||
struct mbedtls_x509_crt;
|
||||
|
||||
namespace LIEF {
|
||||
@ -30,44 +35,106 @@ namespace PE {
|
||||
class Parser;
|
||||
class SignatureParser;
|
||||
|
||||
class RsaInfo;
|
||||
|
||||
class LIEF_API x509 : public Object {
|
||||
|
||||
friend class Parser;
|
||||
friend class SignatureParser;
|
||||
|
||||
public:
|
||||
//! @brief Tuple (Year, Month, Day, Hour, Minute, Second)
|
||||
//! Tuple (Year, Month, Day, Hour, Minute, Second)
|
||||
using date_t = std::array<int32_t, 6>;
|
||||
|
||||
using certificates_t = std::vector<x509>;
|
||||
|
||||
static certificates_t parse(const std::string& path);
|
||||
static certificates_t parse(const std::vector<uint8_t>& content);
|
||||
|
||||
//! Public key scheme
|
||||
enum class KEY_TYPES {
|
||||
NONE = 0,
|
||||
RSA,
|
||||
ECKEY,
|
||||
ECKEY_DH,
|
||||
ECDSA,
|
||||
RSA_ALT,
|
||||
RSASSA_PSS,
|
||||
};
|
||||
|
||||
//! Mirror of mbedtls's X509 Verify codes: MBEDTLS_X509_XX
|
||||
//!
|
||||
//! It must be sync with include/mbedtls/x509.h
|
||||
enum class VERIFICATION_FLAGS {
|
||||
OK = 0, /**< The verification succeed */
|
||||
BADCERT_EXPIRED = 1 << 0, /**< The certificate validity has expired. */
|
||||
BADCERT_REVOKED = 1 << 1, /**< The certificate has been revoked (is on a CRL). */
|
||||
BADCERT_CN_MISMATCH = 1 << 2, /**< The certificate Common Name (CN) does not match with the expected CN. */
|
||||
BADCERT_NOT_TRUSTED = 1 << 3, /**< The certificate is not correctly signed by the trusted CA. */
|
||||
BADCRL_NOT_TRUSTED = 1 << 4, /**< The CRL is not correctly signed by the trusted CA. */
|
||||
BADCRL_EXPIRED = 1 << 5, /**< The CRL is expired. */
|
||||
BADCERT_MISSING = 1 << 6, /**< Certificate was missing. */
|
||||
BADCERT_SKIP_VERIFY = 1 << 7, /**< Certificate verification was skipped. */
|
||||
BADCERT_OTHER = 1 << 8, /**< Other reason (can be used by verify callback) */
|
||||
BADCERT_FUTURE = 1 << 9, /**< The certificate validity starts in the future. */
|
||||
BADCRL_FUTURE = 1 << 10, /**< The CRL is from the future */
|
||||
BADCERT_KEY_USAGE = 1 << 11, /**< Usage does not match the keyUsage extension. */
|
||||
BADCERT_EXT_KEY_USAGE = 1 << 12, /**< Usage does not match the extendedKeyUsage extension. */
|
||||
BADCERT_NS_CERT_TYPE = 1 << 13, /**< Usage does not match the nsCertType extension. */
|
||||
BADCERT_BAD_MD = 1 << 14, /**< The certificate is signed with an unacceptable hash. */
|
||||
BADCERT_BAD_PK = 1 << 15, /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
|
||||
BADCERT_BAD_KEY = 1 << 16, /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */
|
||||
BADCRL_BAD_MD = 1 << 17, /**< The CRL is signed with an unacceptable hash. */
|
||||
BADCRL_BAD_PK = 1 << 18, /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
|
||||
BADCRL_BAD_KEY = 1 << 19, /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */
|
||||
};
|
||||
|
||||
x509(mbedtls_x509_crt* ca);
|
||||
x509(const x509& other);
|
||||
x509& operator=(x509 other);
|
||||
void swap(x509& other);
|
||||
|
||||
//! @brief X.509 version. (1=v1, 2=v2, 3=v3)
|
||||
//! X.509 version. (1=v1, 2=v2, 3=v3)
|
||||
uint32_t version(void) const;
|
||||
|
||||
//! @brief Unique id for certificate issued by a specific CA.
|
||||
//! Unique id for certificate issued by a specific CA.
|
||||
std::vector<uint8_t> serial_number(void) const;
|
||||
|
||||
//! @brief Signature algorithm (OID)
|
||||
//! Signature algorithm (OID)
|
||||
oid_t signature_algorithm(void) const;
|
||||
|
||||
//! @brief Start time of certificate validity
|
||||
//! Start time of certificate validity
|
||||
x509::date_t valid_from(void) const;
|
||||
|
||||
//! @brief End time of certificate validity
|
||||
//! End time of certificate validity
|
||||
x509::date_t valid_to(void) const;
|
||||
|
||||
//! @brief Issuer informations
|
||||
//! Issuer informations
|
||||
std::string issuer(void) const;
|
||||
|
||||
//! @brief Subject informations
|
||||
//! Subject informations
|
||||
std::string subject(void) const;
|
||||
|
||||
//! @brief The raw x509 bytes (DER encoded)
|
||||
//! Try to decrypt the given signature and check if it matches the given hash according to
|
||||
//! the hash algorithm provided
|
||||
bool check_signature(const std::vector<uint8_t>& hash, const std::vector<uint8_t>& signature, ALGORITHMS digest) const;
|
||||
|
||||
//! The raw x509 bytes (DER encoded)
|
||||
std::vector<uint8_t> raw(void) const;
|
||||
|
||||
//! Return the underlying public-key scheme
|
||||
KEY_TYPES key_type() const;
|
||||
|
||||
//! **If** the underlying public-key scheme is RSA, return the Rsa information.
|
||||
//! Otherwise, return a nullptr
|
||||
std::unique_ptr<RsaInfo> rsa_info() const;
|
||||
|
||||
//! Verify that this certificate has been used **to trust** the given certificate
|
||||
VERIFICATION_FLAGS verify(const x509& child) const;
|
||||
|
||||
//! Verify that this certificate **is trusted** by the given CA list
|
||||
VERIFICATION_FLAGS is_trusted_by(const std::vector<x509>& ca) const;
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
virtual ~x509(void);
|
||||
@ -76,11 +143,13 @@ class LIEF_API x509 : public Object {
|
||||
|
||||
private:
|
||||
x509(void);
|
||||
mbedtls_x509_crt *x509_cert_;
|
||||
mbedtls_x509_crt* x509_cert_ = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ENABLE_BITMASK_OPERATORS(LIEF::PE::x509::VERIFICATION_FLAGS);
|
||||
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LIEF_PE_TYPE_TRAITS_H_
|
||||
#define LIEF_PE_TYPE_TRAITS_H_
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "LIEF/iterators.hpp"
|
||||
#include "LIEF/PE/enums.hpp"
|
||||
|
||||
@ -30,6 +31,7 @@ class RichEntry;
|
||||
class RelocationEntry;
|
||||
class Debug;
|
||||
class PogoEntry;
|
||||
class Signature;
|
||||
|
||||
class Import;
|
||||
class ImportEntry;
|
||||
@ -95,6 +97,10 @@ using rich_entries_t = std::vector<RichEntry>;
|
||||
using it_rich_entries = ref_iterator<rich_entries_t&>;
|
||||
using it_const_rich_entries = const_ref_iterator<const rich_entries_t&>;
|
||||
|
||||
using signatures_t = std::vector<Signature>;
|
||||
using it_signatures = ref_iterator<signatures_t&>;
|
||||
using it_const_signatures = const_ref_iterator<const signatures_t&>;
|
||||
|
||||
|
||||
template<class T>
|
||||
using flags_list_t = std::set<T>;
|
||||
|
@ -62,6 +62,8 @@ LIEF_API std::string get_imphash(const Binary& binary);
|
||||
//!
|
||||
//! @return The PE::import resolved with PE::ImportEntry::name set
|
||||
LIEF_API Import resolve_ordinals(const Import& import, bool strict=false);
|
||||
|
||||
LIEF_API ALGORITHMS algo_from_oid(const std::string& oid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -79,11 +79,23 @@ LIEF_PE_FORWARD(ResourceDialog)
|
||||
LIEF_PE_FORWARD(ResourceDialogItem)
|
||||
LIEF_PE_FORWARD(ResourceStringTable)
|
||||
LIEF_PE_FORWARD(ResourceAccelerator)
|
||||
|
||||
LIEF_PE_FORWARD(Signature)
|
||||
LIEF_PE_FORWARD(x509)
|
||||
LIEF_PE_FORWARD(SignerInfo)
|
||||
LIEF_PE_FORWARD(ContentInfo)
|
||||
LIEF_PE_FORWARD(AuthenticatedAttributes)
|
||||
LIEF_PE_FORWARD(Attribute)
|
||||
LIEF_PE_FORWARD(ContentType)
|
||||
LIEF_PE_FORWARD(GenericType)
|
||||
//LIEF_PE_FORWARD(MsCounterSign)
|
||||
LIEF_PE_FORWARD(MsSpcNestedSignature)
|
||||
LIEF_PE_FORWARD(MsSpcStatementType)
|
||||
LIEF_PE_FORWARD(PKCS9AtSequenceNumber)
|
||||
LIEF_PE_FORWARD(PKCS9CounterSignature)
|
||||
LIEF_PE_FORWARD(PKCS9MessageDigest)
|
||||
LIEF_PE_FORWARD(PKCS9SigningTime)
|
||||
LIEF_PE_FORWARD(SpcSpOpusInfo)
|
||||
|
||||
LIEF_PE_FORWARD(CodeIntegrity)
|
||||
LIEF_PE_FORWARD(LoadConfiguration)
|
||||
LIEF_PE_FORWARD(LoadConfigurationV0)
|
||||
@ -196,189 +208,216 @@ LIEF_ART_FORWARD(Header)
|
||||
|
||||
|
||||
class LIEF_API Visitor {
|
||||
public:
|
||||
Visitor(void);
|
||||
virtual ~Visitor(void);
|
||||
public:
|
||||
Visitor(void);
|
||||
virtual ~Visitor(void);
|
||||
|
||||
virtual void operator()(void);
|
||||
virtual void operator()(void);
|
||||
|
||||
template<typename Arg1, typename... Args>
|
||||
void operator()(Arg1&& arg1, Args&&... args);
|
||||
template<typename Arg1, typename... Args>
|
||||
void operator()(Arg1&& arg1, Args&&... args);
|
||||
|
||||
virtual void visit(const Object&);
|
||||
virtual void visit(const Object&);
|
||||
|
||||
// Abstract Part
|
||||
// =============
|
||||
// Abstract Part
|
||||
// =============
|
||||
|
||||
//! Method to visit a LIEF::Binary
|
||||
LIEF_ABSTRACT_VISITABLE(Binary)
|
||||
//! Method to visit a LIEF::Binary
|
||||
LIEF_ABSTRACT_VISITABLE(Binary)
|
||||
|
||||
//! Method to visit a LIEF::Header
|
||||
LIEF_ABSTRACT_VISITABLE(Header)
|
||||
//! Method to visit a LIEF::Header
|
||||
LIEF_ABSTRACT_VISITABLE(Header)
|
||||
|
||||
//! Method to visit a LIEF::Section
|
||||
LIEF_ABSTRACT_VISITABLE(Section)
|
||||
//! Method to visit a LIEF::Section
|
||||
LIEF_ABSTRACT_VISITABLE(Section)
|
||||
|
||||
//! Method to visit a LIEF::Symbol
|
||||
LIEF_ABSTRACT_VISITABLE(Symbol)
|
||||
//! Method to visit a LIEF::Symbol
|
||||
LIEF_ABSTRACT_VISITABLE(Symbol)
|
||||
|
||||
//! Method to visit a LIEF::Relocation
|
||||
LIEF_ABSTRACT_VISITABLE(Relocation)
|
||||
//! Method to visit a LIEF::Relocation
|
||||
LIEF_ABSTRACT_VISITABLE(Relocation)
|
||||
|
||||
//! Method to visit a LIEF::Function
|
||||
LIEF_ABSTRACT_VISITABLE(Function)
|
||||
//! Method to visit a LIEF::Function
|
||||
LIEF_ABSTRACT_VISITABLE(Function)
|
||||
|
||||
LIEF_ELF_VISITABLE(Binary)
|
||||
LIEF_ELF_VISITABLE(Header)
|
||||
LIEF_ELF_VISITABLE(Section)
|
||||
LIEF_ELF_VISITABLE(Segment)
|
||||
LIEF_ELF_VISITABLE(DynamicEntry)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryArray)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryLibrary)
|
||||
LIEF_ELF_VISITABLE(DynamicSharedObject)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryRunPath)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryRpath)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryFlags)
|
||||
LIEF_ELF_VISITABLE(Symbol)
|
||||
LIEF_ELF_VISITABLE(Relocation)
|
||||
LIEF_ELF_VISITABLE(SymbolVersion)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionRequirement)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionDefinition)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionAux)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionAuxRequirement)
|
||||
LIEF_ELF_VISITABLE(Note)
|
||||
LIEF_ELF_VISITABLE(NoteDetails)
|
||||
LIEF_ELF_VISITABLE(AndroidNote)
|
||||
LIEF_ELF_VISITABLE(NoteAbi)
|
||||
LIEF_ELF_VISITABLE(CorePrPsInfo)
|
||||
LIEF_ELF_VISITABLE(CorePrStatus)
|
||||
LIEF_ELF_VISITABLE(CoreAuxv)
|
||||
LIEF_ELF_VISITABLE(CoreSigInfo)
|
||||
LIEF_ELF_VISITABLE(CoreFile)
|
||||
LIEF_ELF_VISITABLE(GnuHash)
|
||||
LIEF_ELF_VISITABLE(SysvHash)
|
||||
LIEF_ELF_VISITABLE(Binary)
|
||||
LIEF_ELF_VISITABLE(Header)
|
||||
LIEF_ELF_VISITABLE(Section)
|
||||
LIEF_ELF_VISITABLE(Segment)
|
||||
LIEF_ELF_VISITABLE(DynamicEntry)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryArray)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryLibrary)
|
||||
LIEF_ELF_VISITABLE(DynamicSharedObject)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryRunPath)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryRpath)
|
||||
LIEF_ELF_VISITABLE(DynamicEntryFlags)
|
||||
LIEF_ELF_VISITABLE(Symbol)
|
||||
LIEF_ELF_VISITABLE(Relocation)
|
||||
LIEF_ELF_VISITABLE(SymbolVersion)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionRequirement)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionDefinition)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionAux)
|
||||
LIEF_ELF_VISITABLE(SymbolVersionAuxRequirement)
|
||||
LIEF_ELF_VISITABLE(Note)
|
||||
LIEF_ELF_VISITABLE(NoteDetails)
|
||||
LIEF_ELF_VISITABLE(AndroidNote)
|
||||
LIEF_ELF_VISITABLE(NoteAbi)
|
||||
LIEF_ELF_VISITABLE(CorePrPsInfo)
|
||||
LIEF_ELF_VISITABLE(CorePrStatus)
|
||||
LIEF_ELF_VISITABLE(CoreAuxv)
|
||||
LIEF_ELF_VISITABLE(CoreSigInfo)
|
||||
LIEF_ELF_VISITABLE(CoreFile)
|
||||
LIEF_ELF_VISITABLE(GnuHash)
|
||||
LIEF_ELF_VISITABLE(SysvHash)
|
||||
|
||||
// PE Part
|
||||
// =======
|
||||
//! Method to visit a LIEF::PE::Binary
|
||||
LIEF_PE_VISITABLE(Binary)
|
||||
// PE Part
|
||||
// =======
|
||||
//! Method to visit a LIEF::PE::Binary
|
||||
LIEF_PE_VISITABLE(Binary)
|
||||
|
||||
//! Method to visit a LIEF::PE::DosHeader
|
||||
LIEF_PE_VISITABLE(DosHeader)
|
||||
//! Method to visit a LIEF::PE::DosHeader
|
||||
LIEF_PE_VISITABLE(DosHeader)
|
||||
|
||||
//! Method to visit a LIEF::PE:RichHeader
|
||||
LIEF_PE_VISITABLE(RichHeader)
|
||||
//! Method to visit a LIEF::PE:RichHeader
|
||||
LIEF_PE_VISITABLE(RichHeader)
|
||||
|
||||
//! Method to visit a LIEF::PE:RichEntry
|
||||
LIEF_PE_VISITABLE(RichEntry)
|
||||
//! Method to visit a LIEF::PE:RichEntry
|
||||
LIEF_PE_VISITABLE(RichEntry)
|
||||
|
||||
//! Method to visit a LIEF::PE::Header
|
||||
LIEF_PE_VISITABLE(Header)
|
||||
//! Method to visit a LIEF::PE::Header
|
||||
LIEF_PE_VISITABLE(Header)
|
||||
|
||||
//! Method to visit a LIEF::PE::OptionalHeader
|
||||
LIEF_PE_VISITABLE(OptionalHeader)
|
||||
//! Method to visit a LIEF::PE::OptionalHeader
|
||||
LIEF_PE_VISITABLE(OptionalHeader)
|
||||
|
||||
//! Method to visit a LIEF::PE::DataDirectory
|
||||
LIEF_PE_VISITABLE(DataDirectory)
|
||||
//! Method to visit a LIEF::PE::DataDirectory
|
||||
LIEF_PE_VISITABLE(DataDirectory)
|
||||
|
||||
//! Method to visit a LIEF::PE::TLS
|
||||
LIEF_PE_VISITABLE(TLS)
|
||||
//! Method to visit a LIEF::PE::TLS
|
||||
LIEF_PE_VISITABLE(TLS)
|
||||
|
||||
//! Method to visit a LIEF::PE::Symbol
|
||||
LIEF_PE_VISITABLE(Symbol)
|
||||
//! Method to visit a LIEF::PE::Symbol
|
||||
LIEF_PE_VISITABLE(Symbol)
|
||||
|
||||
//! Method to visit a LIEF::PE::Section
|
||||
LIEF_PE_VISITABLE(Section)
|
||||
//! Method to visit a LIEF::PE::Section
|
||||
LIEF_PE_VISITABLE(Section)
|
||||
|
||||
//! Method to visit a LIEF::PE::Relocation
|
||||
LIEF_PE_VISITABLE(Relocation)
|
||||
//! Method to visit a LIEF::PE::Relocation
|
||||
LIEF_PE_VISITABLE(Relocation)
|
||||
|
||||
//! Method to visit a LIEF::PE::RelocationEntry
|
||||
LIEF_PE_VISITABLE(RelocationEntry)
|
||||
//! Method to visit a LIEF::PE::RelocationEntry
|
||||
LIEF_PE_VISITABLE(RelocationEntry)
|
||||
|
||||
//! Method to visit a LIEF::PE::Export
|
||||
LIEF_PE_VISITABLE(Export)
|
||||
//! Method to visit a LIEF::PE::Export
|
||||
LIEF_PE_VISITABLE(Export)
|
||||
|
||||
//! Method to visit a LIEF::PE::ExportEntry
|
||||
LIEF_PE_VISITABLE(ExportEntry)
|
||||
//! Method to visit a LIEF::PE::ExportEntry
|
||||
LIEF_PE_VISITABLE(ExportEntry)
|
||||
|
||||
//! Method to visit a LIEF::PE::Debug
|
||||
LIEF_PE_VISITABLE(Debug)
|
||||
//! Method to visit a LIEF::PE::Debug
|
||||
LIEF_PE_VISITABLE(Debug)
|
||||
|
||||
//! Method to visit a LIEF::PE::CodeView
|
||||
LIEF_PE_VISITABLE(CodeView)
|
||||
//! Method to visit a LIEF::PE::CodeView
|
||||
LIEF_PE_VISITABLE(CodeView)
|
||||
|
||||
//! Method to visit a LIEF::PE::CodeViewPDB
|
||||
LIEF_PE_VISITABLE(CodeViewPDB)
|
||||
//! Method to visit a LIEF::PE::CodeViewPDB
|
||||
LIEF_PE_VISITABLE(CodeViewPDB)
|
||||
|
||||
//! Method to visit a LIEF::PE::Import
|
||||
LIEF_PE_VISITABLE(Import)
|
||||
//! Method to visit a LIEF::PE::Import
|
||||
LIEF_PE_VISITABLE(Import)
|
||||
|
||||
//! Method to visit a LIEF::PE::ImportEntry
|
||||
LIEF_PE_VISITABLE(ImportEntry)
|
||||
//! Method to visit a LIEF::PE::ImportEntry
|
||||
LIEF_PE_VISITABLE(ImportEntry)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceNode
|
||||
LIEF_PE_VISITABLE(ResourceNode)
|
||||
//! Method to visit a LIEF::PE::ResourceNode
|
||||
LIEF_PE_VISITABLE(ResourceNode)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceData
|
||||
LIEF_PE_VISITABLE(ResourceData)
|
||||
//! Method to visit a LIEF::PE::ResourceData
|
||||
LIEF_PE_VISITABLE(ResourceData)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceDirectory
|
||||
LIEF_PE_VISITABLE(ResourceDirectory)
|
||||
//! Method to visit a LIEF::PE::ResourceDirectory
|
||||
LIEF_PE_VISITABLE(ResourceDirectory)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceVersion
|
||||
LIEF_PE_VISITABLE(ResourcesManager)
|
||||
//! Method to visit a LIEF::PE::ResourceVersion
|
||||
LIEF_PE_VISITABLE(ResourcesManager)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceVersion
|
||||
LIEF_PE_VISITABLE(ResourceVersion)
|
||||
//! Method to visit a LIEF::PE::ResourceVersion
|
||||
LIEF_PE_VISITABLE(ResourceVersion)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceStringFileInfo
|
||||
LIEF_PE_VISITABLE(ResourceStringFileInfo)
|
||||
//! Method to visit a LIEF::PE::ResourceStringFileInfo
|
||||
LIEF_PE_VISITABLE(ResourceStringFileInfo)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceFixedFileInfo
|
||||
LIEF_PE_VISITABLE(ResourceFixedFileInfo)
|
||||
//! Method to visit a LIEF::PE::ResourceFixedFileInfo
|
||||
LIEF_PE_VISITABLE(ResourceFixedFileInfo)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceVarFileInfo
|
||||
LIEF_PE_VISITABLE(ResourceVarFileInfo)
|
||||
//! Method to visit a LIEF::PE::ResourceVarFileInfo
|
||||
LIEF_PE_VISITABLE(ResourceVarFileInfo)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceStringTable
|
||||
LIEF_PE_VISITABLE(ResourceStringTable)
|
||||
//! Method to visit a LIEF::PE::ResourceStringTable
|
||||
LIEF_PE_VISITABLE(ResourceStringTable)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceAccelerator
|
||||
LIEF_PE_VISITABLE(ResourceAccelerator)
|
||||
//! Method to visit a LIEF::PE::ResourceAccelerator
|
||||
LIEF_PE_VISITABLE(ResourceAccelerator)
|
||||
|
||||
//! Method to visit a LIEF::PE::LangCodeItem
|
||||
LIEF_PE_VISITABLE(LangCodeItem)
|
||||
//! Method to visit a LIEF::PE::LangCodeItem
|
||||
LIEF_PE_VISITABLE(LangCodeItem)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceIcon
|
||||
LIEF_PE_VISITABLE(ResourceIcon)
|
||||
//! Method to visit a LIEF::PE::ResourceIcon
|
||||
LIEF_PE_VISITABLE(ResourceIcon)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceDialog
|
||||
LIEF_PE_VISITABLE(ResourceDialog)
|
||||
//! Method to visit a LIEF::PE::ResourceDialog
|
||||
LIEF_PE_VISITABLE(ResourceDialog)
|
||||
|
||||
//! Method to visit a LIEF::PE::ResourceDialogItem
|
||||
LIEF_PE_VISITABLE(ResourceDialogItem)
|
||||
//! Method to visit a LIEF::PE::ResourceDialogItem
|
||||
LIEF_PE_VISITABLE(ResourceDialogItem)
|
||||
|
||||
//! Method to visit a LIEF::PE::Signature
|
||||
LIEF_PE_VISITABLE(Signature)
|
||||
//! Method to visit a LIEF::PE::Signature
|
||||
LIEF_PE_VISITABLE(Signature)
|
||||
|
||||
//! Method to visit a LIEF::PE::x509
|
||||
LIEF_PE_VISITABLE(x509)
|
||||
//! Method to visit a LIEF::PE::x509
|
||||
LIEF_PE_VISITABLE(x509)
|
||||
|
||||
//! Method to visit a LIEF::PE::SignerInfo
|
||||
LIEF_PE_VISITABLE(SignerInfo)
|
||||
//! Method to visit a LIEF::PE::SignerInfo
|
||||
LIEF_PE_VISITABLE(SignerInfo)
|
||||
|
||||
//! Method to visit a LIEF::PE::ContentInfo
|
||||
LIEF_PE_VISITABLE(ContentInfo)
|
||||
//! Method to visit a LIEF::PE::ContentInfo
|
||||
LIEF_PE_VISITABLE(ContentInfo)
|
||||
|
||||
//! Method to visit a LIEF::PE::AuthenticatedAttributes
|
||||
LIEF_PE_VISITABLE(AuthenticatedAttributes)
|
||||
//! Method to visit a LIEF::PE::Attribute
|
||||
LIEF_PE_VISITABLE(Attribute)
|
||||
|
||||
//! Method to visit a LIEF::PE::issuer_t
|
||||
LIEF_PE_VISITABLE(issuer_t)
|
||||
//! Method to visit a LIEF::PE::ContentType
|
||||
LIEF_PE_VISITABLE(ContentType)
|
||||
|
||||
//! Method to visit a LIEF::PE::LoadConfiguration
|
||||
LIEF_PE_VISITABLE(LoadConfiguration)
|
||||
//! Method to visit a LIEF::PE::GenericType
|
||||
LIEF_PE_VISITABLE(GenericType)
|
||||
|
||||
//! Method to visit a LIEF::PE::MsCounterSign
|
||||
//LIEF_PE_VISITABLE(MsCounterSign)
|
||||
|
||||
//! Method to visit a LIEF::PE::MsSpcNestedSignature
|
||||
LIEF_PE_VISITABLE(MsSpcNestedSignature)
|
||||
|
||||
//! Method to visit a LIEF::PE::MsSpcStatementType
|
||||
LIEF_PE_VISITABLE(MsSpcStatementType)
|
||||
|
||||
//! Method to visit a LIEF::PE::PKCS9AtSequenceNumber
|
||||
LIEF_PE_VISITABLE(PKCS9AtSequenceNumber)
|
||||
|
||||
//! Method to visit a LIEF::PE::PKCS9CounterSignature
|
||||
LIEF_PE_VISITABLE(PKCS9CounterSignature)
|
||||
|
||||
//! Method to visit a LIEF::PE::PKCS9MessageDigest
|
||||
LIEF_PE_VISITABLE(PKCS9MessageDigest)
|
||||
|
||||
//! Method to visit a LIEF::PE::PKCS9SigningTime
|
||||
LIEF_PE_VISITABLE(PKCS9SigningTime)
|
||||
|
||||
//! Method to visit a LIEF::PE::SpcSpOpusInfo
|
||||
LIEF_PE_VISITABLE(SpcSpOpusInfo)
|
||||
|
||||
//! Method to visit a LIEF::PE::LoadConfiguration
|
||||
LIEF_PE_VISITABLE(LoadConfiguration)
|
||||
|
||||
//! Method to visit a LIEF::PE::LoadConfigurationV0
|
||||
LIEF_PE_VISITABLE(LoadConfigurationV0)
|
||||
|
81
include/LIEF/errors.hpp
Normal file
81
include/LIEF/errors.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef LIEF_ERROR_H_
|
||||
#define LIEF_ERROR_H_
|
||||
#include <system_error>
|
||||
#include <LIEF/third-party/boost/leaf/all.hpp>
|
||||
|
||||
//! LIEF error codes definition
|
||||
enum class lief_errors {
|
||||
read_error = 1,
|
||||
not_found,
|
||||
not_implemented,
|
||||
not_supported,
|
||||
|
||||
corrupted,
|
||||
conversion_error,
|
||||
|
||||
read_out_of_bound,
|
||||
asn1_bad_tag,
|
||||
file_error,
|
||||
};
|
||||
|
||||
const std::error_category& error_category();
|
||||
std::error_code make_error_code(lief_errors e);
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct is_error_code_enum<lief_errors>: std::true_type
|
||||
{};
|
||||
}
|
||||
|
||||
const std::error_category& lief_error_category();
|
||||
|
||||
//! Create an standard error code from lief_errors
|
||||
inline std::error_code make_error_code(lief_errors e) {
|
||||
return std::error_code(int(e), lief_error_category());
|
||||
}
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
|
||||
|
||||
//! Wrapper that contains an Object or an error
|
||||
//!
|
||||
//! The LEAF implementation exposes the method ``value()`` to access the underlying object (if no error)
|
||||
//!
|
||||
//! Typical usage is:
|
||||
//! \code{.cpp}
|
||||
//! result<int> intval = my_function();
|
||||
//! if (intval) {
|
||||
//! int val = intval.value();
|
||||
//! } else { // There is an error
|
||||
//! std::cout << get_error(intval).message() << "\n";
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! See https://boostorg.github.io/leaf/ for more details
|
||||
template<typename T>
|
||||
using result = boost::leaf::result<T>;
|
||||
|
||||
//! Abstraction over the implementation
|
||||
template<typename T>
|
||||
using error_result_t = typename result<T>::error_resul;
|
||||
|
||||
//! Abstraction over the implementation
|
||||
using error_t = boost::leaf::error_id;
|
||||
|
||||
//! Create an error_t from a lief_errors
|
||||
error_t return_error(lief_errors);
|
||||
|
||||
//! Get the error code associated with the result
|
||||
template<class T>
|
||||
std::error_code get_error(result<T>& err) {
|
||||
return make_error_code(lief_errors(boost::leaf::error_id(err.error()).value()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
#include <streambuf>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#include "LIEF/BinaryStream/Convert.hpp"
|
||||
|
||||
@ -39,6 +40,7 @@ class vector_iostream {
|
||||
vector_iostream& write(std::vector<uint8_t>&& s);
|
||||
vector_iostream& write(const std::string& s);
|
||||
vector_iostream& write(size_t count, uint8_t value);
|
||||
vector_iostream& write_sized_int(uint64_t value, size_t size);
|
||||
|
||||
template<typename T>
|
||||
vector_iostream& write_conv(const T& t);
|
||||
@ -54,17 +56,23 @@ class vector_iostream {
|
||||
this->raw_.resize(static_cast<size_t>(this->tellp()) + sizeof(Integer));
|
||||
}
|
||||
|
||||
auto&& it = std::begin(this->raw_);
|
||||
std::advance(it, static_cast<size_t>(this->tellp()));
|
||||
auto int_p = reinterpret_cast<const uint8_t*>(&integer);
|
||||
std::copy(
|
||||
reinterpret_cast<const Integer*>(&integer),
|
||||
reinterpret_cast<const Integer*>(&integer) + sizeof(Integer),
|
||||
it);
|
||||
int_p, int_p + sizeof(Integer),
|
||||
std::begin(this->raw_) + static_cast<size_t>(this->tellp()));
|
||||
|
||||
this->current_pos_ += sizeof(Integer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t size, typename = typename std::enable_if<std::is_integral<T>::value>>
|
||||
vector_iostream& write(const std::array<T, size>& t) {
|
||||
for (T val : t) {
|
||||
this->write<T>(val);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
vector_iostream& write_uleb128(uint64_t value);
|
||||
vector_iostream& write_sleb128(int64_t value);
|
||||
|
||||
|
@ -71,6 +71,8 @@ LIEF_API std::u16string u8tou16(const std::string& string);
|
||||
|
||||
LIEF_API std::string hex_str(uint8_t c);
|
||||
|
||||
LIEF_API std::string hex_dump(const std::vector<uint8_t>& data, std::string sep = ":");
|
||||
|
||||
//! Check if the given string in printable
|
||||
LIEF_API bool is_printable(const std::string& str);
|
||||
|
||||
|
@ -21,11 +21,28 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/asn1.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/x509_crt.h>
|
||||
|
||||
#include "logging.hpp"
|
||||
|
||||
#include "LIEF/BinaryStream/VectorStream.hpp"
|
||||
#include "LIEF/exception.hpp"
|
||||
namespace LIEF {
|
||||
|
||||
inline void free_names(mbedtls_x509_name& names) {
|
||||
mbedtls_x509_name *name_cur;
|
||||
name_cur = names.next;
|
||||
while (name_cur != nullptr) {
|
||||
mbedtls_x509_name *name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_free(name_prv);
|
||||
}
|
||||
}
|
||||
|
||||
VectorStream::VectorStream(const std::string& filename) {
|
||||
std::ifstream binary(filename, std::ios::in | std::ios::binary);
|
||||
|
||||
@ -70,6 +87,251 @@ const void* VectorStream::read_at(uint64_t offset, uint64_t size, bool throw_err
|
||||
return this->binary_.data() + offset;
|
||||
}
|
||||
|
||||
|
||||
result<size_t> VectorStream::asn1_read_tag(int tag) {
|
||||
size_t out = 0;
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_asn1_get_tag(&p, end, &out, tag);
|
||||
|
||||
if (ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA) {
|
||||
return make_error_code(lief_errors::read_out_of_bound);
|
||||
}
|
||||
else if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
return make_error_code(lief_errors::asn1_bad_tag);
|
||||
}
|
||||
else if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return out;
|
||||
}
|
||||
|
||||
result<size_t> VectorStream::asn1_peek_len() {
|
||||
const uint64_t pos = this->pos();
|
||||
auto len = this->asn1_read_len();
|
||||
this->setpos(pos);
|
||||
return len;
|
||||
}
|
||||
|
||||
result<size_t> VectorStream::asn1_read_len() {
|
||||
size_t len = 0;
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_asn1_get_len(&p, end, &len);
|
||||
|
||||
if (ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA) {
|
||||
return make_error_code(lief_errors::read_out_of_bound);
|
||||
}
|
||||
else if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return len;
|
||||
}
|
||||
|
||||
result<std::string> VectorStream::asn1_read_alg() {
|
||||
mbedtls_asn1_buf alg_oid;
|
||||
char oid_str[256] = {0};
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_asn1_get_alg_null(&p, end, &alg_oid);
|
||||
|
||||
if (ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA) {
|
||||
return make_error_code(lief_errors::read_out_of_bound);
|
||||
}
|
||||
else if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
ret = mbedtls_oid_get_numeric_string(oid_str, sizeof(oid_str), &alg_oid);
|
||||
if (ret <= 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return std::string(oid_str);
|
||||
}
|
||||
|
||||
result<std::string> VectorStream::asn1_read_oid() {
|
||||
mbedtls_asn1_buf buf;
|
||||
char oid_str[256] = {0};
|
||||
|
||||
auto len = this->asn1_read_tag(MBEDTLS_ASN1_OID);
|
||||
if (not len) {
|
||||
return len.error();
|
||||
}
|
||||
|
||||
buf.len = len.value();
|
||||
buf.p = this->p();
|
||||
buf.tag = MBEDTLS_ASN1_OID;
|
||||
|
||||
int ret = mbedtls_oid_get_numeric_string(oid_str, sizeof(oid_str), &buf);
|
||||
if (ret == MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
|
||||
LIEF_DEBUG("asn1_read_oid: mbedtls_oid_get_numeric_string return MBEDTLS_ERR_OID_BUF_TOO_SMALL");
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(buf.len);
|
||||
return std::string(oid_str);
|
||||
}
|
||||
|
||||
|
||||
result<int32_t> VectorStream::asn1_read_int() {
|
||||
int32_t value = 0;
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_asn1_get_int(&p, end, &value);
|
||||
|
||||
if (ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA) {
|
||||
return make_error_code(lief_errors::read_out_of_bound);
|
||||
}
|
||||
else if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return value;
|
||||
}
|
||||
|
||||
result<std::vector<uint8_t>> VectorStream::asn1_read_bitstring() {
|
||||
mbedtls_asn1_bitstring bs = {0, 0, nullptr};
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_asn1_get_bitstring(&p, end, &bs);
|
||||
|
||||
if (ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA) {
|
||||
return make_error_code(lief_errors::read_out_of_bound);
|
||||
}
|
||||
else if (ret == MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) {
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return std::vector<uint8_t>{bs.p, bs.p + bs.len};
|
||||
}
|
||||
else if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return std::vector<uint8_t>{bs.p, bs.p + bs.len};
|
||||
}
|
||||
|
||||
|
||||
result<std::vector<uint8_t>> VectorStream::asn1_read_octet_string() {
|
||||
auto tag = this->asn1_read_tag(MBEDTLS_ASN1_OCTET_STRING);
|
||||
if (not tag) {
|
||||
return tag.error();
|
||||
}
|
||||
std::vector<uint8_t> raw = {this->p(), this->p() + tag.value()};
|
||||
this->increment_pos(tag.value());
|
||||
return raw;
|
||||
}
|
||||
|
||||
result<std::unique_ptr<mbedtls_x509_crt>> VectorStream::asn1_read_cert() {
|
||||
std::unique_ptr<mbedtls_x509_crt> ca{new mbedtls_x509_crt{}};
|
||||
mbedtls_x509_crt_init(ca.get());
|
||||
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
const uintptr_t buff_len = reinterpret_cast<uintptr_t>(end) - reinterpret_cast<uintptr_t>(p);
|
||||
|
||||
int ret = mbedtls_x509_crt_parse_der(ca.get(), p, /* buff len */ buff_len);
|
||||
if (ret != 0) {
|
||||
LIEF_DEBUG("asn1_read_cert(): {:x}", ret);
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
if (ca->raw.len <= 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
this->increment_pos(ca->raw.len);
|
||||
return ca;
|
||||
}
|
||||
|
||||
result<std::string> VectorStream::x509_read_names() {
|
||||
mbedtls_x509_name name;
|
||||
std::memset(&name, 0, sizeof(name));
|
||||
|
||||
auto tag = this->asn1_read_tag(/* Name */
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (not tag) {
|
||||
LIEF_INFO("Wrong tag: 0x{:x} for x509_read_names (pos: {:d})",
|
||||
this->peek<uint8_t>(), this->pos());
|
||||
return tag.error();
|
||||
}
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = p + tag.value();
|
||||
int ret = mbedtls_x509_get_name(&p, end, &name);
|
||||
if (ret != 0) {
|
||||
free_names(name);
|
||||
LIEF_DEBUG("mbedtls_x509_get_name failed with {:d}", ret);
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
char buffer[1024];
|
||||
ret = mbedtls_x509_dn_gets(buffer, sizeof(buffer), &name);
|
||||
free_names(name);
|
||||
|
||||
if (ret < 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
result<std::vector<uint8_t>> VectorStream::x509_read_serial() {
|
||||
mbedtls_x509_buf serial;
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_x509_get_serial(&p, end, &serial);
|
||||
|
||||
if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return std::vector<uint8_t>{serial.p, serial.p + serial.len};
|
||||
}
|
||||
|
||||
result<std::unique_ptr<mbedtls_x509_time>> VectorStream::x509_read_time() {
|
||||
std::unique_ptr<mbedtls_x509_time> tm{new mbedtls_x509_time{}};
|
||||
|
||||
const uint8_t* cur_p = this->p();
|
||||
uint8_t* p = this->p();
|
||||
const uint8_t* end = this->end();
|
||||
|
||||
int ret = mbedtls_x509_get_time(&p, end, tm.get());
|
||||
|
||||
if (ret != 0) {
|
||||
return make_error_code(lief_errors::read_error);
|
||||
}
|
||||
|
||||
this->increment_pos(reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(cur_p));
|
||||
return std::move(tm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::vector<uint8_t>& VectorStream::content(void) const {
|
||||
return this->binary_;
|
||||
}
|
||||
|
@ -21,10 +21,12 @@
|
||||
#include <limits>
|
||||
|
||||
#include "logging.hpp"
|
||||
#include "hash_stream.hpp"
|
||||
|
||||
#include "LIEF/exception.hpp"
|
||||
#include "LIEF/utils.hpp"
|
||||
#include "LIEF/BinaryStream/VectorStream.hpp"
|
||||
#include "LIEF/iostream.hpp"
|
||||
|
||||
#include "LIEF/Abstract/Relocation.hpp"
|
||||
|
||||
@ -98,7 +100,6 @@ Binary::Binary(void) :
|
||||
has_rich_header_{false},
|
||||
has_tls_{false},
|
||||
has_imports_{false},
|
||||
has_signature_{false},
|
||||
has_exports_{false},
|
||||
has_resources_{false},
|
||||
has_exceptions_{false},
|
||||
@ -347,8 +348,8 @@ bool Binary::has_imports(void) const {
|
||||
return this->has_imports_;
|
||||
}
|
||||
|
||||
bool Binary::has_signature(void) const {
|
||||
return this->has_signature_;
|
||||
bool Binary::has_signatures(void) const {
|
||||
return not this->signatures_.empty();
|
||||
}
|
||||
|
||||
bool Binary::has_exports(void) const {
|
||||
@ -1011,8 +1012,228 @@ const debug_entries_t& Binary::debug(void) const {
|
||||
//
|
||||
/////////////////////
|
||||
|
||||
const Signature& Binary::signature(void) const {
|
||||
return this->signature_;
|
||||
it_const_signatures Binary::signatures(void) const {
|
||||
return this->signatures_;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Binary::authentihash(ALGORITHMS algo) const {
|
||||
static const std::map<ALGORITHMS, hashstream::HASH> HMAP = {
|
||||
{ALGORITHMS::MD5, hashstream::HASH::MD5},
|
||||
{ALGORITHMS::SHA_1, hashstream::HASH::SHA1},
|
||||
{ALGORITHMS::SHA_256, hashstream::HASH::SHA256},
|
||||
{ALGORITHMS::SHA_384, hashstream::HASH::SHA384},
|
||||
{ALGORITHMS::SHA_512, hashstream::HASH::SHA512},
|
||||
};
|
||||
auto it_hash = HMAP.find(algo);
|
||||
if (it_hash == std::end(HMAP)) {
|
||||
LIEF_WARN("Unsupported hash algorithm: {}", to_string(algo));
|
||||
return {};
|
||||
}
|
||||
const size_t sizeof_ptr = this->type_ == PE_TYPE::PE32 ? sizeof(uint32_t) : sizeof(uint64_t);
|
||||
const hashstream::HASH hash_type = it_hash->second;
|
||||
hashstream ios(hash_type);
|
||||
//vector_iostream ios;
|
||||
ios // Hash dos header
|
||||
.write(this->dos_header_.magic())
|
||||
.write(this->dos_header_.used_bytes_in_the_last_page())
|
||||
.write(this->dos_header_.file_size_in_pages())
|
||||
.write(this->dos_header_.numberof_relocation())
|
||||
.write(this->dos_header_.header_size_in_paragraphs())
|
||||
.write(this->dos_header_.minimum_extra_paragraphs())
|
||||
.write(this->dos_header_.maximum_extra_paragraphs())
|
||||
.write(this->dos_header_.initial_relative_ss())
|
||||
.write(this->dos_header_.initial_sp())
|
||||
.write(this->dos_header_.checksum())
|
||||
.write(this->dos_header_.initial_ip())
|
||||
.write(this->dos_header_.initial_relative_cs())
|
||||
.write(this->dos_header_.addressof_relocation_table())
|
||||
.write(this->dos_header_.overlay_number())
|
||||
.write(this->dos_header_.reserved())
|
||||
.write(this->dos_header_.oem_id())
|
||||
.write(this->dos_header_.oem_info())
|
||||
.write(this->dos_header_.reserved2())
|
||||
.write(this->dos_header_.addressof_new_exeheader())
|
||||
.write(this->dos_stub_);
|
||||
|
||||
ios // Hash PE Header
|
||||
.write(this->header_.signature())
|
||||
.write(static_cast<uint16_t>(this->header_.machine()))
|
||||
.write(this->header_.numberof_sections())
|
||||
.write(this->header_.time_date_stamp())
|
||||
.write(this->header_.pointerto_symbol_table())
|
||||
.write(this->header_.numberof_symbols())
|
||||
.write(this->header_.sizeof_optional_header())
|
||||
.write(static_cast<uint16_t>(this->header_.characteristics()));
|
||||
|
||||
ios // Hash OptionalHeader
|
||||
.write(static_cast<uint16_t>(this->optional_header_.magic()))
|
||||
.write(this->optional_header_.major_linker_version())
|
||||
.write(this->optional_header_.minor_linker_version())
|
||||
.write(this->optional_header_.sizeof_code())
|
||||
.write(this->optional_header_.sizeof_initialized_data())
|
||||
.write(this->optional_header_.sizeof_uninitialized_data())
|
||||
.write(this->optional_header_.addressof_entrypoint())
|
||||
.write(this->optional_header_.baseof_code());
|
||||
|
||||
if (this->type_ == PE_TYPE::PE32) {
|
||||
ios.write(this->optional_header_.baseof_data());
|
||||
}
|
||||
ios // Continuation of optional header
|
||||
.write_sized_int(this->optional_header_.imagebase(), sizeof_ptr)
|
||||
.write(this->optional_header_.section_alignment())
|
||||
.write(this->optional_header_.file_alignment())
|
||||
.write(this->optional_header_.major_operating_system_version())
|
||||
.write(this->optional_header_.minor_operating_system_version())
|
||||
.write(this->optional_header_.major_image_version())
|
||||
.write(this->optional_header_.minor_image_version())
|
||||
.write(this->optional_header_.major_subsystem_version())
|
||||
.write(this->optional_header_.minor_subsystem_version())
|
||||
.write(this->optional_header_.win32_version_value())
|
||||
.write(this->optional_header_.sizeof_image())
|
||||
.write(this->optional_header_.sizeof_headers())
|
||||
// this->optional_header_.checksum()) is not a part of the hash
|
||||
.write(static_cast<uint16_t>(this->optional_header_.subsystem()))
|
||||
.write(static_cast<uint16_t>(this->optional_header_.dll_characteristics()))
|
||||
.write_sized_int(this->optional_header_.sizeof_stack_reserve(), sizeof_ptr)
|
||||
.write_sized_int(this->optional_header_.sizeof_stack_commit(), sizeof_ptr)
|
||||
.write_sized_int(this->optional_header_.sizeof_heap_reserve(), sizeof_ptr)
|
||||
.write_sized_int(this->optional_header_.sizeof_heap_commit(), sizeof_ptr)
|
||||
.write(this->optional_header_.loader_flags())
|
||||
.write(this->optional_header_.numberof_rva_and_size());
|
||||
|
||||
for (const DataDirectory* dir : this->data_directories_) {
|
||||
if (dir->type() == DATA_DIRECTORY::CERTIFICATE_TABLE) {
|
||||
continue;
|
||||
}
|
||||
ios
|
||||
.write(dir->RVA())
|
||||
.write(dir->size());
|
||||
}
|
||||
|
||||
// Empty data directory
|
||||
ios
|
||||
.write<uint32_t>(0)
|
||||
.write<uint32_t>(0);
|
||||
|
||||
for (const Section* sec : this->sections_) {
|
||||
std::array<char, 8> name = {0};
|
||||
const std::string& sec_name = sec->name();
|
||||
uint32_t name_length = std::min<uint32_t>(sec_name.size() + 1, sizeof(name));
|
||||
std::copy(sec_name.c_str(), sec_name.c_str() + name_length, std::begin(name));
|
||||
ios
|
||||
.write(name)
|
||||
.write(sec->virtual_size())
|
||||
.write<uint32_t>(sec->virtual_address())
|
||||
.write(sec->sizeof_raw_data())
|
||||
.write(sec->pointerto_raw_data())
|
||||
.write(sec->pointerto_relocation())
|
||||
.write(sec->pointerto_line_numbers())
|
||||
.write(sec->numberof_relocations())
|
||||
.write(sec->numberof_line_numbers())
|
||||
.write(static_cast<uint32_t>(sec->characteristics()));
|
||||
}
|
||||
//LIEF_DEBUG("Section padding at 0x{:x}", ios.tellp());
|
||||
ios.write(this->section_offset_padding_);
|
||||
|
||||
std::vector<Section*> sections = this->sections_;
|
||||
|
||||
// Sort by file offset
|
||||
std::sort(
|
||||
std::begin(sections),
|
||||
std::end(sections),
|
||||
[] (const Section* lhs, const Section* rhs) {
|
||||
return lhs->pointerto_raw_data() < rhs->pointerto_raw_data();
|
||||
});
|
||||
|
||||
uint64_t position = 0;
|
||||
for (const Section* sec : sections) {
|
||||
const std::vector<uint8_t>& pad = sec->padding();
|
||||
const std::vector<uint8_t>& content = sec->content();
|
||||
LIEF_DEBUG("Authentihash: Append section {:<8}: [0x{:04x}, 0x{:04x}] + [0x{:04x}] = [0x{:04x}, 0x{:04x}]",
|
||||
sec->name(),
|
||||
sec->offset(), sec->offset() + content.size(), pad.size(),
|
||||
sec->offset(), sec->offset() + content.size() + pad.size());
|
||||
if (/* overlapping */ sec->offset() < position) {
|
||||
// Trunc the beginning of the overlap
|
||||
if (position <= sec->offset() + content.size()) {
|
||||
const uint64_t start_p = position - sec->offset();
|
||||
const uint64_t size = content.size() - start_p;
|
||||
ios
|
||||
.write(content.data() + start_p, size)
|
||||
.write(pad);
|
||||
} else {
|
||||
LIEF_WARN("Overlapping in the padding area");
|
||||
}
|
||||
} else {
|
||||
ios
|
||||
.write(content)
|
||||
.write(pad);
|
||||
}
|
||||
position = sec->offset() + content.size() + pad.size();
|
||||
}
|
||||
if (this->overlay_.size() > 0) {
|
||||
const DataDirectory& cert_dir = this->data_directory(DATA_DIRECTORY::CERTIFICATE_TABLE);
|
||||
LIEF_DEBUG("Add overlay and omit 0x{:08x} - 0x{:08x}", cert_dir.RVA(), cert_dir.RVA() + cert_dir.size());
|
||||
if (cert_dir.RVA() > 0 and cert_dir.size() > 0) {
|
||||
const uint64_t start_cert_offset = cert_dir.RVA() - this->overlay_offset_;
|
||||
const uint64_t end_cert_offset = start_cert_offset + cert_dir.size();
|
||||
LIEF_DEBUG("Add [0x{:x}, 0x{:x}]", this->overlay_offset_, this->overlay_offset_ + start_cert_offset);
|
||||
LIEF_DEBUG("Add [0x{:x}, 0x{:x}]",
|
||||
this->overlay_offset_ + end_cert_offset, this->overlay_offset_ + this->overlay_.size() - end_cert_offset);
|
||||
ios
|
||||
.write(this->overlay_.data(), start_cert_offset)
|
||||
.write(this->overlay_.data() + end_cert_offset, this->overlay_.size() - end_cert_offset);
|
||||
}
|
||||
}
|
||||
//ios.write(this->overlay_);
|
||||
// When something gets wrong with the hash:
|
||||
// std::vector<uint8_t> out = ios.raw();
|
||||
// std::ofstream output_file{"/tmp/hash.blob", std::ios::out | std::ios::binary | std::ios::trunc};
|
||||
// if (output_file) {
|
||||
// std::copy(
|
||||
// std::begin(out),
|
||||
// std::end(out),
|
||||
// std::ostreambuf_iterator<char>(output_file));
|
||||
// }
|
||||
// std::vector<uint8_t> hash = hashstream(hash_type).write(out).raw();
|
||||
|
||||
std::vector<uint8_t> hash = ios.raw();
|
||||
LIEF_DEBUG("{}", hex_dump(hash));
|
||||
return hash;
|
||||
}
|
||||
|
||||
Signature::VERIFICATION_FLAGS Binary::verify_signature() const {
|
||||
if (not this->has_signatures()) {
|
||||
return Signature::VERIFICATION_FLAGS::NO_SIGNATURE;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < this->signatures_.size(); ++i) {
|
||||
const Signature& sig = this->signatures_[i];
|
||||
Signature::VERIFICATION_FLAGS flags = this->verify_signature(sig);
|
||||
if (flags != Signature::VERIFICATION_FLAGS::OK) {
|
||||
LIEF_INFO("Verification failed for signature #{:d} (0b{:b})", i, static_cast<uintptr_t>(flags));
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
return Signature::VERIFICATION_FLAGS::OK;
|
||||
}
|
||||
|
||||
Signature::VERIFICATION_FLAGS Binary::verify_signature(const Signature& sig) const {
|
||||
const Signature::VERIFICATION_FLAGS value = sig.check();
|
||||
if (value != Signature::VERIFICATION_FLAGS::OK) {
|
||||
LIEF_INFO("Bad signature (0b{:b})", static_cast<uintptr_t>(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
// Check that the authentihash matches Content Info's digest
|
||||
const std::vector<uint8_t>& authhash = this->authentihash(sig.digest_algorithm());
|
||||
const std::vector<uint8_t>& chash = sig.content_info().digest();
|
||||
if (authhash != chash) {
|
||||
LIEF_INFO("Authentihash and Content info's digest does not match:\n {}\n {}",
|
||||
hex_dump(authhash), hex_dump(chash));
|
||||
return Signature::VERIFICATION_FLAGS::BAD_SIGNATURE;
|
||||
}
|
||||
return Signature::VERIFICATION_FLAGS::OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1407,10 +1628,12 @@ std::ostream& Binary::print(std::ostream& os) const {
|
||||
}
|
||||
|
||||
|
||||
if (this->has_signature()) {
|
||||
os << "Signature" << std::endl;
|
||||
os << "=========" << std::endl;
|
||||
os << this->signature() << std::endl;
|
||||
if (this->has_signatures()) {
|
||||
os << "Signatures" << std::endl;
|
||||
os << "==========" << std::endl;
|
||||
for (const Signature& sig : this->signatures_) {
|
||||
os << sig << std::endl;
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
|
@ -444,33 +444,33 @@ void Builder::build_overlay(void) {
|
||||
|
||||
Builder& Builder::operator<<(const DosHeader& dos_header) {
|
||||
|
||||
pe_dos_header dosHeader;
|
||||
dosHeader.Magic = static_cast<uint16_t>(dos_header.magic());
|
||||
dosHeader.UsedBytesInTheLastPage = static_cast<uint16_t>(dos_header.used_bytes_in_the_last_page());
|
||||
dosHeader.FileSizeInPages = static_cast<uint16_t>(dos_header.file_size_in_pages());
|
||||
dosHeader.NumberOfRelocationItems = static_cast<uint16_t>(dos_header.numberof_relocation());
|
||||
dosHeader.HeaderSizeInParagraphs = static_cast<uint16_t>(dos_header.header_size_in_paragraphs());
|
||||
dosHeader.MinimumExtraParagraphs = static_cast<uint16_t>(dos_header.minimum_extra_paragraphs());
|
||||
dosHeader.MaximumExtraParagraphs = static_cast<uint16_t>(dos_header.maximum_extra_paragraphs());
|
||||
dosHeader.InitialRelativeSS = static_cast<uint16_t>(dos_header.initial_relative_ss());
|
||||
dosHeader.InitialSP = static_cast<uint16_t>(dos_header.initial_sp());
|
||||
dosHeader.Checksum = static_cast<uint16_t>(dos_header.checksum());
|
||||
dosHeader.InitialIP = static_cast<uint16_t>(dos_header.initial_ip());
|
||||
dosHeader.InitialRelativeCS = static_cast<uint16_t>(dos_header.initial_relative_cs());
|
||||
dosHeader.AddressOfRelocationTable = static_cast<uint16_t>(dos_header.addressof_relocation_table());
|
||||
dosHeader.OverlayNumber = static_cast<uint16_t>(dos_header.overlay_number());
|
||||
dosHeader.OEMid = static_cast<uint16_t>(dos_header.oem_id());
|
||||
dosHeader.OEMinfo = static_cast<uint16_t>(dos_header.oem_info());
|
||||
dosHeader.AddressOfNewExeHeader = static_cast<uint16_t>(dos_header.addressof_new_exeheader());
|
||||
pe_dos_header raw_dos_header;
|
||||
raw_dos_header.Magic = static_cast<uint16_t>(dos_header.magic());
|
||||
raw_dos_header.UsedBytesInTheLastPage = static_cast<uint16_t>(dos_header.used_bytes_in_the_last_page());
|
||||
raw_dos_header.FileSizeInPages = static_cast<uint16_t>(dos_header.file_size_in_pages());
|
||||
raw_dos_header.NumberOfRelocationItems = static_cast<uint16_t>(dos_header.numberof_relocation());
|
||||
raw_dos_header.HeaderSizeInParagraphs = static_cast<uint16_t>(dos_header.header_size_in_paragraphs());
|
||||
raw_dos_header.MinimumExtraParagraphs = static_cast<uint16_t>(dos_header.minimum_extra_paragraphs());
|
||||
raw_dos_header.MaximumExtraParagraphs = static_cast<uint16_t>(dos_header.maximum_extra_paragraphs());
|
||||
raw_dos_header.InitialRelativeSS = static_cast<uint16_t>(dos_header.initial_relative_ss());
|
||||
raw_dos_header.InitialSP = static_cast<uint16_t>(dos_header.initial_sp());
|
||||
raw_dos_header.Checksum = static_cast<uint16_t>(dos_header.checksum());
|
||||
raw_dos_header.InitialIP = static_cast<uint16_t>(dos_header.initial_ip());
|
||||
raw_dos_header.InitialRelativeCS = static_cast<uint16_t>(dos_header.initial_relative_cs());
|
||||
raw_dos_header.AddressOfRelocationTable = static_cast<uint16_t>(dos_header.addressof_relocation_table());
|
||||
raw_dos_header.OverlayNumber = static_cast<uint16_t>(dos_header.overlay_number());
|
||||
raw_dos_header.OEMid = static_cast<uint16_t>(dos_header.oem_id());
|
||||
raw_dos_header.OEMinfo = static_cast<uint16_t>(dos_header.oem_info());
|
||||
raw_dos_header.AddressOfNewExeHeader = static_cast<uint16_t>(dos_header.addressof_new_exeheader());
|
||||
|
||||
const DosHeader::reserved_t& reserved = dos_header.reserved();
|
||||
const DosHeader::reserved2_t& reserved2 = dos_header.reserved2();
|
||||
|
||||
std::copy(std::begin(reserved), std::end(reserved), std::begin(dosHeader.Reserved));
|
||||
std::copy(std::begin(reserved2), std::end(reserved2), std::begin(dosHeader.Reserved2));
|
||||
std::copy(std::begin(reserved), std::end(reserved), std::begin(raw_dos_header.Reserved));
|
||||
std::copy(std::begin(reserved2), std::end(reserved2), std::begin(raw_dos_header.Reserved2));
|
||||
|
||||
this->ios_.seekp(0);
|
||||
this->ios_.write(reinterpret_cast<const uint8_t*>(&dosHeader), sizeof(pe_dos_header));
|
||||
this->ios_.write(reinterpret_cast<const uint8_t*>(&raw_dos_header), sizeof(pe_dos_header));
|
||||
if (this->binary_->dos_stub().size() > 0 and this->build_dos_stub_) {
|
||||
|
||||
if (sizeof(pe_dos_header) + this->binary_->dos_stub().size() > dos_header.addressof_new_exeheader()) {
|
||||
|
@ -29,13 +29,6 @@ set(LIEF_PE_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RelocationEntry.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DataDirectory.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/CodeIntegrity.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/AuthenticatedAttributes.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/ContentInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/Signature.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/SignerInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/x509.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/OIDToString.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/signature/SignatureParser.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Builder.tcc"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Parser.tcc"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/resources/ResourceVersion.cpp"
|
||||
@ -125,7 +118,7 @@ set(LIEF_PE_INCLUDE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/ResourceNode.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/ResourcesManager.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Section.hpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/PE/Structures.hpp" # Do we want to do this since it's autogenerated?
|
||||
#"${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/PE/Structures.hpp" # Do we want to do this since it's autogenerated?
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Symbol.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/TLS.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/type_traits.hpp"
|
||||
@ -146,18 +139,6 @@ set(LIEF_PE_LOAD_CONFIGURATION_INCLUDE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/LoadConfigurations/LoadConfigurationV7.hpp"
|
||||
)
|
||||
|
||||
set(LIEF_PE_SIG_INCLUDE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/AuthenticatedAttributes.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/ContentInfo.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/OIDToString.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/Signature.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/SignatureParser.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/SignerInfo.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/types.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/x509.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/PE/signature/pkcs7.h"
|
||||
)
|
||||
|
||||
set(LIEF_PE_RESOURCES_INCLUDE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/resources/ResourceVersion.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/resources/ResourceDialog.hpp"
|
||||
@ -199,7 +180,6 @@ list(APPEND LIEF_PE_INCLUDE_FILES ${LIEF_PE_HASH_HDR})
|
||||
source_group("Source Files\\PE" FILES ${LIEF_PE_SRC})
|
||||
source_group("Source Files\\PE\\Load Configure" FILES ${LIEF_PE_LOAD_CONFIGURATION_SRC})
|
||||
source_group("Header Files\\PE" FILES ${LIEF_PE_INCLUDE_FILES})
|
||||
source_group("Header Files\\PE\\signature" FILES ${LIEF_PE_SIG_INCLUDE_FILES})
|
||||
source_group("Header Files\\PE\\resources" FILES ${LIEF_PE_RESOURCES_INCLUDE_FILES})
|
||||
source_group("Header Files\\PE\\Load Configuration" FILES ${LIEF_PE_LOAD_CONFIGURATION_INCLUDE})
|
||||
source_group("Header Files\\PE\\utils\\Ordinals Lookup Tables" FILES ${LIEF_PE_UTILS_INCLUDE_FILES})
|
||||
@ -215,3 +195,5 @@ if (LIEF_PE)
|
||||
${LIEF_PE_LOAD_CONFIGURATION_INCLUDE}
|
||||
)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/signature/CMakeLists.txt")
|
||||
|
@ -1337,5 +1337,54 @@ const char* to_string(ACCELERATOR_VK_CODES e) {
|
||||
return it != enumStrings.end() ? it->second : "Undefined or reserved";
|
||||
}
|
||||
|
||||
const char* to_string(ALGORITHMS e) {
|
||||
CONST_MAP(ALGORITHMS, const char*, 20) enumStrings {
|
||||
{ ALGORITHMS::UNKNOWN, "UNKNOWN" },
|
||||
{ ALGORITHMS::SHA_512, "SHA_512" },
|
||||
{ ALGORITHMS::SHA_384, "SHA_384" },
|
||||
{ ALGORITHMS::SHA_256, "SHA_256" },
|
||||
{ ALGORITHMS::SHA_1, "SHA_1" },
|
||||
|
||||
{ ALGORITHMS::MD5, "MD5" },
|
||||
{ ALGORITHMS::MD4, "MD4" },
|
||||
{ ALGORITHMS::MD2, "MD2" },
|
||||
|
||||
{ ALGORITHMS::RSA, "RSA" },
|
||||
{ ALGORITHMS::EC, "EC" },
|
||||
|
||||
{ ALGORITHMS::MD5_RSA, "MD5_RSA" },
|
||||
{ ALGORITHMS::SHA1_DSA, "SHA1_DSA" },
|
||||
{ ALGORITHMS::SHA1_RSA, "SHA1_RSA" },
|
||||
{ ALGORITHMS::SHA_256_RSA, "SHA_256_RSA" },
|
||||
{ ALGORITHMS::SHA_384_RSA, "SHA_384_RSA" },
|
||||
{ ALGORITHMS::SHA_512_RSA, "SHA_512_RSA" },
|
||||
{ ALGORITHMS::SHA1_ECDSA, "SHA1_ECDSA" },
|
||||
{ ALGORITHMS::SHA_256_ECDSA, "SHA_256_ECDSA" },
|
||||
{ ALGORITHMS::SHA_384_ECDSA, "SHA_384_ECDSA" },
|
||||
{ ALGORITHMS::SHA_512_ECDSA, "SHA_512_ECDSA" },
|
||||
};
|
||||
auto it = enumStrings.find(e);
|
||||
return it == enumStrings.end() ? "UNKNOWN" : it->second;
|
||||
}
|
||||
|
||||
|
||||
const char* to_string(SIG_ATTRIBUTE_TYPES e) {
|
||||
CONST_MAP(SIG_ATTRIBUTE_TYPES, const char*, 11) enumStrings {
|
||||
{ SIG_ATTRIBUTE_TYPES::UNKNOWN, "UNKNOWN" },
|
||||
{ SIG_ATTRIBUTE_TYPES::CONTENT_TYPE, "CONTENT_TYPE" },
|
||||
{ SIG_ATTRIBUTE_TYPES::GENERIC_TYPE, "GENERIC_TYPE" },
|
||||
{ SIG_ATTRIBUTE_TYPES::SPC_SP_OPUS_INFO, "SPC_SP_OPUS_INFO" },
|
||||
{ SIG_ATTRIBUTE_TYPES::MS_COUNTER_SIGN, "MS_COUNTER_SIGN" },
|
||||
{ SIG_ATTRIBUTE_TYPES::MS_SPC_NESTED_SIGN, "MS_SPC_NESTED_SIGN" },
|
||||
{ SIG_ATTRIBUTE_TYPES::MS_SPC_STATEMENT_TYPE, "MS_SPC_STATEMENT_TYPE" },
|
||||
{ SIG_ATTRIBUTE_TYPES::PKCS9_AT_SEQUENCE_NUMBER, "PKCS9_AT_SEQUENCE_NUMBER" },
|
||||
{ SIG_ATTRIBUTE_TYPES::PKCS9_COUNTER_SIGNATURE, "PKCS9_COUNTER_SIGNATURE" },
|
||||
{ SIG_ATTRIBUTE_TYPES::PKCS9_MESSAGE_DIGEST, "PKCS9_MESSAGE_DIGEST" },
|
||||
{ SIG_ATTRIBUTE_TYPES::PKCS9_SIGNING_TIME, "PKCS9_SIGNING_TIME" },
|
||||
};
|
||||
auto it = enumStrings.find(e);
|
||||
return it == enumStrings.end() ? "UNKNOWN" : it->second;
|
||||
}
|
||||
|
||||
} // namespace PE
|
||||
} // namespace LIEF
|
||||
|
@ -115,7 +115,7 @@ void Parser::parse_dos_stub(void) {
|
||||
}
|
||||
const uint64_t sizeof_dos_stub = dos_header.addressof_new_exeheader() - sizeof(pe_dos_header);
|
||||
|
||||
LIEF_DEBUG("DOS Stub size: 0x{:x}", sizeof_dos_stub);
|
||||
LIEF_DEBUG("DOS stub: @0x{:x}:0x{:x}", sizeof(pe_dos_header), sizeof_dos_stub);
|
||||
|
||||
const uint8_t* ptr_to_dos_stub = this->stream_->peek_array<uint8_t>(sizeof(pe_dos_header), sizeof_dos_stub, /* check */false);
|
||||
if (ptr_to_dos_stub == nullptr) {
|
||||
@ -224,7 +224,9 @@ void Parser::parse_sections(void) {
|
||||
|
||||
uint32_t size_to_read = 0;
|
||||
uint32_t offset = sections[i].PointerToRawData;
|
||||
first_section_offset = std::min(first_section_offset, offset);
|
||||
if (offset > 0) {
|
||||
first_section_offset = std::min(first_section_offset, offset);
|
||||
}
|
||||
|
||||
if (sections[i].VirtualSize > 0) {
|
||||
size_to_read = std::min(sections[i].VirtualSize, sections[i].SizeOfRawData); // According to Corkami
|
||||
@ -250,10 +252,22 @@ void Parser::parse_sections(void) {
|
||||
ptr_to_rawdata + size_to_read
|
||||
};
|
||||
}
|
||||
const uint64_t padding_size = section->size() - size_to_read;
|
||||
const uint8_t* ptr_to_padding = this->stream_->peek_array<uint8_t>(offset + size_to_read, padding_size, /* check */false);
|
||||
if (ptr_to_padding != nullptr) {
|
||||
section->padding_ = {ptr_to_padding, ptr_to_padding + padding_size};
|
||||
}
|
||||
}
|
||||
this->binary_->sections_.push_back(section.release());
|
||||
}
|
||||
|
||||
const uint32_t last_section_header_offset = sections_offset + numberof_sections * sizeof(pe_section);
|
||||
const size_t padding_size = first_section_offset - last_section_header_offset;
|
||||
const uint8_t* padding_ptr = this->stream_->peek_array<uint8_t>(last_section_header_offset, padding_size,
|
||||
/* check */ false);
|
||||
if (padding_ptr != nullptr) {
|
||||
this->binary_->section_offset_padding_ = {padding_ptr, padding_ptr + padding_size};
|
||||
}
|
||||
this->binary_->available_sections_space_ = (first_section_offset - last_section_header_offset) / sizeof(pe_section) - 1;
|
||||
LIEF_DEBUG("Number of sections that could be added: #{:d}", this->binary_->available_sections_space_);
|
||||
}
|
||||
@ -865,23 +879,41 @@ void Parser::parse_exports(void) {
|
||||
|
||||
void Parser::parse_signature(void) {
|
||||
LIEF_DEBUG("== Parsing signature ==");
|
||||
static constexpr size_t SIZEOF_HEADER = 8;
|
||||
|
||||
/*** /!\ In this data directory, RVA is used as an **OFFSET** /!\ ****/
|
||||
/*********************************************************************/
|
||||
const uint32_t signature_offset = this->binary_->data_directory(DATA_DIRECTORY::CERTIFICATE_TABLE).RVA();
|
||||
const uint32_t signature_size = this->binary_->data_directory(DATA_DIRECTORY::CERTIFICATE_TABLE).size();
|
||||
const uint64_t end_p = signature_offset + signature_size;
|
||||
LIEF_DEBUG("Signature Offset: 0x{:04x}", signature_offset);
|
||||
LIEF_DEBUG("Signature Size: 0x{:04x}", signature_size);
|
||||
|
||||
const uint8_t* signature_ptr = this->stream_->peek_array<uint8_t>(signature_offset, signature_size, /* check */false);
|
||||
if (signature_ptr == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::vector<uint8_t> raw_signature = {signature_ptr, signature_ptr + signature_size};
|
||||
this->stream_->setpos(signature_offset);
|
||||
while (this->stream_->pos() < end_p) {
|
||||
const uint64_t current_p = this->stream_->pos();
|
||||
auto length = this->stream_->read<uint32_t>();
|
||||
auto revision = this->stream_->read<uint16_t>();
|
||||
auto certificate_type = this->stream_->read<uint16_t>();
|
||||
LIEF_DEBUG("Signature {}r0x{:x} (0x{:x} bytes)", certificate_type, revision, length);
|
||||
const uint8_t* data_ptr = this->stream_->read_array<uint8_t>(length - SIZEOF_HEADER, /* check */false);
|
||||
if (data_ptr == nullptr) {
|
||||
LIEF_INFO("Can't read 0x{:x} bytes", length);
|
||||
break;
|
||||
}
|
||||
std::vector<uint8_t> raw_signature = {data_ptr, data_ptr + length - SIZEOF_HEADER};
|
||||
auto sign = SignatureParser::parse(std::move(raw_signature));
|
||||
|
||||
//TODO: Deal with header (+8)
|
||||
this->binary_->signature_ = SignatureParser::parse(raw_signature);
|
||||
this->binary_->has_signature_ = true;
|
||||
if (sign) {
|
||||
this->binary_->signatures_.push_back(std::move(sign.value()));
|
||||
} else {
|
||||
LIEF_INFO("Unable to parse the signature");
|
||||
}
|
||||
this->stream_->align(8);
|
||||
if (this->stream_->pos() <= current_p) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -907,6 +939,7 @@ void Parser::parse_overlay(void) {
|
||||
ptr_to_overlay,
|
||||
ptr_to_overlay + overlay_size
|
||||
};
|
||||
this->binary_->overlay_offset_ = last_section_offset;
|
||||
}
|
||||
} else {
|
||||
this->binary_->overlay_ = {};
|
||||
|
@ -31,28 +31,18 @@ namespace PE {
|
||||
|
||||
Section::~Section(void) = default;
|
||||
|
||||
Section::Section(void) :
|
||||
LIEF::Section{},
|
||||
virtualSize_{0},
|
||||
content_{},
|
||||
pointerToRelocations_{0},
|
||||
pointerToLineNumbers_{0},
|
||||
numberOfRelocations_{0},
|
||||
numberOfLineNumbers_{0},
|
||||
characteristics_{0},
|
||||
types_{PE_SECTION_TYPES::UNKNOWN}
|
||||
{}
|
||||
Section::Section(void) = default;
|
||||
|
||||
|
||||
Section& Section::operator=(const Section&) = default;
|
||||
Section::Section(const Section&) = default;
|
||||
|
||||
Section::Section(const pe_section* header) :
|
||||
virtualSize_{header->VirtualSize},
|
||||
pointerToRelocations_{header->PointerToRelocations},
|
||||
pointerToLineNumbers_{header->PointerToLineNumbers},
|
||||
numberOfRelocations_{header->NumberOfRelocations},
|
||||
numberOfLineNumbers_{header->NumberOfLineNumbers},
|
||||
virtual_size_{header->VirtualSize},
|
||||
pointer_to_relocations_{header->PointerToRelocations},
|
||||
pointer_to_linenumbers_{header->PointerToLineNumbers},
|
||||
number_of_relocations_{header->NumberOfRelocations},
|
||||
number_of_linenumbers_{header->NumberOfLineNumbers},
|
||||
characteristics_{header->Characteristics},
|
||||
types_{PE_SECTION_TYPES::UNKNOWN}
|
||||
{
|
||||
@ -60,7 +50,6 @@ Section::Section(const pe_section* header) :
|
||||
this->virtual_address_ = header->VirtualAddress;
|
||||
this->size_ = header->SizeOfRawData;
|
||||
this->offset_ = header->PointerToRawData;
|
||||
|
||||
}
|
||||
|
||||
Section::Section(const std::vector<uint8_t>& data, const std::string& name, uint32_t characteristics) :
|
||||
@ -80,7 +69,7 @@ Section::Section(const std::string& name) :
|
||||
|
||||
|
||||
uint32_t Section::virtual_size(void) const {
|
||||
return this->virtualSize_;
|
||||
return this->virtual_size_;
|
||||
}
|
||||
|
||||
|
||||
@ -103,20 +92,20 @@ uint32_t Section::pointerto_raw_data(void) const {
|
||||
|
||||
|
||||
uint32_t Section::pointerto_relocation(void) const {
|
||||
return this->pointerToRelocations_;
|
||||
return this->pointer_to_relocations_;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Section::pointerto_line_numbers(void) const {
|
||||
return this->pointerToLineNumbers_;
|
||||
return this->pointer_to_linenumbers_;
|
||||
}
|
||||
|
||||
uint16_t Section::numberof_relocations(void) const {
|
||||
return this->numberOfRelocations_;
|
||||
return this->number_of_relocations_;
|
||||
}
|
||||
|
||||
uint16_t Section::numberof_line_numbers(void) const {
|
||||
return this->numberOfLineNumbers_;
|
||||
return this->number_of_linenumbers_;
|
||||
}
|
||||
|
||||
uint32_t Section::characteristics(void) const {
|
||||
@ -164,7 +153,7 @@ void Section::content(const std::vector<uint8_t>& data) {
|
||||
|
||||
|
||||
void Section::virtual_size(uint32_t virtualSize) {
|
||||
this->virtualSize_ = virtualSize;
|
||||
this->virtual_size_ = virtualSize;
|
||||
}
|
||||
|
||||
|
||||
@ -174,22 +163,22 @@ void Section::pointerto_raw_data(uint32_t pointerToRawData) {
|
||||
|
||||
|
||||
void Section::pointerto_relocation(uint32_t pointerToRelocation) {
|
||||
this->pointerToRelocations_ = pointerToRelocation;
|
||||
this->pointer_to_relocations_ = pointerToRelocation;
|
||||
}
|
||||
|
||||
|
||||
void Section::pointerto_line_numbers(uint32_t pointerToLineNumbers) {
|
||||
this->pointerToLineNumbers_ = pointerToLineNumbers;
|
||||
this->pointer_to_linenumbers_ = pointerToLineNumbers;
|
||||
}
|
||||
|
||||
|
||||
void Section::numberof_relocations(uint16_t numberOfRelocations) {
|
||||
this->numberOfRelocations_ = numberOfRelocations;
|
||||
this->number_of_relocations_ = numberOfRelocations;
|
||||
}
|
||||
|
||||
|
||||
void Section::numberof_line_numbers(uint16_t numberOfLineNumbers) {
|
||||
this->numberOfLineNumbers_ = numberOfLineNumbers;
|
||||
this->number_of_linenumbers_ = numberOfLineNumbers;
|
||||
}
|
||||
|
||||
void Section::sizeof_raw_data(uint32_t sizeOfRawData) {
|
||||
|
@ -437,17 +437,14 @@ void Hash::visit(const ResourceAccelerator& accelerator) {
|
||||
}
|
||||
|
||||
void Hash::visit(const Signature& signature) {
|
||||
|
||||
this->process(signature.version());
|
||||
this->process(signature.digest_algorithm());
|
||||
this->process(signature.content_info());
|
||||
this->process(std::begin(signature.certificates()), std::end(signature.certificates()));
|
||||
this->process(signature.signer_info());
|
||||
this->process(signature.original_signature());
|
||||
this->process(std::begin(signature.signers()), std::end(signature.signers()));
|
||||
}
|
||||
|
||||
void Hash::visit(const x509& x509) {
|
||||
|
||||
this->process(x509.subject());
|
||||
this->process(x509.issuer());
|
||||
this->process(x509.valid_to());
|
||||
@ -460,19 +457,65 @@ void Hash::visit(const x509& x509) {
|
||||
void Hash::visit(const SignerInfo& signerinfo) {
|
||||
|
||||
this->process(signerinfo.version());
|
||||
//this->process(signerinfo.issuer());
|
||||
this->process(signerinfo.serial_number());
|
||||
this->process(signerinfo.issuer());
|
||||
this->process(signerinfo.encryption_algorithm());
|
||||
this->process(signerinfo.digest_algorithm());
|
||||
this->process(signerinfo.authenticated_attributes());
|
||||
this->process(signerinfo.signature_algorithm());
|
||||
this->process(signerinfo.encrypted_digest());
|
||||
this->process(std::begin(signerinfo.authenticated_attributes()), std::end(signerinfo.authenticated_attributes()));
|
||||
this->process(std::begin(signerinfo.unauthenticated_attributes()), std::end(signerinfo.unauthenticated_attributes()));
|
||||
}
|
||||
|
||||
void Hash::visit(const AuthenticatedAttributes& auth) {
|
||||
void Hash::visit(const Attribute& attr) {
|
||||
this->process(attr.type());
|
||||
}
|
||||
|
||||
this->process(auth.content_type());
|
||||
this->process(auth.message_digest());
|
||||
this->process(u16tou8(auth.program_name()));
|
||||
this->process(auth.more_info());
|
||||
void Hash::visit(const ContentInfo& info) {
|
||||
this->process(info.content_type());
|
||||
this->process(info.digest_algorithm());
|
||||
this->process(info.digest());
|
||||
this->process(info.file());
|
||||
}
|
||||
|
||||
|
||||
void Hash::visit(const ContentType& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.oid());
|
||||
}
|
||||
void Hash::visit(const GenericType& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.raw_content());
|
||||
this->process(attr.oid());
|
||||
}
|
||||
void Hash::visit(const MsSpcNestedSignature& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.sig());
|
||||
}
|
||||
void Hash::visit(const MsSpcStatementType& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.oid());
|
||||
}
|
||||
void Hash::visit(const PKCS9AtSequenceNumber& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.number());
|
||||
}
|
||||
void Hash::visit(const PKCS9CounterSignature& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
it_const_signers_t signers = attr.signers();
|
||||
this->process(std::begin(signers), std::end(signers));
|
||||
}
|
||||
void Hash::visit(const PKCS9MessageDigest& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.digest());
|
||||
}
|
||||
void Hash::visit(const PKCS9SigningTime& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.time());
|
||||
}
|
||||
void Hash::visit(const SpcSpOpusInfo& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->process(attr.program_name());
|
||||
this->process(attr.more_info());
|
||||
}
|
||||
|
||||
void Hash::visit(const CodeIntegrity& code_integrity) {
|
||||
|
129
src/PE/json.cpp
129
src/PE/json.cpp
@ -22,6 +22,8 @@
|
||||
#include "LIEF/PE/json.hpp"
|
||||
#include "LIEF/PE.hpp"
|
||||
|
||||
#include "Object.tcc"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
@ -165,11 +167,15 @@ void JsonVisitor::visit(const Binary& binary) {
|
||||
}
|
||||
|
||||
|
||||
// Signature
|
||||
if (binary.has_signature()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(binary.signature());
|
||||
this->node_["signature"] = visitor.get();
|
||||
// Signatures
|
||||
std::vector<json> sigs;
|
||||
if (binary.has_signatures()) {
|
||||
for (const Signature& sig : binary.signatures()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(sig);
|
||||
sigs.push_back(std::move(visitor.get()));
|
||||
}
|
||||
this->node_["signatures"] = sigs;
|
||||
}
|
||||
|
||||
std::vector<json> symbols;
|
||||
@ -762,20 +768,25 @@ void JsonVisitor::visit(const Signature& signature) {
|
||||
JsonVisitor content_info_visitor;
|
||||
content_info_visitor(signature.content_info());
|
||||
|
||||
JsonVisitor signer_info_visitor;
|
||||
signer_info_visitor(signature.signer_info());
|
||||
std::vector<json> jsigners;
|
||||
for (const SignerInfo& signer : signature.signers()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(signer);
|
||||
jsigners.emplace_back(std::move(visitor.get()));
|
||||
}
|
||||
|
||||
std::vector<json> crts;
|
||||
for (const x509& crt : signature.certificates()) {
|
||||
JsonVisitor crt_visitor;
|
||||
crt_visitor(crt);
|
||||
crts.emplace_back(crt_visitor.get());
|
||||
crts.emplace_back(std::move(crt_visitor.get()));
|
||||
}
|
||||
|
||||
this->node_["version"] = signature.version();
|
||||
this->node_["content_info"] = content_info_visitor.get();
|
||||
this->node_["signer_info"] = signer_info_visitor.get();
|
||||
this->node_["certificates"] = crts;
|
||||
this->node_["digest_algorithm"] = to_string(signature.digest_algorithm());
|
||||
this->node_["version"] = signature.version();
|
||||
this->node_["content_info"] = content_info_visitor.get();
|
||||
this->node_["signer_info"] = jsigners;
|
||||
this->node_["certificates"] = crts;
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const x509& x509) {
|
||||
@ -789,27 +800,93 @@ void JsonVisitor::visit(const x509& x509) {
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const SignerInfo& signerinfo) {
|
||||
JsonVisitor authenticated_attributes_visitor;
|
||||
authenticated_attributes_visitor(signerinfo.authenticated_attributes());
|
||||
std::vector<json> auth_attrs;
|
||||
for (const Attribute& attr : signerinfo.authenticated_attributes()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(attr);
|
||||
auth_attrs.emplace_back(std::move(visitor.get()));
|
||||
}
|
||||
|
||||
this->node_["version"] = signerinfo.version();
|
||||
this->node_["digest_algorithm"] = signerinfo.digest_algorithm();
|
||||
this->node_["signature_algorithm"] = signerinfo.signature_algorithm();
|
||||
this->node_["authenticated_attributes"] = authenticated_attributes_visitor.get();
|
||||
this->node_["issuer"] = std::get<0>(signerinfo.issuer());
|
||||
std::vector<json> unauth_attrs;
|
||||
for (const Attribute& attr : signerinfo.unauthenticated_attributes()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(attr);
|
||||
auth_attrs.emplace_back(std::move(visitor.get()));
|
||||
}
|
||||
|
||||
this->node_["version"] = signerinfo.version();
|
||||
this->node_["digest_algorithm"] = to_string(signerinfo.digest_algorithm());
|
||||
this->node_["encryption_algorithm"] = to_string(signerinfo.encryption_algorithm());
|
||||
this->node_["encrypted_digest"] = signerinfo.encrypted_digest();
|
||||
this->node_["issuer"] = signerinfo.issuer();
|
||||
this->node_["serial_number"] = signerinfo.serial_number();
|
||||
this->node_["authenticated_attributes"] = auth_attrs;
|
||||
this->node_["unauthenticated_attributes"] = unauth_attrs;
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const ContentInfo& contentinfo) {
|
||||
this->node_["content_type"] = contentinfo.content_type();
|
||||
this->node_["type"] = contentinfo.type();
|
||||
this->node_["digest_algorithm"] = contentinfo.digest_algorithm();
|
||||
this->node_["digest_algorithm"] = to_string(contentinfo.digest_algorithm());
|
||||
this->node_["digest"] = contentinfo.digest();
|
||||
this->node_["file"] = contentinfo.file();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const AuthenticatedAttributes& auth) {
|
||||
this->node_["content_type"] = auth.content_type();
|
||||
this->node_["program_name"] = u16tou8(auth.program_name());
|
||||
this->node_["url"] = auth.more_info();
|
||||
this->node_["message_digest"] = auth.message_digest();
|
||||
void JsonVisitor::visit(const Attribute& auth) {
|
||||
this->node_["type"] = to_string(auth.type());
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const ContentType& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["oid"] = attr.oid();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const GenericType& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["oid"] = attr.oid();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const MsSpcNestedSignature& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
JsonVisitor visitor;
|
||||
visitor(attr.sig());
|
||||
this->node_["signature"] = std::move(visitor.get());
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const MsSpcStatementType& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["oid"] = attr.oid();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const PKCS9AtSequenceNumber& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["number"] = attr.number();
|
||||
}
|
||||
void JsonVisitor::visit(const PKCS9CounterSignature& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
|
||||
std::vector<json> signers;
|
||||
for (const SignerInfo& signer : attr.signers()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(signer);
|
||||
signers.emplace_back(std::move(visitor.get()));
|
||||
}
|
||||
this->node_["signers"] = std::move(signers);
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const PKCS9MessageDigest& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["digest"] = attr.digest();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const PKCS9SigningTime& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["time"] = attr.time();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const SpcSpOpusInfo& attr) {
|
||||
this->visit(*attr.as<Attribute>());
|
||||
this->node_["more_info"] = attr.more_info();
|
||||
this->node_["program_name"] = attr.program_name();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const CodeIntegrity& code_integrity) {
|
||||
|
54
src/PE/signature/Attribute.cpp
Normal file
54
src/PE/signature/Attribute.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <iomanip>
|
||||
|
||||
#include "LIEF/utils.hpp"
|
||||
#include "LIEF/PE/utils.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
Attribute::Attribute(void) = default;
|
||||
|
||||
Attribute::Attribute(SIG_ATTRIBUTE_TYPES type) :
|
||||
type_{type}
|
||||
{}
|
||||
|
||||
Attribute::Attribute(const Attribute& other) :
|
||||
type_{other.type_}
|
||||
{}
|
||||
|
||||
Attribute& Attribute::operator=(const Attribute& other) {
|
||||
if (this != &other) {
|
||||
this->type_ = other.type_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Attribute::~Attribute(void) = default;
|
||||
|
||||
void Attribute::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Attribute& attribute) {
|
||||
os << attribute.print();
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <iomanip>
|
||||
|
||||
#include "LIEF/utils.hpp"
|
||||
#include "LIEF/PE/utils.hpp"
|
||||
#include "LIEF/PE/signature/AuthenticatedAttributes.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
AuthenticatedAttributes::AuthenticatedAttributes(void) = default;
|
||||
AuthenticatedAttributes::AuthenticatedAttributes(const AuthenticatedAttributes&) = default;
|
||||
AuthenticatedAttributes& AuthenticatedAttributes::operator=(const AuthenticatedAttributes&) = default;
|
||||
AuthenticatedAttributes::~AuthenticatedAttributes(void) = default;
|
||||
|
||||
|
||||
const oid_t& AuthenticatedAttributes::content_type(void) const {
|
||||
return this->content_type_;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t>& AuthenticatedAttributes::message_digest(void) const {
|
||||
return this->message_digest_;
|
||||
}
|
||||
|
||||
const std::u16string& AuthenticatedAttributes::program_name(void) const {
|
||||
return this->program_name_;
|
||||
}
|
||||
|
||||
const std::string& AuthenticatedAttributes::more_info(void) const {
|
||||
return this->more_info_;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t>& AuthenticatedAttributes::raw(void) const {
|
||||
return this->raw_;
|
||||
}
|
||||
|
||||
void AuthenticatedAttributes::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const AuthenticatedAttributes& authenticated_attributes) {
|
||||
constexpr uint8_t wsize = 30;
|
||||
std::string content_type = authenticated_attributes.content_type();
|
||||
if (content_type.empty()) {
|
||||
content_type = "N/A";
|
||||
}
|
||||
std::string program_name = u16tou8(authenticated_attributes.program_name());
|
||||
if (program_name.empty()) {
|
||||
program_name = "N/A";
|
||||
}
|
||||
std::string url = authenticated_attributes.more_info();
|
||||
if (url.empty()) {
|
||||
url = "N/A";
|
||||
}
|
||||
os << std::hex << std::left;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Content type: " << content_type << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Program name: " << program_name << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "URL : " << url << std::endl;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
36
src/PE/signature/CMakeLists.txt
Normal file
36
src/PE/signature/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
||||
set(LIEF_PE_SIGNATURE_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Attribute.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ContentInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Signature.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/SignerInfo.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/x509.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/OIDToString.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/SignatureParser.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RsaInfo.cpp"
|
||||
)
|
||||
|
||||
|
||||
set(LIEF_PE_SIGNATURE_INCLUDES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/Attribute.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/ContentInfo.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/OIDToString.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/Signature.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/SignatureParser.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/SignerInfo.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/types.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/x509.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/RsaInfo.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/PE/signature/pkcs7.h"
|
||||
)
|
||||
|
||||
source_group("Header Files\\PE\\signature" FILES ${LIEF_PE_SIGNATURE_SRC})
|
||||
source_group("Header Files\\PE\\signature" FILES ${LIEF_PE_SIGNATURE_INCLUDES})
|
||||
|
||||
if (LIEF_PE)
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${LIEF_PE_SIGNATURE_SRC}
|
||||
${LIEF_PE_SIGNATURE_INCLUDES}
|
||||
)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/attributes/CMakeLists.txt")
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "LIEF/PE/signature/OIDToString.hpp"
|
||||
#include "LIEF/PE/signature/ContentInfo.hpp"
|
||||
#include "LIEF/PE/EnumToString.hpp"
|
||||
#include "LIEF/utils.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
@ -26,27 +28,6 @@ ContentInfo::ContentInfo(const ContentInfo&) = default;
|
||||
ContentInfo& ContentInfo::operator=(const ContentInfo&) = default;
|
||||
ContentInfo::~ContentInfo(void) = default;
|
||||
|
||||
const oid_t& ContentInfo::content_type(void) const {
|
||||
return this->content_type_;
|
||||
}
|
||||
|
||||
const oid_t& ContentInfo::type(void) const {
|
||||
return this->type_;
|
||||
}
|
||||
|
||||
|
||||
const oid_t& ContentInfo::digest_algorithm(void) const {
|
||||
return this->digest_algorithm_;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<uint8_t>& ContentInfo::digest(void) const {
|
||||
return this->digest_;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t>& ContentInfo::raw(void) const {
|
||||
return this->raw_;
|
||||
}
|
||||
|
||||
void ContentInfo::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
@ -54,12 +35,8 @@ void ContentInfo::accept(Visitor& visitor) const {
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const ContentInfo& content_info) {
|
||||
constexpr uint8_t wsize = 30;
|
||||
|
||||
os << std::hex << std::left;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Content Type: " << oid_to_string(content_info.content_type()) << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Type: " << oid_to_string(content_info.type()) << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Digest Algorithm: " << oid_to_string(content_info.digest_algorithm()) << std::endl;
|
||||
os << "Authentihash: " << hex_dump(content_info.digest())
|
||||
<< "(" << to_string(content_info.digest_algorithm()) << ")\n";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ const char* oid_to_string(const oid_t& oid) {
|
||||
{ "1.2.840.10040.2.3", "REJECT" },
|
||||
{ "1.2.840.10040.2.4", "PICKUP_TOKEN" },
|
||||
{ "1.2.840.10040.3", "ATTRIBUTE" },
|
||||
{ "1.2.840.10040.3.1", "COUNTERSIGNATURE" },
|
||||
{ "1.2.840.10040.3.1", "COUNTER_SIGNATURE" },
|
||||
{ "1.2.840.10040.3.2", "ATTRIBUTE_CERT" },
|
||||
{ "1.2.840.10040.4", "ALGORITHM" },
|
||||
{ "1.2.840.10040.4.1", "DSA" },
|
||||
@ -616,7 +616,7 @@ const char* oid_to_string(const oid_t& oid) {
|
||||
{ "1.2.840.113549.1.9.3", "CONTENT_TYPE" },
|
||||
{ "1.2.840.113549.1.9.4", "MESSAGE_DIGEST" },
|
||||
{ "1.2.840.113549.1.9.5", "SIGNING_TIME" },
|
||||
{ "1.2.840.113549.1.9.6", "COUNTERSIGNATURE" },
|
||||
{ "1.2.840.113549.1.9.6", "COUNTER_SIGNATURE" },
|
||||
{ "1.2.840.113549.1.9.7", "CHALLENGE_PASSWORD" },
|
||||
{ "1.2.840.113549.1.9.8", "UNSTRUCTURED_ADDRESS" },
|
||||
{ "1.2.840.113549.1.9.9", "EXTENDED_CERTIFICATE_ATTRIBUTES" },
|
||||
@ -976,7 +976,7 @@ const char* oid_to_string(const oid_t& oid) {
|
||||
{ "1.2.840.113635.100.6.1.1", "APPLE_CERTIFICATE_EXTENSION_APPLE_SIGNING" },
|
||||
{ "1.2.840.113635.100.6.1.2", "APPLE_CERTIFICATE_EXTENSION_ADC_DEVELOPER_SIGNING" },
|
||||
{ "1.2.840.113635.100.6.1.3", "APPLE_CERTIFICATE_EXTENSION_ADC_APPLE_SIGNING" },
|
||||
{ "1.3.6.1.4.1.311.2.1.4", "SPC_INDIRECT_DATA_CONTEXT" },
|
||||
{ "1.3.6.1.4.1.311.2.1.4", "SPC_INDIRECT_DATA_CONTENT" },
|
||||
{ "1.3.6.1.4.1.311.2.1.10", "SPC_AGENCY_INFO" },
|
||||
{ "1.3.6.1.4.1.311.2.1.11", "SPC_STATEMENT_TYPE" },
|
||||
{ "1.3.6.1.4.1.311.2.1.12", "SPC_SP_OPUS_INFO" },
|
||||
@ -2241,10 +2241,11 @@ const char* oid_to_string(const oid_t& oid) {
|
||||
{ "2.16.840.1.114404.1.1.2.4.1", "TRUST_WAVE_EV_POLICY" },
|
||||
{ "1.3.6.1.4.1.40869.1.1.22.3", "TWCA_EV_POLICY" },
|
||||
{ "2.16.840.1.113733.1.7.23.6", "VERI_SIGN_EV_POLICY" },
|
||||
{ "2.16.840.1.114171.500.9", "WELLS_FARGO_EV_POLICY" }
|
||||
{ "2.16.840.1.114171.500.9", "WELLS_FARGO_EV_POLICY" },
|
||||
{ "1.3.6.1.4.1.311.3.3.1", "MS_COUNTER_SIGN" }
|
||||
};
|
||||
auto it = oid_to_str.find(oid);
|
||||
return it == oid_to_str.end() ? "Out of range" : it->second;
|
||||
return it == oid_to_str.end() ? oid.c_str() : it->second;
|
||||
}
|
||||
|
||||
}
|
||||
|
123
src/PE/signature/RsaInfo.cpp
Normal file
123
src/PE/signature/RsaInfo.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
|
||||
#include "LIEF/PE/signature/RsaInfo.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
||||
#include <mbedtls/x509.h>
|
||||
#include <mbedtls/asn1.h>
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/pk.h>
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
RsaInfo::RsaInfo(void) = default;
|
||||
|
||||
RsaInfo::RsaInfo(const RsaInfo::rsa_ctx_handle ctx) {
|
||||
const mbedtls_rsa_context* pctx = reinterpret_cast<const mbedtls_rsa_context*>(ctx);
|
||||
mbedtls_rsa_context* local_ctx = new mbedtls_rsa_context{};
|
||||
mbedtls_rsa_init(local_ctx, pctx->padding, pctx->hash_id);
|
||||
mbedtls_rsa_copy(local_ctx, pctx);
|
||||
this->ctx_ = reinterpret_cast<RsaInfo::rsa_ctx_handle>(local_ctx);
|
||||
}
|
||||
|
||||
RsaInfo::RsaInfo(const RsaInfo& other)
|
||||
{
|
||||
if (other) {
|
||||
const mbedtls_rsa_context* octx = reinterpret_cast<const mbedtls_rsa_context*>(other.ctx_);
|
||||
mbedtls_rsa_context* local_ctx = new mbedtls_rsa_context{};
|
||||
mbedtls_rsa_init(local_ctx, octx->padding, octx->hash_id);
|
||||
mbedtls_rsa_copy(local_ctx, octx);
|
||||
this->ctx_ = reinterpret_cast<RsaInfo::rsa_ctx_handle>(local_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RsaInfo::RsaInfo(RsaInfo&& other) :
|
||||
ctx_{std::move(other.ctx_)}
|
||||
{}
|
||||
|
||||
RsaInfo& RsaInfo::operator=(RsaInfo other) {
|
||||
this->swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void RsaInfo::swap(RsaInfo& other) {
|
||||
std::swap(this->ctx_, other.ctx_);
|
||||
}
|
||||
|
||||
RsaInfo::operator bool() const {
|
||||
return this->ctx_ != nullptr;
|
||||
}
|
||||
|
||||
bool RsaInfo::has_public_key(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
return mbedtls_rsa_check_pubkey(lctx) == 0;
|
||||
}
|
||||
|
||||
bool RsaInfo::has_private_key(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
return mbedtls_rsa_check_privkey(lctx) == 0;
|
||||
}
|
||||
|
||||
|
||||
RsaInfo::bignum_wrapper_t RsaInfo::N(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
bignum_wrapper_t N(mbedtls_mpi_bitlen(&lctx->N));
|
||||
mbedtls_mpi_write_binary(&lctx->N, N.data(), N.size());
|
||||
return N;
|
||||
}
|
||||
|
||||
RsaInfo::bignum_wrapper_t RsaInfo::E(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
bignum_wrapper_t E(mbedtls_mpi_bitlen(&lctx->E));
|
||||
mbedtls_mpi_write_binary(&lctx->E, E.data(), E.size());
|
||||
return E;
|
||||
}
|
||||
|
||||
RsaInfo::bignum_wrapper_t RsaInfo::D(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
bignum_wrapper_t D(mbedtls_mpi_bitlen(&lctx->D));
|
||||
mbedtls_mpi_write_binary(&lctx->D, D.data(), D.size());
|
||||
return D;
|
||||
}
|
||||
|
||||
RsaInfo::bignum_wrapper_t RsaInfo::P(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
bignum_wrapper_t P(mbedtls_mpi_bitlen(&lctx->P));
|
||||
mbedtls_mpi_write_binary(&lctx->P, P.data(), P.size());
|
||||
return P;
|
||||
}
|
||||
|
||||
RsaInfo::bignum_wrapper_t RsaInfo::Q(void) const {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
bignum_wrapper_t Q(mbedtls_mpi_bitlen(&lctx->Q));
|
||||
mbedtls_mpi_write_binary(&lctx->Q, Q.data(), Q.size());
|
||||
return Q;
|
||||
}
|
||||
|
||||
|
||||
RsaInfo::~RsaInfo(void) {
|
||||
if (this->ctx_) {
|
||||
mbedtls_rsa_context* lctx = reinterpret_cast<mbedtls_rsa_context*>(this->ctx_);
|
||||
mbedtls_rsa_free(lctx);
|
||||
delete lctx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RsaInfo& info) {
|
||||
if (not info) {
|
||||
os << "<Empty>";
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -14,39 +14,256 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
#include "logging.hpp"
|
||||
|
||||
#include "LIEF/utils.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/Signature.hpp"
|
||||
#include "LIEF/PE/signature/OIDToString.hpp"
|
||||
#include "LIEF/PE/EnumToString.hpp"
|
||||
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
#include "LIEF/PE/signature/attributes.hpp"
|
||||
|
||||
#include <mbedtls/sha512.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
|
||||
#include <mbedtls/md2.h>
|
||||
#include <mbedtls/md4.h>
|
||||
#include <mbedtls/md5.h>
|
||||
|
||||
#include "mbedtls/x509_crt.h"
|
||||
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
Signature::Signature(void) = default; // TODO
|
||||
|
||||
Signature::Signature(void) = default;
|
||||
Signature::Signature(const Signature&) = default;
|
||||
Signature& Signature::operator=(const Signature&) = default;
|
||||
Signature::~Signature(void) = default;
|
||||
|
||||
|
||||
std::vector<uint8_t> Signature::hash(const std::vector<uint8_t>& input, ALGORITHMS algo) {
|
||||
switch (algo) {
|
||||
|
||||
case ALGORITHMS::SHA_512:
|
||||
{
|
||||
std::vector<uint8_t> out(64);
|
||||
int ret = mbedtls_sha512_ret(input.data(), input.size(), out.data(), /* is384 */ false);
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with SHA-512 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
case ALGORITHMS::SHA_384:
|
||||
{
|
||||
std::vector<uint8_t> out(64);
|
||||
int ret = mbedtls_sha512_ret(input.data(), input.size(), out.data(), /* is384 */ true);
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with SHA-384 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
case ALGORITHMS::SHA_256:
|
||||
{
|
||||
std::vector<uint8_t> out(32);
|
||||
int ret = mbedtls_sha256_ret(input.data(), input.size(), out.data(), /* is224 */ false);
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with SHA-256 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
case ALGORITHMS::SHA_1:
|
||||
{
|
||||
std::vector<uint8_t> out(20);
|
||||
int ret = mbedtls_sha1_ret(input.data(), input.size(), out.data());
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with SHA-1 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
case ALGORITHMS::MD5:
|
||||
{
|
||||
std::vector<uint8_t> out(16);
|
||||
int ret = mbedtls_md5_ret(input.data(), input.size(), out.data());
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with MD5 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
case ALGORITHMS::MD4:
|
||||
{
|
||||
std::vector<uint8_t> out(16);
|
||||
int ret = mbedtls_md4_ret(input.data(), input.size(), out.data());
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with MD4 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
case ALGORITHMS::MD2:
|
||||
{
|
||||
std::vector<uint8_t> out(16);
|
||||
int ret = mbedtls_md2_ret(input.data(), input.size(), out.data());
|
||||
if (ret != 0) {
|
||||
LIEF_ERR("Hashing {} bytes with MD2 failed! (ret: 0x{:x})", input.size(), ret);
|
||||
return {};
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
LIEF_ERR("Unsupported hash algorithm {}", to_string(algo));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
uint32_t Signature::version(void) const {
|
||||
return this->version_;
|
||||
}
|
||||
|
||||
const oid_t& Signature::digest_algorithm(void) const {
|
||||
return this->digest_algorithm_;
|
||||
}
|
||||
|
||||
const ContentInfo& Signature::content_info(void) const {
|
||||
return this->content_info_;
|
||||
}
|
||||
|
||||
it_const_crt Signature::certificates(void) const {
|
||||
return {this->certificates_};
|
||||
return this->certificates_;
|
||||
}
|
||||
|
||||
const SignerInfo& Signature::signer_info(void) const {
|
||||
return this->signer_info_;
|
||||
it_const_signers_t Signature::signers(void) const {
|
||||
return this->signers_;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t>& Signature::original_signature(void) const {
|
||||
Signature::VERIFICATION_FLAGS Signature::check() const {
|
||||
// According to the Authenticode documentation,
|
||||
// *SignerInfos contains one SignerInfo structure*
|
||||
const size_t nb_signers = this->signers_.size();
|
||||
VERIFICATION_FLAGS flags = VERIFICATION_FLAGS::OK;
|
||||
if (nb_signers == 0) {
|
||||
LIEF_WARN("No signer associated with the signature");
|
||||
return flags | VERIFICATION_FLAGS::INVALID_SIGNER;
|
||||
}
|
||||
|
||||
if (nb_signers > 1) {
|
||||
LIEF_WARN("More than ONE signer ({:d} signers)", nb_signers);
|
||||
return flags | VERIFICATION_FLAGS::INVALID_SIGNER;
|
||||
}
|
||||
const SignerInfo& signer = this->signers_.back();
|
||||
|
||||
// Check that Signature.digest_algorithm matches:
|
||||
// - SignerInfo.digest_algorithm
|
||||
// - ContentInfo.digest_algorithm
|
||||
|
||||
if (this->digest_algorithm_ == ALGORITHMS::UNKNOWN) {
|
||||
LIEF_WARN("Unsupported digest algorithm");
|
||||
return flags | VERIFICATION_FLAGS::UNSUPPORTED_ALGORITHM;
|
||||
}
|
||||
|
||||
if (this->digest_algorithm_ != this->content_info_.digest_algorithm()) {
|
||||
LIEF_WARN("Digest algorithm is different from ContentInfo");
|
||||
return flags | VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM;
|
||||
}
|
||||
|
||||
if (this->digest_algorithm_ != signer.digest_algorithm()) {
|
||||
LIEF_WARN("Digest algorithm is different from Signer");
|
||||
return flags | VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM;
|
||||
}
|
||||
|
||||
const ALGORITHMS digest_algo = this->content_info().digest_algorithm();
|
||||
|
||||
if (signer.cert() == nullptr) {
|
||||
LIEF_WARN("Can't find certificate whose the issuer is {}", signer.issuer());
|
||||
return flags | VERIFICATION_FLAGS::CERT_NOT_FOUND;
|
||||
}
|
||||
const x509& cert = *signer.cert();
|
||||
const SignerInfo::encrypted_digest_t& enc_digest = signer.encrypted_digest();
|
||||
|
||||
if (this->content_info_start_ == 0 or this->content_info_end_ == 0) {
|
||||
return flags | VERIFICATION_FLAGS::CORRUPTED_CONTENT_INFO;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> raw_content_info = {
|
||||
std::begin(this->original_raw_signature_) + this->content_info_start_,
|
||||
std::begin(this->original_raw_signature_) + this->content_info_end_
|
||||
};
|
||||
|
||||
const std::vector<uint8_t> content_info_hash = Signature::hash(std::move(raw_content_info), digest_algo);
|
||||
|
||||
if (this->auth_start_ == 0 or this->auth_end_ == 0) {
|
||||
flags |= VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA;
|
||||
}
|
||||
|
||||
// Copy authenticated attributes
|
||||
it_const_attributes_t auth_attrs = signer.authenticated_attributes();
|
||||
if (auth_attrs.size() > 0 and
|
||||
(flags & VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA) != VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA) {
|
||||
std::vector<uint8_t> auth_data = {
|
||||
std::begin(this->original_raw_signature_) + this->auth_start_,
|
||||
std::begin(this->original_raw_signature_) + this->auth_end_
|
||||
};
|
||||
|
||||
// According to the RFC:
|
||||
//
|
||||
// "[...] The Attributes value's tag is SET OF, and the DER encoding of
|
||||
// the SET OF tag, rather than of the IMPLICIT [0] tag [...]"
|
||||
auth_data[0] = /* SET OF */ 0x31;
|
||||
|
||||
const std::vector<uint8_t> auth_attr_hash = Signature::hash(auth_data, digest_algo);
|
||||
LIEF_DEBUG("Authenticated attribute digest: {}", hex_dump(auth_attr_hash));
|
||||
bool check_sig = cert.check_signature(auth_attr_hash, enc_digest, digest_algo);
|
||||
|
||||
if (not check_sig) {
|
||||
return flags | VERIFICATION_FLAGS::BAD_SIGNATURE;
|
||||
}
|
||||
|
||||
// Check that content_info_hash matches pkcs9-message-digest
|
||||
auto it_pkcs9_digest = std::find_if(std::begin(auth_attrs), std::end(auth_attrs),
|
||||
[] (const Attribute& attr) {
|
||||
return attr.type() == SIG_ATTRIBUTE_TYPES::PKCS9_MESSAGE_DIGEST;
|
||||
});
|
||||
|
||||
if (it_pkcs9_digest == std::end(auth_attrs)) {
|
||||
return flags | VERIFICATION_FLAGS::MISSING_PKCS9_MESSAGE_DIGEST;
|
||||
}
|
||||
|
||||
const auto& digest_attr = reinterpret_cast<const PKCS9MessageDigest&>(*it_pkcs9_digest);
|
||||
LIEF_DEBUG("pkcs9-message-digest:\n {}\n {}", hex_dump(digest_attr.digest()), hex_dump(content_info_hash));
|
||||
if (digest_attr.digest() != content_info_hash) {
|
||||
return flags | VERIFICATION_FLAGS::BAD_DIGEST;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
/*
|
||||
* If there is no authenticated attributes, then encrypted digested should match ENC(content_info_hash)
|
||||
*/
|
||||
if (not cert.check_signature(content_info_hash, enc_digest, digest_algo)) {
|
||||
return flags | VERIFICATION_FLAGS::BAD_SIGNATURE;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<uint8_t>& Signature::raw_der(void) const {
|
||||
return this->original_raw_signature_;
|
||||
}
|
||||
|
||||
@ -54,28 +271,140 @@ void Signature::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Signature& signature) {
|
||||
constexpr uint8_t wsize = 30;
|
||||
os << std::hex << std::left;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Version: " << signature.version() << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Digest Algorithm: " << oid_to_string(signature.digest_algorithm()) << std::endl;
|
||||
inline void print_attr(it_const_attributes_t& attrs, std::ostream& os) {
|
||||
for (const Attribute& attr : attrs) {
|
||||
std::string suffix;
|
||||
switch (attr.type()) {
|
||||
case SIG_ATTRIBUTE_TYPES::CONTENT_TYPE:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const ContentType&>(attr);
|
||||
suffix = ct.oid() + " (" + oid_to_string(ct.oid()) + ")";
|
||||
break;
|
||||
}
|
||||
|
||||
os << "Content Info" << std::endl;
|
||||
os << "============" << std::endl;
|
||||
os << signature.content_info() << std::endl << std::endl;
|
||||
case SIG_ATTRIBUTE_TYPES::MS_SPC_STATEMENT_TYPE:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const MsSpcStatementType&>(attr);
|
||||
suffix = ct.oid() + " (" + oid_to_string(ct.oid()) + ")";
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::SPC_SP_OPUS_INFO:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const SpcSpOpusInfo&>(attr);
|
||||
if (not ct.program_name().empty()) {
|
||||
suffix = ct.program_name();
|
||||
}
|
||||
if (not ct.more_info().empty()) {
|
||||
if (not suffix.empty()) {
|
||||
suffix += " - ";
|
||||
}
|
||||
suffix += ct.more_info();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::PKCS9_MESSAGE_DIGEST:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const PKCS9MessageDigest&>(attr);
|
||||
suffix = hex_dump(ct.digest()).substr(0, 41) + "...";
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::MS_SPC_NESTED_SIGN:
|
||||
{
|
||||
const auto& nested_attr = reinterpret_cast<const MsSpcNestedSignature&>(attr);
|
||||
const Signature& ct = nested_attr.sig();
|
||||
auto signers = ct.signers();
|
||||
auto crts = ct.certificates();
|
||||
if (signers.size() > 0) {
|
||||
suffix = signers[0].issuer();
|
||||
} else if (crts.size() > 0) {
|
||||
suffix = crts[0].issuer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::GENERIC_TYPE:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const GenericType&>(attr);
|
||||
suffix = ct.oid();
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::PKCS9_AT_SEQUENCE_NUMBER:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const PKCS9AtSequenceNumber&>(attr);
|
||||
suffix = std::to_string(ct.number());
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::PKCS9_COUNTER_SIGNATURE:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const PKCS9CounterSignature&>(attr);
|
||||
it_const_signers_t signers = ct.signers();
|
||||
|
||||
if (signers.size() > 1 or signers.size() == 0) {
|
||||
suffix = std::to_string(signers.size()) + " signers";
|
||||
break;
|
||||
}
|
||||
const SignerInfo& signer = signers[0];
|
||||
suffix = signer.issuer();
|
||||
break;
|
||||
}
|
||||
|
||||
case SIG_ATTRIBUTE_TYPES::PKCS9_SIGNING_TIME:
|
||||
{
|
||||
const auto& ct = reinterpret_cast<const PKCS9SigningTime&>(attr);
|
||||
const PKCS9SigningTime::time_t time = ct.time();
|
||||
suffix = fmt::format("{}/{}/{} - {}:{}:{}",
|
||||
time[0], time[1], time[2], time[3], time[4], time[5]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
os << fmt::format(" {}: {}\n", to_string(attr.type()), suffix);
|
||||
|
||||
os << "Certificates" << std::endl;
|
||||
os << "============" << std::endl;
|
||||
for (const x509& crt : signature.certificates()) {
|
||||
os << crt << std::endl;;
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
os << "Signer Info" << std::endl;
|
||||
os << "===========" << std::endl;
|
||||
os << signature.signer_info() << std::endl << std::endl;
|
||||
std::ostream& operator<<(std::ostream& os, const Signature& signature) {
|
||||
const ContentInfo& cinfo = signature.content_info();
|
||||
os << fmt::format("Version: {:d}\n", signature.version());
|
||||
os << fmt::format("Digest Algorithm: {}\n", to_string(signature.digest_algorithm()));
|
||||
os << fmt::format("Content Info Digest: {}\n", hex_dump(cinfo.digest()));
|
||||
if (not cinfo.file().empty()) {
|
||||
os << fmt::format("Content Info File: {}\n", cinfo.file());
|
||||
}
|
||||
it_const_crt certs = signature.certificates();
|
||||
os << fmt::format("#{:d} certificate(s):\n", certs.size());
|
||||
for (const x509& crt : certs) {
|
||||
os << fmt::format(" - {}\n", crt.issuer()); // TODO(romain): RSA-2048, ...
|
||||
}
|
||||
|
||||
it_const_signers_t signers = signature.signers();
|
||||
os << fmt::format("#{:d} signer(s):\n", signers.size());
|
||||
for (const SignerInfo& signer : signers) {
|
||||
os << fmt::format("Issuer: {}\n", signer.issuer());
|
||||
os << fmt::format("Digest: {}\n", to_string(signer.digest_algorithm()));
|
||||
os << fmt::format("Encryption: {}\n", to_string(signer.encryption_algorithm()));
|
||||
os << fmt::format("Encrypted DG: {} ...\n", hex_dump(signer.encrypted_digest()).substr(0, 41));
|
||||
it_const_attributes_t auth_attr = signer.authenticated_attributes();
|
||||
if (auth_attr.size() > 0) {
|
||||
os << fmt::format("#{:d} authenticated attributes:\n", auth_attr.size());
|
||||
print_attr(auth_attr, os);
|
||||
}
|
||||
|
||||
it_const_attributes_t unauth_attr = signer.unauthenticated_attributes();
|
||||
if (unauth_attr.size() > 0) {
|
||||
os << fmt::format("#{:d} un-authenticated attributes:\n", unauth_attr.size());
|
||||
print_attr(unauth_attr, os);
|
||||
}
|
||||
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,80 +18,132 @@
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
#include "LIEF/PE/signature/x509.hpp"
|
||||
#include "LIEF/PE/signature/OIDToString.hpp"
|
||||
#include "LIEF/PE/signature/SignerInfo.hpp"
|
||||
#include "LIEF/PE/signature/Attribute.hpp"
|
||||
|
||||
#include "LIEF/PE/EnumToString.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
SignerInfo::SignerInfo(void) = default;
|
||||
SignerInfo::SignerInfo(const SignerInfo&) = default;
|
||||
SignerInfo& SignerInfo::operator=(const SignerInfo&) = default;
|
||||
SignerInfo::~SignerInfo(void) = default;
|
||||
|
||||
SignerInfo::SignerInfo(SignerInfo&&) = default;
|
||||
SignerInfo& SignerInfo::operator=(SignerInfo&&) = default;
|
||||
|
||||
SignerInfo::SignerInfo(const SignerInfo& other) :
|
||||
Object::Object(other),
|
||||
version_{other.version_},
|
||||
issuer_{other.issuer_},
|
||||
serialno_{other.serialno_},
|
||||
digest_algorithm_{other.digest_algorithm_},
|
||||
digest_enc_algorithm_{other.digest_enc_algorithm_},
|
||||
encrypted_digest_{other.encrypted_digest_}
|
||||
{
|
||||
for (const std::unique_ptr<Attribute>& attr : other.authenticated_attributes_) {
|
||||
this->authenticated_attributes_.push_back(attr->clone());
|
||||
}
|
||||
|
||||
for (const std::unique_ptr<Attribute>& attr : other.unauthenticated_attributes_) {
|
||||
this->unauthenticated_attributes_.push_back(attr->clone());
|
||||
}
|
||||
|
||||
if (other.cert_ != nullptr) {
|
||||
this->cert_ = std::unique_ptr<x509>(new x509{*other.cert_});
|
||||
}
|
||||
}
|
||||
|
||||
SignerInfo& SignerInfo::operator=(SignerInfo other) {
|
||||
this->swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SignerInfo::swap(SignerInfo& other) {
|
||||
std::swap(this->version_, other.version_);
|
||||
std::swap(this->issuer_, other.issuer_);
|
||||
std::swap(this->serialno_, other.serialno_);
|
||||
std::swap(this->digest_algorithm_, other.digest_algorithm_);
|
||||
std::swap(this->digest_enc_algorithm_, other.digest_enc_algorithm_);
|
||||
std::swap(this->encrypted_digest_, other.encrypted_digest_);
|
||||
std::swap(this->authenticated_attributes_, other.authenticated_attributes_);
|
||||
std::swap(this->unauthenticated_attributes_, other.unauthenticated_attributes_);
|
||||
std::swap(this->cert_, other.cert_);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SignerInfo::version(void) const {
|
||||
return this->version_;
|
||||
}
|
||||
|
||||
|
||||
const issuer_t& SignerInfo::issuer(void) const {
|
||||
return this->issuer_;
|
||||
}
|
||||
|
||||
|
||||
const oid_t& SignerInfo::digest_algorithm(void) const {
|
||||
ALGORITHMS SignerInfo::digest_algorithm(void) const {
|
||||
return this->digest_algorithm_;
|
||||
}
|
||||
|
||||
|
||||
const AuthenticatedAttributes& SignerInfo::authenticated_attributes(void) const {
|
||||
return this->authenticated_attributes_;
|
||||
ALGORITHMS SignerInfo::encryption_algorithm(void) const {
|
||||
return this->digest_enc_algorithm_;
|
||||
}
|
||||
|
||||
|
||||
const oid_t& SignerInfo::signature_algorithm(void) const {
|
||||
return this->signature_algorithm_;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<uint8_t>& SignerInfo::encrypted_digest(void) const {
|
||||
const SignerInfo::encrypted_digest_t& SignerInfo::encrypted_digest(void) const {
|
||||
return this->encrypted_digest_;
|
||||
}
|
||||
|
||||
it_const_attributes_t SignerInfo::authenticated_attributes() const {
|
||||
std::vector<Attribute*> attrs(this->authenticated_attributes_.size(), nullptr);
|
||||
for (size_t i = 0; i < this->authenticated_attributes_.size(); ++i) {
|
||||
attrs[i] = this->authenticated_attributes_[i].get();
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
it_const_attributes_t SignerInfo::unauthenticated_attributes() const {
|
||||
std::vector<Attribute*> attrs(this->unauthenticated_attributes_.size(), nullptr);
|
||||
for (size_t i = 0; i < this->unauthenticated_attributes_.size(); ++i) {
|
||||
attrs[i] = this->unauthenticated_attributes_[i].get();
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
const Attribute* SignerInfo::get_attribute(PE::SIG_ATTRIBUTE_TYPES type) const {
|
||||
// First look for the attribute in the authenticated ones
|
||||
auto it_auth = std::find_if(std::begin(this->authenticated_attributes_), std::end(this->authenticated_attributes_),
|
||||
[type] (const std::unique_ptr<Attribute>& attr) {
|
||||
return attr->type() == type;
|
||||
});
|
||||
if (it_auth != std::end(this->authenticated_attributes_)) {
|
||||
return it_auth->get();
|
||||
}
|
||||
|
||||
// Then in the UN-authenticated ones
|
||||
auto it_uauth = std::find_if(std::begin(this->unauthenticated_attributes_), std::end(this->unauthenticated_attributes_),
|
||||
[type] (const std::unique_ptr<Attribute>& attr) {
|
||||
return attr->type() == type;
|
||||
});
|
||||
if (it_uauth != std::end(this->unauthenticated_attributes_)) {
|
||||
return it_uauth->get();
|
||||
}
|
||||
|
||||
// ... not found -> return nullptr
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SignerInfo::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const SignerInfo& signer_info) {
|
||||
|
||||
constexpr uint8_t wsize = 30;
|
||||
const issuer_t& issuer = signer_info.issuer();
|
||||
std::string issuer_str = std::get<0>(issuer);
|
||||
|
||||
const std::vector<uint8_t>& sn = std::get<1>(issuer);;
|
||||
std::string sn_str = std::accumulate(
|
||||
std::begin(sn),
|
||||
std::end(sn),
|
||||
std::string(""),
|
||||
[] (std::string lhs, uint8_t x) {
|
||||
std::stringstream ss;
|
||||
ss << std::setw(2) << std::setfill('0') << std::hex << static_cast<uint32_t>(x);
|
||||
return lhs.empty() ? ss.str() : lhs + ":" + ss.str();
|
||||
});
|
||||
|
||||
|
||||
os << std::hex << std::left;
|
||||
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Version: " << signer_info.version() << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Serial Number: " << sn_str << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Issuer DN: " << issuer_str << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Digest Algorithm: " << oid_to_string(signer_info.digest_algorithm()) << std::endl;
|
||||
os << std::setw(wsize) << std::setfill(' ') << "Signature algorithm: " << oid_to_string(signer_info.signature_algorithm()) << std::endl;
|
||||
|
||||
os << signer_info.authenticated_attributes() << std::endl;
|
||||
|
||||
os << fmt::format("{}/{} - {} - {:d} auth attr - {:d} unauth attr",
|
||||
to_string(signer_info.digest_algorithm()),
|
||||
to_string(signer_info.encryption_algorithm()),
|
||||
signer_info.issuer(),
|
||||
signer_info.authenticated_attributes().size(),
|
||||
signer_info.unauthenticated_attributes().size());
|
||||
return os;
|
||||
}
|
||||
|
||||
|
42
src/PE/signature/attributes/CMakeLists.txt
Normal file
42
src/PE/signature/attributes/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
||||
set(LIEF_PE_SIGNATURE_ATTRIBUTES_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/GenericType.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ContentType.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/SpcSpOpusInfo.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/MsCounterSign.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/MsSpcNestedSignature.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/MsSpcStatementType.cpp"
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PKCS9AtSequenceNumber.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PKCS9CounterSignature.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PKCS9MessageDigest.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PKCS9SigningTime.cpp"
|
||||
)
|
||||
|
||||
set(LIEF_PE_SIGNATURE_ATTRIBUTES_INCLUDES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/GenericType.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/ContentType.hpp"
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/SpcSpOpusInfo.hpp"
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/MsCounterSign.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/MsSpcNestedSignature.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/MsSpcStatementType.hpp"
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/PKCS9AtSequenceNumber.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/PKCS9CounterSignature.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/PKCS9MessageDigest.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/signature/attributes/PKCS9SigningTime.hpp"
|
||||
)
|
||||
|
||||
source_group("Header Files\\PE\\signature\\attributes" FILES ${LIEF_PE_SIGNATURE_ATTRIBUTES_SRC})
|
||||
source_group("Header Files\\PE\\signature\\attributes" FILES ${LIEF_PE_SIGNATURE_ATTRIBUTES_INCLUDES})
|
||||
|
||||
if (LIEF_PE)
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${LIEF_PE_SIGNATURE_ATTRIBUTES_SRC}
|
||||
${LIEF_PE_SIGNATURE_ATTRIBUTES_INCLUDES}
|
||||
)
|
||||
endif()
|
||||
|
36
src/PE/signature/attributes/ContentType.cpp
Normal file
36
src/PE/signature/attributes/ContentType.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "LIEF/PE/signature/attributes/ContentType.hpp"
|
||||
#include "LIEF/PE/signature/OIDToString.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
ContentType::ContentType() :
|
||||
Attribute(SIG_ATTRIBUTE_TYPES::CONTENT_TYPE)
|
||||
{}
|
||||
|
||||
ContentType::ContentType(const ContentType&) = default;
|
||||
ContentType& ContentType::operator=(const ContentType&) = default;
|
||||
|
||||
std::unique_ptr<Attribute> ContentType::clone(void) const {
|
||||
return std::unique_ptr<Attribute>(new ContentType{*this});
|
||||
}
|
||||
|
||||
ContentType::ContentType(oid_t oid) :
|
||||
Attribute(SIG_ATTRIBUTE_TYPES::CONTENT_TYPE),
|
||||
oid_{std::move(oid)}
|
||||
{}
|
||||
|
||||
void ContentType::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
std::string ContentType::print() const {
|
||||
return this->oid() + " (" + oid_to_string(this->oid()) + ")";
|
||||
}
|
||||
|
||||
|
||||
ContentType::~ContentType() = default;
|
||||
|
||||
|
||||
}
|
||||
}
|
34
src/PE/signature/attributes/GenericType.cpp
Normal file
34
src/PE/signature/attributes/GenericType.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "LIEF/PE/signature/attributes/GenericType.hpp"
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
GenericType::GenericType() :
|
||||
Attribute(SIG_ATTRIBUTE_TYPES::GENERIC_TYPE)
|
||||
{}
|
||||
|
||||
GenericType::GenericType(const GenericType&) = default;
|
||||
GenericType& GenericType::operator=(const GenericType&) = default;
|
||||
|
||||
std::unique_ptr<Attribute> GenericType::clone(void) const {
|
||||
return std::unique_ptr<Attribute>(new GenericType{*this});
|
||||
}
|
||||
|
||||
GenericType::GenericType(oid_t oid, std::vector<uint8_t> raw) :
|
||||
Attribute(SIG_ATTRIBUTE_TYPES::GENERIC_TYPE),
|
||||
oid_{std::move(oid)},
|
||||
raw_{std::move(raw)}
|
||||
{}
|
||||
|
||||
void GenericType::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
std::string GenericType::print() const {
|
||||
return this->oid() + " (" + std::to_string(this->raw_content().size()) + " bytes)";
|
||||
}
|
||||
|
||||
|
||||
GenericType::~GenericType() = default;
|
||||
|
||||
}
|
||||
}
|
0
src/PE/signature/attributes/MsCounterSign.cpp
Normal file
0
src/PE/signature/attributes/MsCounterSign.cpp
Normal file
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user