Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openpgp parser for keyrings #60

Merged
merged 23 commits into from
Jun 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
68bc350
Add ParserInput, ParserPosition and ParserError.
lambdafu May 16, 2018
157c768
Add custom parser rule rep_max_any to match up to a maximum number of…
lambdafu May 24, 2018
67d136d
Add MultiprecisionInteger.
lambdafu May 16, 2018
8bce7aa
Add ObjectIdentifier.
lambdafu May 16, 2018
5689f4b
Clean up coding standard issues.
lambdafu May 16, 2018
96e05cb
Add parser for MarkerPacket.
lambdafu May 16, 2018
886c62f
Add parser for TrustPacket.
lambdafu May 16, 2018
0087c91
Add parser for UserIdPacket.
lambdafu May 16, 2018
19aeff7
Add parser for ModificationDetectionCodePacket.
lambdafu May 16, 2018
4533cd5
Add parser for PublicKeyPacket and PublicSubkeyPacket.
lambdafu May 16, 2018
a3f7e53
Add Packet::create_or_throw.
lambdafu May 16, 2018
3349f0b
Implement more of packet filter command.
lambdafu May 16, 2018
0ede71b
Fix memory leak in Packet and PacketHeader.
lambdafu Jun 27, 2018
a50d2a9
Add PacketHeader::length().
lambdafu Jun 28, 2018
1dcd62c
Improve the error handling of the OpenPGP parser.
lambdafu Jun 28, 2018
48565d9
Add parser for SignaturePacket.
lambdafu May 16, 2018
ff939b3
Add parser for UserAttributePacket.
lambdafu Jun 27, 2018
f27b262
Turn Botan decoding error into parser error for OIDs (found with afl …
lambdafu Jun 28, 2018
e26f9c1
Enable support for indeterminate length packets (found with afl 2.52b).
lambdafu Jun 28, 2018
9bfc5d6
Catch unrecoverable parser errors (found with afl 2.52b).
lambdafu Jun 28, 2018
adb831a
Fix another issue with invalid OID parsing (found with afl 2.52b).
lambdafu Jun 28, 2018
1949dac
Throw ParserError in EcdhPublicKeyMaterial (found with afl 2.52b).
lambdafu Jun 28, 2018
2ac018a
Check that notation data has no trailing data (found with afl 2.52b).
lambdafu Jun 28, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 115 additions & 3 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,149 @@ set(NeopgHeaders
openpgp/literal_data_packet.h
openpgp/marker_packet.h
openpgp/modification_detection_code_packet.h
openpgp/packet_header.h
openpgp/multiprecision_integer.h
openpgp/object_identifier.h
openpgp/packet.h
openpgp/packet_header.h
openpgp/public_key/data/v3_public_key_data.h
openpgp/public_key/data/v4_public_key_data.h
openpgp/public_key/material/dsa_public_key_material.h
openpgp/public_key/material/ecdh_public_key_material.h
openpgp/public_key/material/ecdsa_public_key_material.h
openpgp/public_key/material/eddsa_public_key_material.h
openpgp/public_key/material/elgamal_public_key_material.h
openpgp/public_key/material/raw_public_key_material.h
openpgp/public_key/material/rsa_public_key_material.h
openpgp/public_key/public_key_data.h
openpgp/public_key/public_key_material.h
openpgp/public_key_packet.h
openpgp/public_subkey_packet.h
openpgp/raw_packet.h
openpgp/signature_packet.h
openpgp/signature/signature_data.h
openpgp/signature/data/v3_signature_data.h
openpgp/signature/data/v4_signature_data.h
openpgp/signature/data/v4_signature_subpacket_data.h
openpgp/signature/material/raw_signature_material.h
openpgp/signature/material/rsa_signature_material.h
openpgp/signature/material/dsa_signature_material.h
openpgp/signature/material/ecdsa_signature_material.h
openpgp/signature/material/eddsa_signature_material.h
openpgp/signature/signature_material.h
openpgp/signature/signature_subpacket.h
openpgp/signature/subpacket/embedded_signature_subpacket.h
openpgp/signature/subpacket/exportable_certification_subpacket.h
openpgp/signature/subpacket/features_subpacket.h
openpgp/signature/subpacket/issuer_subpacket.h
openpgp/signature/subpacket/key_expiration_time_subpacket.h
openpgp/signature/subpacket/key_flags_subpacket.h
openpgp/signature/subpacket/key_server_preferences_subpacket.h
openpgp/signature/subpacket/notation_data_subpacket.h
openpgp/signature/subpacket/policy_uri_subpacket.h
openpgp/signature/subpacket/preferred_compression_algorithms_subpacket.h
openpgp/signature/subpacket/preferred_hash_algorithms_subpacket.h
openpgp/signature/subpacket/preferred_key_server_subpacket.h
openpgp/signature/subpacket/preferred_symmetric_algorithms_subpacket.h
openpgp/signature/subpacket/primary_user_id_subpacket.h
openpgp/signature/subpacket/raw_signature_subpacket.h
openpgp/signature/subpacket/reason_for_revocation_subpacket.h
openpgp/signature/subpacket/regular_expression_subpacket.h
openpgp/signature/subpacket/revocable_subpacket.h
openpgp/signature/subpacket/revocation_key_subpacket.h
openpgp/signature/subpacket/signature_creation_time_subpacket.h
openpgp/signature/subpacket/signature_expiration_time_subpacket.h
openpgp/signature/subpacket/signature_target_subpacket.h
openpgp/signature/subpacket/signers_user_id_subpacket.h
openpgp/signature/subpacket/trust_signature_subpacket.h
openpgp/symmetrically_encrypted_data_packet.h
openpgp/symmetrically_encrypted_integrity_protected_data_packet.h
openpgp/trust_packet.h
openpgp/user_attribute/subpacket/image_attribute_subpacket.h
openpgp/user_attribute/subpacket/raw_user_attribute_subpacket.h
openpgp/user_attribute/user_attribute_subpacket.h
openpgp/user_attribute_packet.h
openpgp/user_id_packet.h
parser/openpgp.h
parser/parser_error.h
parser/parser_input.h
parser/parser_position.h
proto/http.h
proto/uri.h
utils/common.h
utils/stream.h
utils/time.h
)
add_library(neopg
include/neopg/intern/cplusplus.h
crypto/rng.cpp
include/neopg/intern/cplusplus.h
openpgp/compressed_data_packet.cpp
openpgp/literal_data_packet.cpp
openpgp/marker_packet.cpp
openpgp/modification_detection_code_packet.cpp
openpgp/packet_header.cpp
openpgp/multiprecision_integer.cpp
openpgp/object_identifier.cpp
openpgp/packet.cpp
openpgp/packet_header.cpp
openpgp/public_key_packet.cpp
openpgp/public_key/data/v3_public_key_data.cpp
openpgp/public_key/data/v4_public_key_data.cpp
openpgp/public_key/material/dsa_public_key_material.cpp
openpgp/public_key/material/ecdh_public_key_material.cpp
openpgp/public_key/material/ecdsa_public_key_material.cpp
openpgp/public_key/material/eddsa_public_key_material.cpp
openpgp/public_key/material/elgamal_public_key_material.cpp
openpgp/public_key/material/raw_public_key_material.cpp
openpgp/public_key/material/rsa_public_key_material.cpp
openpgp/public_key/public_key_data.cpp
openpgp/public_key/public_key_material.cpp
openpgp/public_subkey_packet.cpp
openpgp/raw_packet.cpp
openpgp/signature_packet.cpp
openpgp/signature/data/v3_signature_data.cpp
openpgp/signature/data/v4_signature_data.cpp
openpgp/signature/data/v4_signature_subpacket_data.cpp
openpgp/signature/material/raw_signature_material.cpp
openpgp/signature/material/rsa_signature_material.cpp
openpgp/signature/material/dsa_signature_material.cpp
openpgp/signature/material/ecdsa_signature_material.cpp
openpgp/signature/material/eddsa_signature_material.cpp
openpgp/signature/signature_data.cpp
openpgp/signature/signature_material.cpp
openpgp/signature/signature_subpacket.cpp
openpgp/signature/subpacket/embedded_signature_subpacket.cpp
openpgp/signature/subpacket/exportable_certification_subpacket.cpp
openpgp/signature/subpacket/features_subpacket.cpp
openpgp/signature/subpacket/issuer_subpacket.cpp
openpgp/signature/subpacket/key_expiration_time_subpacket.cpp
openpgp/signature/subpacket/key_flags_subpacket.cpp
openpgp/signature/subpacket/key_server_preferences_subpacket.cpp
openpgp/signature/subpacket/notation_data_subpacket.cpp
openpgp/signature/subpacket/policy_uri_subpacket.cpp
openpgp/signature/subpacket/preferred_compression_algorithms_subpacket.cpp
openpgp/signature/subpacket/preferred_hash_algorithms_subpacket.cpp
openpgp/signature/subpacket/preferred_key_server_subpacket.cpp
openpgp/signature/subpacket/preferred_symmetric_algorithms_subpacket.cpp
openpgp/signature/subpacket/primary_user_id_subpacket.cpp
openpgp/signature/subpacket/raw_signature_subpacket.cpp
openpgp/signature/subpacket/reason_for_revocation_subpacket.cpp
openpgp/signature/subpacket/regular_expression_subpacket.cpp
openpgp/signature/subpacket/revocable_subpacket.cpp
openpgp/signature/subpacket/revocation_key_subpacket.cpp
openpgp/signature/subpacket/signature_creation_time_subpacket.cpp
openpgp/signature/subpacket/signature_expiration_time_subpacket.cpp
openpgp/signature/subpacket/signature_target_subpacket.cpp
openpgp/signature/subpacket/signers_user_id_subpacket.cpp
openpgp/signature/subpacket/trust_signature_subpacket.cpp
openpgp/symmetrically_encrypted_data_packet.cpp
openpgp/symmetrically_encrypted_integrity_protected_data_packet.cpp
openpgp/trust_packet.cpp
openpgp/user_attribute/subpacket/image_attribute_subpacket.cpp
openpgp/user_attribute/subpacket/raw_user_attribute_subpacket.cpp
openpgp/user_attribute/user_attribute_subpacket.cpp
openpgp/user_attribute_packet.cpp
openpgp/user_id_packet.cpp
parser/openpgp.cpp
parser/parser_input.cpp
proto/http.cpp
proto/uri.cpp
utils/stream.cpp
Expand Down
168 changes: 168 additions & 0 deletions lib/include/neopg/intern/pegtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,176 @@

#pragma once

#include <neopg/parser_error.h>
#include <neopg/parser_input.h>
#include <neopg/parser_position.h>

#include <neopg/public_key_data.h>
#include <neopg/reason_for_revocation_subpacket.h>
#include <neopg/signature_data.h>

#include <botan/loadstor.h>

#include <string>
#include <vector>

// Protect our use of PEGTL from other library users.
#define TAO_PEGTL_NAMESPACE neopg_pegtl
#include <tao/pegtl.hpp>

namespace pegtl = tao::TAO_PEGTL_NAMESPACE;

namespace NeoPG {

class ParserInput::Impl {
public:
pegtl::memory_input<> m_input;
Impl(const char* data, size_t length, const std::string& source)
: m_input{data, length, source} {}
};

class ParserInput::Mark::Impl {
public:
pegtl::internal::marker<pegtl::internal::iterator,
pegtl::rewind_mode::REQUIRED>
m_mark;
Impl(ParserInput& in)
: m_mark{in.m_impl->m_input.mark<pegtl::rewind_mode::REQUIRED>()} {}
};

template <typename Input>
ParserError parser_error(const std::string& msg, const Input& in) {
const pegtl::position in_pos = in.position();
ParserPosition pos(in_pos.source, in_pos.byte);
return ParserError(msg, pos);
}

} // namespace NeoPG

namespace tao {
namespace TAO_PEGTL_NAMESPACE {
// Custom rule to match as many octets as are indicated by length.
template <uint32_t max_length>
struct rep_max_any {
using analyze_t = analysis::generic<analysis::rule_type::OPT>;
template <apply_mode A, rewind_mode M, template <typename...> class Action,
template <typename...> class Control, typename Input,
typename... States>
static bool match(Input& in, States&&... st) {
uint32_t length = in.size(max_length);
if (length > max_length) length = max_length;
in.bump(length);
return true;
}
};

// With C++17, we can derive the parameter T this way:
// template <auto value>
// struct bind {};
// template <typename T, std::vector<uint8_t> T::*Field>
// struct bind<Field> {
// template <typename Input>
// static void apply(const Input& in, T& pkt) {

template <typename T, typename R, R T::*Field>
struct bind {};

template <typename T, std::vector<uint8_t> T::*Field>
struct bind<T, std::vector<uint8_t>, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
auto src = in.begin();
auto ptr = reinterpret_cast<const uint8_t*>(src);
static_assert(sizeof(*src) == sizeof(*ptr), "can't do pointer arithmetic");
(pkt.*Field).assign(ptr, ptr + in.size());
}
};

template <typename T, std::string T::*Field>
struct bind<T, std::string, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
(pkt.*Field).assign(in.begin(), in.end());
}
};

