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

CommandAPDU reuse data object to avoid PIN copy #80

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

metsma
Copy link
Contributor

@metsma metsma commented Aug 6, 2024

WE2-1007

Signed-off-by: Raul Metsma [email protected]

@@ -140,53 +140,37 @@ struct ResponseApdu
};

/** Struct that wraps command APDUs. */
struct CommandApdu
struct CommandApdu : public byte_vector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inheriting from STL containers is usually frowned upon, see isocpp/CppCoreGuidelines#1232

But I see your point and like this creative approach. Note that std::vector destructor is non-virtual, so deallocating CommandApdu through a byte_vector pointer can lead to undefined behavior, but I think only if we add fields to CommandApdu (possibly in the future). At minimum, both the rationale and undefined behavior risk must be clearly documented.

{
}

CommandApdu(const CommandApdu& other, byte_vector d) :
CommandApdu(other.cla, other.ins, other.p1, other.p2, std::move(d), other.le)
// Case 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we disable copying and assignment and only allow moving?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still many cases where we need make copy. Eg hash inputs are all const ref.

CommandApdu(byte_type cls, byte_type ins, byte_type p1, byte_type p2, byte_vector data,
byte_type le) : CommandApdu {cls, ins, p1, p2, std::move(data)}
{
push_back(le);
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a destructor that erases memory with std::fill(data.begin(), data.end(), 0)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot have destructor because std::vector does not have virtual destructor.
We could do another PR to change all const predefined APDU-s to runtime generated and move ownerships to transfer() where we can clear all buffers.
This change does not clear all PIN copy-s only minimises.

+ bytes2hexstr(command.toBytes()) + "' - expected '"s
+ bytes2hexstr(expectedResponseBytes) + "', got '"s + bytes2hexstr(response.toBytes())
+ " in " + removeAbsolutePathPrefix(file) + ':' + std::to_string(line) + ':'
+ bytes2hexstr(command) + "' - expected '"s + bytes2hexstr(expectedResponseBytes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add a SecureCommandApdu that outputs *** when passed to bytes2hexstr()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again out of scope this change. Only minimise copy-s of PIN memories. The issue already is in master branch

}
insert(begin(), {cls, ins, p1, p2, static_cast<byte_type>(size())});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it so that when using the T=0 protocol, the Le field should be omitted? Shouldn't you handle protocol differences here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have many cases where we send with T=0 Le field and do not have any issues reported:
https://github.com/web-eid/libelectronic-id/blob/main/src/electronic-ids/pcsc/EIDIDEMIA.cpp#L146-L152
https://github.com/web-eid/libelectronic-id/blob/main/src/electronic-ids/pcsc/FinEID.cpp#L161-L162
If this is issue we should handle this in transfer()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants