Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1523)

Unified Diff: device/u2f/u2f_apdu_command.cc

Issue 2665493002: Add builders to APDU command class (Closed)
Patch Set: Add suffix for legacy version case and add additional unittests Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « device/u2f/u2f_apdu_command.h ('k') | device/u2f/u2f_apdu_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/u2f/u2f_apdu_command.cc
diff --git a/device/u2f/u2f_apdu_command.cc b/device/u2f/u2f_apdu_command.cc
index cd854825e53d8d64367ea5fe2dd4f22f385f44fa..2bb8efe6e1c40a6efdbe8451ca94688b6f854833 100644
--- a/device/u2f/u2f_apdu_command.cc
+++ b/device/u2f/u2f_apdu_command.cc
@@ -9,8 +9,10 @@ namespace device {
scoped_refptr<U2fApduCommand> U2fApduCommand::CreateFromMessage(
const std::vector<uint8_t>& message) {
uint16_t data_length = 0;
- size_t index = 0, response_length = 0;
+ size_t index = 0;
+ size_t response_length = 0;
std::vector<uint8_t> data;
+ std::vector<uint8_t> suffix;
if (message.size() < kApduMinHeader || message.size() > kApduMaxLength)
return nullptr;
@@ -59,14 +61,18 @@ scoped_refptr<U2fApduCommand> U2fApduCommand::CreateFromMessage(
// Defined in ISO7816-4
if (response_length == 0)
response_length = kApduMaxResponseLength;
+ // Non-ISO7816-4 special legacy case where 2 suffix bytes are passed
+ // along with a version message
+ if (data_length == 0 && ins == kInsU2fVersion)
+ suffix = {0x0, 0x0};
} else {
return nullptr;
}
break;
}
- return make_scoped_refptr(
- new U2fApduCommand(cla, ins, p1, p2, response_length, std::move(data)));
+ return make_scoped_refptr(new U2fApduCommand(
+ cla, ins, p1, p2, response_length, std::move(data), std::move(suffix)));
}
// static
@@ -98,6 +104,8 @@ std::vector<uint8_t> U2fApduCommand::GetEncodedCommand() const {
encoded.push_back((response_length_ >> 8) & 0xff);
encoded.push_back(response_length_ & 0xff);
}
+ // Add suffix, if required, for legacy compatibility
+ encoded.insert(encoded.end(), suffix_.begin(), suffix_.end());
return encoded;
}
@@ -109,14 +117,76 @@ U2fApduCommand::U2fApduCommand(uint8_t cla,
uint8_t p1,
uint8_t p2,
size_t response_length,
- std::vector<uint8_t> data)
+ std::vector<uint8_t> data,
+ std::vector<uint8_t> suffix)
: cla_(cla),
ins_(ins),
p1_(p1),
p2_(p2),
response_length_(response_length),
- data_(std::move(data)) {}
+ data_(std::move(data)),
+ suffix_(std::move(suffix)) {}
U2fApduCommand::~U2fApduCommand() {}
+// static
+scoped_refptr<U2fApduCommand> U2fApduCommand::CreateRegister(
+ const std::vector<uint8_t>& appid_digest,
+ const std::vector<uint8_t>& challenge_digest) {
+ if (appid_digest.size() != kAppIdDigestLen ||
+ challenge_digest.size() != kChallengeDigestLen) {
+ return nullptr;
+ }
+
+ scoped_refptr<U2fApduCommand> command = Create();
+ std::vector<uint8_t> data(challenge_digest.begin(), challenge_digest.end());
+ data.insert(data.end(), appid_digest.begin(), appid_digest.end());
+ command->set_ins(kInsU2fEnroll);
+ command->set_p1(kP1TupRequiredConsumed);
+ command->set_data(data);
+ return command;
+}
+
+// static
+scoped_refptr<U2fApduCommand> U2fApduCommand::CreateVersion() {
+ scoped_refptr<U2fApduCommand> command = Create();
+ command->set_ins(kInsU2fVersion);
+ command->set_response_length(kApduMaxResponseLength);
+ return command;
+}
+
+// static
+scoped_refptr<U2fApduCommand> U2fApduCommand::CreateLegacyVersion() {
+ scoped_refptr<U2fApduCommand> command = Create();
+ command->set_ins(kInsU2fVersion);
+ command->set_response_length(kApduMaxResponseLength);
+ // Early U2F drafts defined the U2F version command in extended
+ // length ISO 7816-4 format so 2 additional 0x0 bytes are necessary.
+ // https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html#implementation-considerations
+ command->set_suffix(std::vector<uint8_t>(2, 0));
+ return command;
+}
+
+// static
+scoped_refptr<U2fApduCommand> U2fApduCommand::CreateSign(
+ const std::vector<uint8_t>& appid_digest,
+ const std::vector<uint8_t>& challenge_digest,
+ const std::vector<uint8_t>& key_handle) {
+ if (appid_digest.size() != kAppIdDigestLen ||
+ challenge_digest.size() != kChallengeDigestLen ||
+ key_handle.size() > kMaxKeyHandleLength) {
+ return nullptr;
+ }
+
+ scoped_refptr<U2fApduCommand> command = Create();
+ std::vector<uint8_t> data(challenge_digest.begin(), challenge_digest.end());
+ data.insert(data.end(), appid_digest.begin(), appid_digest.end());
+ data.push_back(static_cast<uint8_t>(key_handle.size()));
+ data.insert(data.end(), key_handle.begin(), key_handle.end());
+ command->set_ins(kInsU2fSign);
+ command->set_p1(kP1TupRequiredConsumed);
+ command->set_data(data);
+ return command;
+}
+
} // namespace device
« no previous file with comments | « device/u2f/u2f_apdu_command.h ('k') | device/u2f/u2f_apdu_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698