template <typename T, uint32_t T::*Field>
struct bind<T, uint32_t, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
auto src = in.begin();
auto ptr = reinterpret_cast<const uint8_t*>(src);
static_assert(sizeof(*src) == sizeof(*ptr), "can't do pointer arithmetic");
pkt.*Field = Botan::load_be<uint32_t>(ptr, 0);
}
};

template <typename T, uint16_t T::*Field>
struct bind<T, uint16_t, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
auto src = in.begin();
auto ptr = reinterpret_cast<const uint8_t*>(src);
static_assert(sizeof(*src) == sizeof(*ptr), "can't do pointer arithmetic");
pkt.*Field = Botan::load_be<uint16_t>(ptr, 0);
}
};

template <typename T, uint8_t T::*Field>
struct bind<T, uint8_t, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = in.peek_byte(0);
}
};

template <typename T, NeoPG::PublicKeyVersion T::*Field>
struct bind<T, NeoPG::PublicKeyVersion, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = static_cast<NeoPG::PublicKeyVersion>(in.peek_byte());
}
};

template <typename T, NeoPG::PublicKeyAlgorithm T::*Field>
struct bind<T, NeoPG::PublicKeyAlgorithm, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = static_cast<NeoPG::PublicKeyAlgorithm>(in.peek_byte());
}
};

