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

Add basic asymmetric roundtrip tests #4314

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions src/lib/pubkey/pk_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ secure_vector<uint8_t> PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len,
return z;
}

void PK_Ops::Signature::set_associated_data(std::span<const uint8_t> associated_data) {
BOTAN_UNUSED(associated_data);
throw Not_Implemented("This signature scheme does not support labels for signing");
}

void PK_Ops::Verification::set_associated_data(std::span<const uint8_t> associated_data) {
BOTAN_UNUSED(associated_data);
throw Not_Implemented("This signature scheme does not support labels for verification");
}

namespace {

std::unique_ptr<HashFunction> create_signature_hash(std::string_view padding) {
Expand Down
42 changes: 42 additions & 0 deletions src/lib/pubkey/pk_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ class BOTAN_UNSTABLE_API Decryption {
*/
class BOTAN_UNSTABLE_API Verification {
public:
/**
* Incorporate an application-defined associated data into the signature
* verification. This is useful for domain separation, but is not supported
* by all signature schemes. The valid associated data's length is checked
* beforehand, using is_valid_associated_data_length().
*
* Note: The associated data is meant to be kept between individual message
* verifications. It is the implementer's responsibility to handle
* this state correctly.
*/
virtual void set_associated_data(std::span<const uint8_t> label);

/**
* Add more data to the message currently being signed
* @param input the input to be hashed/verified
Expand All @@ -96,6 +108,15 @@ class BOTAN_UNSTABLE_API Verification {
*/
virtual std::string hash_function() const = 0;

/**
* @returns true if the associated data length is valid for this signature scheme.
* Schemes that don't support associated data always return false.
*/
virtual bool is_valid_associated_data_length(size_t length) const {
BOTAN_UNUSED(length);
return false;
}

virtual ~Verification() = default;
};

Expand All @@ -104,6 +125,18 @@ class BOTAN_UNSTABLE_API Verification {
*/
class BOTAN_UNSTABLE_API Signature {
public:
/**
* Incorporate an application-defined label into the signature. This is
* useful for domain separation, but is not supported by all signature
* schemes. The valid length of the label is checked beforehand, using
* is_valid_associated_data_length().
*
* Note: The associated data is meant to be kept between individual message
* signings. It is the implementer's responsibility to handle this
* state correctly.
*/
virtual void set_associated_data(std::span<const uint8_t> associated_data);

/**
* Add more data to the message currently being signed
* @param input the input to be hashed/signed
Expand Down Expand Up @@ -133,6 +166,15 @@ class BOTAN_UNSTABLE_API Signature {
*/
virtual std::string hash_function() const = 0;

/**
* @returns true if the label length is valid for this signature scheme
* Schemes that don't support labels always return false.
*/
virtual bool is_valid_associated_data_length(size_t length) const {
BOTAN_UNUSED(length);
return false;
}

virtual ~Signature() = default;
};

Expand Down
23 changes: 20 additions & 3 deletions src/lib/pubkey/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,13 @@ PK_Signer::~PK_Signer() = default;
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;

void PK_Signer::set_associated_data(std::span<const uint8_t> associated_data) {
if(!is_valid_associated_data_length(associated_data.size())) {
throw Invalid_Argument("PK_Signer: Associated data does not have a supported length");
}
m_op->set_associated_data(associated_data);
}

void PK_Signer::update(std::string_view in) {
this->update(cast_char_ptr_to_uint8(in.data()), in.size());
}
Expand Down Expand Up @@ -313,6 +320,10 @@ size_t PK_Signer::signature_length() const {
}
}

bool PK_Signer::is_valid_associated_data_length(size_t length) const {
return m_op->is_valid_associated_data_length(length);
}

std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
std::vector<uint8_t> sig = m_op->sign(rng);

Expand Down Expand Up @@ -368,9 +379,15 @@ void PK_Verifier::set_input_format(Signature_Format format) {
m_sig_format = format;
}

bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
update(msg, msg_length);
return check_signature(sig, sig_length);
bool PK_Verifier::is_valid_associated_data_length(size_t length) const {
return m_op->is_valid_associated_data_length(length);
}

void PK_Verifier::set_associated_data(std::span<const uint8_t> associated_data) {
if(!is_valid_associated_data_length(associated_data.size())) {
throw Invalid_Argument("PK_Verifier: Associated data does not have a supported length");
}
m_op->set_associated_data(associated_data);
}

void PK_Verifier::update(std::string_view in) {
Expand Down
49 changes: 48 additions & 1 deletion src/lib/pubkey/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ class BOTAN_PUBLIC_API(2, 0) PK_Signer final {
return sign_message(in.data(), in.size(), rng);
}

/**
* Incorporate application-defined associated data into the signature. This
* is useful for (e.g.) domain separation, but is not supported by all
* signature schemes. This must be called at most once and before any calls
* to update().
*
* Unless reset by another call to set_associated_data(), it is kept between
* signature creations.
*
* @sa is_valid_associated_data_length
* @throws Invalid_Argument if associated data is not supported, or the data's
* length is invalid
*
* @param associated_data an application-defined associated data
*/
void set_associated_data(std::span<const uint8_t> associated_data);

/**
* Add a message part (single byte).
* @param in the byte to add
Expand Down Expand Up @@ -258,6 +275,11 @@ class BOTAN_PUBLIC_API(2, 0) PK_Signer final {
*/
std::string hash_function() const;

/**
* @returns true if the associated data's length is valid for this signature scheme
*/
bool is_valid_associated_data_length(size_t length) const;

private:
std::unique_ptr<PK_Ops::Signature> m_op;
Signature_Format m_sig_format;
Expand Down Expand Up @@ -314,7 +336,10 @@ class BOTAN_PUBLIC_API(2, 0) PK_Verifier final {
* @param sig_length the length of the above byte array sig
* @return true if the signature is valid
*/
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length);
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
update(msg, msg_length);
return check_signature(sig, sig_length);
}

/**
* Verify a signature.
Expand All @@ -326,6 +351,23 @@ class BOTAN_PUBLIC_API(2, 0) PK_Verifier final {
return verify_message(msg.data(), msg.size(), sig.data(), sig.size());
}

/**
* Incorporate application-defined associated data into the signature. This
* is useful for (e.g.) domain separation, but is not supported by all
* signature schemes. This must be called at most once and before any calls
* to update().
*
* Unless reset by another call to set_associated_data(), it is kept between
* signature verifications.
*
* @sa is_valid_associated_data_length
* @throws Invalid_Argument if associated data is not supported, or the data's
* length is invalid
*
* @param associated_data an application-defined associated data
*/
void set_associated_data(std::span<const uint8_t> associated_data);

/**
* Add a message part (single byte) of the message corresponding to the
* signature to be verified.
Expand Down Expand Up @@ -385,6 +427,11 @@ class BOTAN_PUBLIC_API(2, 0) PK_Verifier final {
*/
std::string hash_function() const;

/**
* @returns true if the associated data's length is valid for this signature scheme
*/
bool is_valid_associated_data_length(size_t length) const;

private:
std::unique_ptr<PK_Ops::Verification> m_op;
Signature_Format m_sig_format;
Expand Down
Loading
Loading