blob: a43a7c5133e47a01cbdf7eaeb5d5ce05c6cea4b4 [file] [log] [blame]
piperc7929e072017-01-20 01:04:491// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Jun Choi3545f502018-03-14 01:30:005#ifndef COMPONENTS_APDU_APDU_COMMAND_H_
6#define COMPONENTS_APDU_APDU_COMMAND_H_
piperc7929e072017-01-20 01:04:497
piperc6de00822017-03-22 16:37:328#include <cinttypes>
Jun Choib49986d2018-03-13 20:01:449#include <utility>
piperc7929e072017-01-20 01:04:4910#include <vector>
11
Balazs Engedyd531bf42018-03-12 22:51:4212#include "base/component_export.h"
Jun Choi3545f502018-03-14 01:30:0013#include "base/containers/span.h"
piperc7929e072017-01-20 01:04:4914#include "base/gtest_prod_util.h"
Jun Choi3545f502018-03-14 01:30:0015#include "base/macros.h"
16#include "base/optional.h"
piperc7929e072017-01-20 01:04:4917
Jun Choi3545f502018-03-14 01:30:0018namespace apdu {
piperc7929e072017-01-20 01:04:4919
20// APDU commands are defined as part of ISO 7816-4. Commands can be serialized
Pavel Kalinnikov0f59e1b2017-09-08 20:31:1721// into either short length encodings, where the maximum data length is 256
piperc7929e072017-01-20 01:04:4922// bytes, or an extended length encoding, where the maximum data length is 65536
23// bytes. This class implements only the extended length encoding. Serialized
24// commands consist of a CLA byte, denoting the class of instruction, an INS
25// byte, denoting the instruction code, P1 and P2, each one byte denoting
26// instruction parameters, a length field (Lc), a data field of length Lc, and
27// a maximum expected response length (Le).
Jun Choi3545f502018-03-14 01:30:0028class COMPONENT_EXPORT(APDU) ApduCommand {
piperc7929e072017-01-20 01:04:4929 public:
Jun Choib49986d2018-03-13 20:01:4430 // Constructs an APDU command from the serialized message data.
Jun Choi3545f502018-03-14 01:30:0031 static base::Optional<ApduCommand> CreateFromMessage(
32 base::span<const uint8_t> message);
Jun Choib49986d2018-03-13 20:01:4433
Jun Choi3545f502018-03-14 01:30:0034 ApduCommand();
35 ApduCommand(uint8_t cla,
36 uint8_t ins,
37 uint8_t p1,
38 uint8_t p2,
39 size_t response_length,
40 std::vector<uint8_t> data);
41 ApduCommand(ApduCommand&& that);
42 ApduCommand& operator=(ApduCommand&& that);
43 ~ApduCommand();
piperc6de00822017-03-22 16:37:3244
Pavel Kalinnikov0f59e1b2017-09-08 20:31:1745 // Returns serialized message data.
piperc7929e072017-01-20 01:04:4946 std::vector<uint8_t> GetEncodedCommand() const;
Jun Choib49986d2018-03-13 20:01:4447
piperc7929e072017-01-20 01:04:4948 void set_cla(uint8_t cla) { cla_ = cla; }
49 void set_ins(uint8_t ins) { ins_ = ins; }
50 void set_p1(uint8_t p1) { p1_ = p1; }
51 void set_p2(uint8_t p2) { p2_ = p2; }
Jun Choib49986d2018-03-13 20:01:4452 void set_data(std::vector<uint8_t> data) { data_ = std::move(data); }
piperc7929e072017-01-20 01:04:4953 void set_response_length(size_t response_length) {
54 response_length_ = response_length;
55 }
Jun Choief10f862017-11-09 01:04:3356
Jun Choib49986d2018-03-13 20:01:4457 uint8_t cla() const { return cla_; }
58 uint8_t ins() const { return ins_; }
59 uint8_t p1() const { return p1_; }
60 uint8_t p2() const { return p2_; }
61 size_t response_length() const { return response_length_; }
62 const std::vector<uint8_t>& data() const { return data_; }
piperc7929e072017-01-20 01:04:4963
Adam Langley1d08c092018-03-27 09:16:3764 static constexpr size_t kApduMaxResponseLength = 65536;
65
piperc7929e072017-01-20 01:04:4966 private:
Jun Choi3545f502018-03-14 01:30:0067 FRIEND_TEST_ALL_PREFIXES(ApduTest, TestDeserializeBasic);
68 FRIEND_TEST_ALL_PREFIXES(ApduTest, TestDeserializeComplex);
69 FRIEND_TEST_ALL_PREFIXES(ApduTest, TestSerializeEdgeCases);
Arnar Birgissonedc8fe42018-03-13 00:52:2670
piperc7929e072017-01-20 01:04:4971 static constexpr size_t kApduMinHeader = 4;
72 static constexpr size_t kApduMaxHeader = 7;
Jun Choi3545f502018-03-14 01:30:0073 static constexpr size_t kApduCommandDataOffset = 7;
74 static constexpr size_t kApduCommandLengthOffset = 5;
75
piperc7929e072017-01-20 01:04:4976 // As defined in ISO7816-4, extended length APDU request data is limited to
77 // 16 bits in length with a maximum value of 65535. Response data length is
78 // also limited to 16 bits in length with a value of 0x0000 corresponding to
Pavel Kalinnikov0f59e1b2017-09-08 20:31:1779 // a length of 65536.
piperc7929e072017-01-20 01:04:4980 static constexpr size_t kApduMaxDataLength = 65535;
piperc7929e072017-01-20 01:04:4981 static constexpr size_t kApduMaxLength =
82 kApduMaxDataLength + kApduMaxHeader + 2;
Pavel Kalinnikov0f59e1b2017-09-08 20:31:1783
Jun Choi3545f502018-03-14 01:30:0084 uint8_t cla_ = 0;
85 uint8_t ins_ = 0;
86 uint8_t p1_ = 0;
87 uint8_t p2_ = 0;
88 size_t response_length_ = 0;
piperc7929e072017-01-20 01:04:4989 std::vector<uint8_t> data_;
Jun Choi3545f502018-03-14 01:30:0090
91 DISALLOW_COPY_AND_ASSIGN(ApduCommand);
piperc7929e072017-01-20 01:04:4992};
Pavel Kalinnikov0f59e1b2017-09-08 20:31:1793
Jun Choi3545f502018-03-14 01:30:0094} // namespace apdu
piperc7929e072017-01-20 01:04:4995
Jun Choi3545f502018-03-14 01:30:0096#endif // COMPONENTS_APDU_APDU_COMMAND_H_