template <typename T, NeoPG::HashAlgorithm T::*Field>
struct bind<T, NeoPG::HashAlgorithm, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = static_cast<NeoPG::HashAlgorithm>(in.peek_byte());
}
};

template <typename T, NeoPG::SignatureType T::*Field>
struct bind<T, NeoPG::SignatureType, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = static_cast<NeoPG::SignatureType>(in.peek_byte());
}
};

template <typename T, NeoPG::SignatureVersion T::*Field>
struct bind<T, NeoPG::SignatureVersion, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = static_cast<NeoPG::SignatureVersion>(in.peek_byte());
}
};

template <typename T, NeoPG::RevocationCode T::*Field>
struct bind<T, NeoPG::RevocationCode, Field> {
template <typename Input>
static void apply(const Input& in, T& pkt) {
pkt.*Field = static_cast<NeoPG::RevocationCode>(in.peek_byte());
}
};

} // namespace TAO_PEGTL_NAMESPACE
} // namespace tao
9 changes: 4 additions & 5 deletions lib/openpgp/compressed_data_packet.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* OpenPGP format
Copyright 2017 The NeoPG developers

NeoPG is released under the Simplified BSD License (see license.txt)
*/
// OpenPGP compressed data packet (implementation)
// Copyright 2017-2018 The NeoPG developers
//
// NeoPG is released under the Simplified BSD License (see license.txt)

