OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "base/memory/ptr_util.h" |
| 6 |
5 #include "u2f_apdu_command.h" | 7 #include "u2f_apdu_command.h" |
6 | 8 |
7 namespace device { | 9 namespace device { |
8 | 10 |
9 scoped_refptr<U2fApduCommand> U2fApduCommand::CreateFromMessage( | 11 std::unique_ptr<U2fApduCommand> U2fApduCommand::CreateFromMessage( |
10 const std::vector<uint8_t>& message) { | 12 const std::vector<uint8_t>& message) { |
11 uint16_t data_length = 0; | 13 uint16_t data_length = 0; |
12 size_t index = 0; | 14 size_t index = 0; |
13 size_t response_length = 0; | 15 size_t response_length = 0; |
14 std::vector<uint8_t> data; | 16 std::vector<uint8_t> data; |
15 std::vector<uint8_t> suffix; | 17 std::vector<uint8_t> suffix; |
16 | 18 |
17 if (message.size() < kApduMinHeader || message.size() > kApduMaxLength) | 19 if (message.size() < kApduMinHeader || message.size() > kApduMaxLength) |
18 return nullptr; | 20 return nullptr; |
19 uint8_t cla = message[index++]; | 21 uint8_t cla = message[index++]; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 // Non-ISO7816-4 special legacy case where 2 suffix bytes are passed | 66 // Non-ISO7816-4 special legacy case where 2 suffix bytes are passed |
65 // along with a version message | 67 // along with a version message |
66 if (data_length == 0 && ins == kInsU2fVersion) | 68 if (data_length == 0 && ins == kInsU2fVersion) |
67 suffix = {0x0, 0x0}; | 69 suffix = {0x0, 0x0}; |
68 } else { | 70 } else { |
69 return nullptr; | 71 return nullptr; |
70 } | 72 } |
71 break; | 73 break; |
72 } | 74 } |
73 | 75 |
74 return make_scoped_refptr(new U2fApduCommand( | 76 return base::MakeUnique<U2fApduCommand>(cla, ins, p1, p2, response_length, |
75 cla, ins, p1, p2, response_length, std::move(data), std::move(suffix))); | 77 std::move(data), std::move(suffix)); |
76 } | |
77 | |
78 // static | |
79 scoped_refptr<U2fApduCommand> U2fApduCommand::Create() { | |
80 return make_scoped_refptr(new U2fApduCommand()); | |
81 } | 78 } |
82 | 79 |
83 std::vector<uint8_t> U2fApduCommand::GetEncodedCommand() const { | 80 std::vector<uint8_t> U2fApduCommand::GetEncodedCommand() const { |
84 std::vector<uint8_t> encoded = {cla_, ins_, p1_, p2_}; | 81 std::vector<uint8_t> encoded = {cla_, ins_, p1_, p2_}; |
85 | 82 |
86 // If data exists, request size (Lc) is encoded in 3 bytes, with the first | 83 // If data exists, request size (Lc) is encoded in 3 bytes, with the first |
87 // byte always being null, and the other two bytes being a big-endian | 84 // byte always being null, and the other two bytes being a big-endian |
88 // representation of the request size. If data length is 0, response size (Le) | 85 // representation of the request size. If data length is 0, response size (Le) |
89 // will be prepended with a null byte. | 86 // will be prepended with a null byte. |
90 if (data_.size() > 0) { | 87 if (data_.size() > 0) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 ins_(ins), | 120 ins_(ins), |
124 p1_(p1), | 121 p1_(p1), |
125 p2_(p2), | 122 p2_(p2), |
126 response_length_(response_length), | 123 response_length_(response_length), |
127 data_(std::move(data)), | 124 data_(std::move(data)), |
128 suffix_(std::move(suffix)) {} | 125 suffix_(std::move(suffix)) {} |
129 | 126 |
130 U2fApduCommand::~U2fApduCommand() {} | 127 U2fApduCommand::~U2fApduCommand() {} |
131 | 128 |
132 // static | 129 // static |
133 scoped_refptr<U2fApduCommand> U2fApduCommand::CreateRegister( | 130 std::unique_ptr<U2fApduCommand> U2fApduCommand::CreateRegister( |
134 const std::vector<uint8_t>& appid_digest, | 131 const std::vector<uint8_t>& appid_digest, |
135 const std::vector<uint8_t>& challenge_digest) { | 132 const std::vector<uint8_t>& challenge_digest) { |
136 if (appid_digest.size() != kAppIdDigestLen || | 133 if (appid_digest.size() != kAppIdDigestLen || |
137 challenge_digest.size() != kChallengeDigestLen) { | 134 challenge_digest.size() != kChallengeDigestLen) { |
138 return nullptr; | 135 return nullptr; |
139 } | 136 } |
140 | 137 |
141 scoped_refptr<U2fApduCommand> command = Create(); | 138 auto command = base::MakeUnique<U2fApduCommand>(); |
142 std::vector<uint8_t> data(challenge_digest.begin(), challenge_digest.end()); | 139 std::vector<uint8_t> data(challenge_digest.begin(), challenge_digest.end()); |
143 data.insert(data.end(), appid_digest.begin(), appid_digest.end()); | 140 data.insert(data.end(), appid_digest.begin(), appid_digest.end()); |
144 command->set_ins(kInsU2fEnroll); | 141 command->set_ins(kInsU2fEnroll); |
145 command->set_p1(kP1TupRequiredConsumed); | 142 command->set_p1(kP1TupRequiredConsumed); |
146 command->set_data(data); | 143 command->set_data(data); |
147 return command; | 144 return command; |
148 } | 145 } |
149 | 146 |
150 // static | 147 // static |
151 scoped_refptr<U2fApduCommand> U2fApduCommand::CreateVersion() { | 148 std::unique_ptr<U2fApduCommand> U2fApduCommand::CreateVersion() { |
152 scoped_refptr<U2fApduCommand> command = Create(); | 149 auto command = base::MakeUnique<U2fApduCommand>(); |
153 command->set_ins(kInsU2fVersion); | 150 command->set_ins(kInsU2fVersion); |
154 command->set_response_length(kApduMaxResponseLength); | 151 command->set_response_length(kApduMaxResponseLength); |
155 return command; | 152 return command; |
156 } | 153 } |
157 | 154 |
158 // static | 155 // static |
159 scoped_refptr<U2fApduCommand> U2fApduCommand::CreateLegacyVersion() { | 156 std::unique_ptr<U2fApduCommand> U2fApduCommand::CreateLegacyVersion() { |
160 scoped_refptr<U2fApduCommand> command = Create(); | 157 auto command = base::MakeUnique<U2fApduCommand>(); |
161 command->set_ins(kInsU2fVersion); | 158 command->set_ins(kInsU2fVersion); |
162 command->set_response_length(kApduMaxResponseLength); | 159 command->set_response_length(kApduMaxResponseLength); |
163 // Early U2F drafts defined the U2F version command in extended | 160 // Early U2F drafts defined the U2F version command in extended |
164 // length ISO 7816-4 format so 2 additional 0x0 bytes are necessary. | 161 // length ISO 7816-4 format so 2 additional 0x0 bytes are necessary. |
165 // https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-messa
ge-formats-v1.1-id-20160915.html#implementation-considerations | 162 // https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-messa
ge-formats-v1.1-id-20160915.html#implementation-considerations |
166 command->set_suffix(std::vector<uint8_t>(2, 0)); | 163 command->set_suffix(std::vector<uint8_t>(2, 0)); |
167 return command; | 164 return command; |
168 } | 165 } |
169 | 166 |
170 // static | 167 // static |
171 scoped_refptr<U2fApduCommand> U2fApduCommand::CreateSign( | 168 std::unique_ptr<U2fApduCommand> U2fApduCommand::CreateSign( |
172 const std::vector<uint8_t>& appid_digest, | 169 const std::vector<uint8_t>& appid_digest, |
173 const std::vector<uint8_t>& challenge_digest, | 170 const std::vector<uint8_t>& challenge_digest, |
174 const std::vector<uint8_t>& key_handle) { | 171 const std::vector<uint8_t>& key_handle) { |
175 if (appid_digest.size() != kAppIdDigestLen || | 172 if (appid_digest.size() != kAppIdDigestLen || |
176 challenge_digest.size() != kChallengeDigestLen || | 173 challenge_digest.size() != kChallengeDigestLen || |
177 key_handle.size() > kMaxKeyHandleLength) { | 174 key_handle.size() > kMaxKeyHandleLength) { |
178 return nullptr; | 175 return nullptr; |
179 } | 176 } |
180 | 177 |
181 scoped_refptr<U2fApduCommand> command = Create(); | 178 auto command = base::MakeUnique<U2fApduCommand>(); |
182 std::vector<uint8_t> data(challenge_digest.begin(), challenge_digest.end()); | 179 std::vector<uint8_t> data(challenge_digest.begin(), challenge_digest.end()); |
183 data.insert(data.end(), appid_digest.begin(), appid_digest.end()); | 180 data.insert(data.end(), appid_digest.begin(), appid_digest.end()); |
184 data.push_back(static_cast<uint8_t>(key_handle.size())); | 181 data.push_back(static_cast<uint8_t>(key_handle.size())); |
185 data.insert(data.end(), key_handle.begin(), key_handle.end()); | 182 data.insert(data.end(), key_handle.begin(), key_handle.end()); |
186 command->set_ins(kInsU2fSign); | 183 command->set_ins(kInsU2fSign); |
187 command->set_p1(kP1TupRequiredConsumed); | 184 command->set_p1(kP1TupRequiredConsumed); |
188 command->set_data(data); | 185 command->set_data(data); |
189 return command; | 186 return command; |
190 } | 187 } |
191 | 188 |
192 } // namespace device | 189 } // namespace device |
OLD | NEW |