Skip to content

Commit

Permalink
Add SignaturePacket.
Browse files Browse the repository at this point in the history
  • Loading branch information
lambdafu committed Jun 26, 2018
1 parent 2b3a65c commit 7b908d8
Show file tree
Hide file tree
Showing 93 changed files with 5,535 additions and 0 deletions.
60 changes: 60 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,36 @@ set(NeopgHeaders
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/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/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
Expand Down Expand Up @@ -71,6 +101,36 @@ add_library(neopg
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/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/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
Expand Down
42 changes: 42 additions & 0 deletions lib/include/neopg/intern/pegtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#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>

Expand Down Expand Up @@ -117,6 +119,14 @@ struct bind<T, uint16_t, Field> {
}
};

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>
Expand All @@ -133,5 +143,37 @@ struct bind<T, NeoPG::PublicKeyAlgorithm, Field> {
}
};

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
144 changes: 144 additions & 0 deletions lib/openpgp/signature/data/v3_signature_data.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// OpenPGP v3 signature data (implementation)
// Copyright 2018 The NeoPG developers
//
// NeoPG is released under the Simplified BSD License (see license.txt)

#include <neopg/v3_signature_data.h>

#include <neopg/intern/cplusplus.h>
#include <neopg/intern/pegtl.h>

#include <algorithm>
#include <iterator>

using namespace NeoPG;

namespace NeoPG {
namespace v3_signature_data {

using namespace pegtl;

// Grammar
struct type : any {};
struct created : bytes<4> {};
struct v3_hashed : seq<one<0x05>, must<type, created>> {};

struct signer : bytes<8> {};
struct quick : bytes<2> {};
struct public_key_algorithm
: uint8::one<static_cast<uint8_t>(PublicKeyAlgorithm::Rsa),
static_cast<uint8_t>(PublicKeyAlgorithm::RsaEncrypt),
static_cast<uint8_t>(PublicKeyAlgorithm::RsaSign),
static_cast<uint8_t>(PublicKeyAlgorithm::Dsa)> {};
struct hash_algorithm : any {};

struct grammar
: must<v3_hashed, signer, public_key_algorithm, hash_algorithm, quick> {};

// Action
template <typename Rule>
struct action : nothing<Rule> {};

template <>
struct action<type>
: bind<V3SignatureData, SignatureType, &V3SignatureData::m_type> {};

template <>
struct action<created>
: bind<V3SignatureData, uint32_t, &V3SignatureData::m_created> {};

template <>
struct action<signer> {
template <typename Input>
static void apply(const Input& in, V3SignatureData& pkt) {
auto begin = reinterpret_cast<const uint8_t*>(in.begin());
std::copy_n(begin, in.size(), std::begin(pkt.m_signer));
}
};

template <>
struct action<public_key_algorithm>
: bind<V3SignatureData, PublicKeyAlgorithm,
&V3SignatureData::m_public_key_algorithm> {};

template <>
struct action<hash_algorithm>
: bind<V3SignatureData, HashAlgorithm, &V3SignatureData::m_hash_algorithm> {
};

template <>
struct action<quick> {
template <typename Input>
static void apply(const Input& in, V3SignatureData& pkt) {
auto begin = reinterpret_cast<const uint8_t*>(in.begin());
std::copy_n(begin, in.size(), std::begin(pkt.m_quick));
}
};

// Control
template <typename Rule>
struct control : pegtl::normal<Rule> {
static const std::string error_message;

template <typename Input, typename... States>
static void raise(const Input& in, States&&...) {
throw parser_error(error_message, in);
}
};

template <>
const std::string control<type>::error_message =
"v3 signature data is missing type";

template <>
const std::string control<created>::error_message =
"v3 signature data is missing created time";

template <>
const std::string control<v3_hashed>::error_message =
"v3 signature data is missing hashed data";

template <>
const std::string control<signer>::error_message =
"v3 signature data is missing signer";

template <>
const std::string control<public_key_algorithm>::error_message =
"v3 signature data is missing or has invalid public key algorithm";

template <>
const std::string control<hash_algorithm>::error_message =
"v3 signature data is missing hash algorithm";

template <>
const std::string control<quick>::error_message =
"v3 signature data is missing quick check data";

} // namespace v3_signature_data
} // namespace NeoPG

std::unique_ptr<V3SignatureData> V3SignatureData::create_or_throw(
ParserInput& in) {
auto packet = make_unique<V3SignatureData>();

pegtl::parse<v3_signature_data::grammar, v3_signature_data::action,
v3_signature_data::control>(in.m_impl->m_input, *packet);
packet->m_signature =
SignatureMaterial::create_or_throw(packet->m_public_key_algorithm, in);

return packet;
}

void V3SignatureData::write(std::ostream& out) const {
out << static_cast<uint8_t>(0x05);
out << static_cast<uint8_t>(m_type);
out << static_cast<uint8_t>(m_created >> 24)
<< static_cast<uint8_t>(m_created >> 16)
<< static_cast<uint8_t>(m_created >> 8)
<< static_cast<uint8_t>(m_created);
out.write(reinterpret_cast<const char*>(m_signer.data()), m_signer.size());
out << static_cast<uint8_t>(m_public_key_algorithm);
out << static_cast<uint8_t>(m_hash_algorithm);
out.write(reinterpret_cast<const char*>(m_quick.data()), m_quick.size());
if (m_signature) m_signature->write(out);
}
74 changes: 74 additions & 0 deletions lib/openpgp/signature/data/v3_signature_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// OpenPGP v3 signature data
// Copyright 2018 The NeoPG developers
//
// NeoPG is released under the Simplified BSD License (see license.txt)

/// \file
/// This file contains the v3 specific data of signature packets.

#pragma once

#include <neopg/signature_data.h>

#include <array>
#include <memory>

namespace NeoPG {

class NEOPG_UNSTABLE_API V3SignatureData : public SignatureData {
public:
/// The signature type.
SignatureType m_type{SignatureType::Binary};

/// The created time of the signature.
uint32_t m_created{0};

/// The signer key id.
std::array<uint8_t, 8> m_signer{{0, 0, 0, 0, 0, 0, 0, 0}};

/// The public key algorithm of the signature.
PublicKeyAlgorithm m_public_key_algorithm{PublicKeyAlgorithm::Rsa};

/// The hash algorithm of the signature.
HashAlgorithm m_hash_algorithm{HashAlgorithm::Sha1};

/// The quick check bytes.
std::array<uint8_t, 2> m_quick{{0, 0}};

/// The algorithm specific signature material.
std::unique_ptr<SignatureMaterial> m_signature;

/// Create new v3 signature data from \p input. Throw an exception on error.
///
/// \param input the parser input to read from
///
/// \return pointer to packet
///
/// \throws ParserError
static std::unique_ptr<V3SignatureData> create_or_throw(ParserInput& input);

/// Write the packet body to the output stream.
///
/// \param out the output stream to write to
void write(std::ostream& out) const override;

/// Return the signature version.
///
/// \return the value SignatureVersion::V3.
SignatureVersion version() const noexcept override {
return SignatureVersion::V3;
}

/// \return the signature type
SignatureType signature_type() const noexcept { return m_type; }

/// \return the public key algorithm
PublicKeyAlgorithm public_key_algorithm() const noexcept {
return m_public_key_algorithm;
}

/// \return the hash algorithm
HashAlgorithm hash_algorithm() const noexcept { return m_hash_algorithm; }
};

} // namespace NeoPG
Loading

0 comments on commit 7b908d8

Please sign in to comment.