#include <neopg/compressed_data_packet.h>
#include <neopg/packet_header.h>
Expand Down
10 changes: 5 additions & 5 deletions lib/openpgp/compressed_data_packet.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* OpenPGP format
Copyright 2017 The NeoPG developers

NeoPG is released under the Simplified BSD License (see license.txt)
*/
// OpenPGP compressed data packet (implementation)
// Copyright 2017-2018 The NeoPG developers
//
// NeoPG is released under the Simplified BSD License (see license.txt)

#pragma once

#include <neopg/packet.h>

#include <vector>

namespace NeoPG {
Expand Down
12 changes: 8 additions & 4 deletions lib/openpgp/compressed_data_packet_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#include <sstream>

#include "gtest/gtest.h"
// OpenPGP compressed data packet (tests)
// Copyright 2017-2018 The NeoPG developers
//
// NeoPG is released under the Simplified BSD License (see license.txt)

#include <neopg/compressed_data_packet.h>

#include <memory>
#include <sstream>

#include "gtest/gtest.h"

using namespace NeoPG;

TEST(NeoPGTest, openpg_compressed_data_packet_test) {
TEST(NeopgTest, openpgp_compressed_data_packet_test) {
{
std::stringstream out;
UncompressedDataPacket packet;
Expand Down
9 changes: 4 additions & 5 deletions lib/openpgp/literal_data_packet.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* OpenPGP format
Copyright 2017 The NeoPG developers

NeoPG is released under the Simplified BSD License (see license.txt)
*/
// OpenPGP literal data packet (implementation)
// Copyright 2017-2018 The NeoPG developers
//
// NeoPG is released under the Simplified BSD License (see license.txt)

#include <neopg/literal_data_packet.h>
#include <neopg/packet_header.h>
Expand Down
Loading