Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
asn1_message.h
1 #ifndef ASN1_MESSAGE_H_
2 #define ASN1_MESSAGE_H_
3 #include <boost/intrusive_ptr.hpp>
4 
5 #include "AKIpUptaneMes.h"
6 #include "AKTlsConfig.h"
7 
8 class Asn1Message;
9 
10 template <typename T>
11 class Asn1Sub {
12  public:
13  Asn1Sub(boost::intrusive_ptr<Asn1Message> root, T* me) : root_(std::move(root)), me_(me) {}
14 
15  T& operator*() const {
16  assert(me_ != nullptr);
17  return *me_;
18  }
19 
20  T* operator->() const {
21  assert(me_ != nullptr);
22  return me_;
23  }
24 
25  private:
26  boost::intrusive_ptr<Asn1Message> root_;
27  T* me_;
28 };
29 
30 /**
31  * Reference counted holder for the top-level ASN1 message structure.
32  */
33 
34 class Asn1Message {
35  public:
36  using Ptr = boost::intrusive_ptr<Asn1Message>;
37  template <typename T>
38  using SubPtr = Asn1Sub<T>;
39 
40  Asn1Message(const Asn1Message&) = delete;
41  Asn1Message operator=(const Asn1Message&) = delete;
42 
43  /**
44  * Create a new Asn1Message, in order to fill it with data and send it
45  */
46  static Asn1Message::Ptr Empty() { return new Asn1Message(); }
47 
48  /**
49  * Destructively copy from a raw msg pointer created by parsing an incomming
50  * message. This takes ownership of the contents of the message, and sets
51  * *msg=nullptr to make this fact clear.
52  */
53  static Asn1Message::Ptr FromRaw(AKIpUptaneMes_t** msg) { return new Asn1Message(msg); }
54 
55  ~Asn1Message() { ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_AKIpUptaneMes, &msg_); }
56  friend void intrusive_ptr_add_ref(Asn1Message* m) { m->ref_count_++; }
57  friend void intrusive_ptr_release(Asn1Message* m) {
58  if (--m->ref_count_ == 0) {
59  delete m;
60  }
61  }
62 
63  AKIpUptaneMes_PR present() const { return msg_.present; }
64  void present(AKIpUptaneMes_PR present) { msg_.present = present; }
65 
66 #define ASN1_MESSAGE_DEFINE_ACCESSOR(MessageType, FieldName) \
67  SubPtr<MessageType> FieldName() { \
68  return Asn1Sub<MessageType>(this, &msg_.choice.FieldName); /* NOLINT(cppcoreguidelines-pro-type-union-access) */ \
69  }
70 
71  ASN1_MESSAGE_DEFINE_ACCESSOR(AKGetInfoReqMes_t, getInfoReq);
72  ASN1_MESSAGE_DEFINE_ACCESSOR(AKGetInfoRespMes_t, getInfoResp);
73  ASN1_MESSAGE_DEFINE_ACCESSOR(AKManifestReqMes_t, manifestReq);
74  ASN1_MESSAGE_DEFINE_ACCESSOR(AKManifestRespMes_t, manifestResp);
75  ASN1_MESSAGE_DEFINE_ACCESSOR(AKPutMetaReqMes_t, putMetaReq);
76  ASN1_MESSAGE_DEFINE_ACCESSOR(AKPutMetaRespMes_t, putMetaResp);
77  ASN1_MESSAGE_DEFINE_ACCESSOR(AKSendFirmwareReqMes_t, sendFirmwareReq);
78  ASN1_MESSAGE_DEFINE_ACCESSOR(AKSendFirmwareRespMes_t, sendFirmwareResp);
79  ASN1_MESSAGE_DEFINE_ACCESSOR(AKInstallReqMes_t, installReq);
80  ASN1_MESSAGE_DEFINE_ACCESSOR(AKInstallRespMes_t, installResp);
81 
82  /**
83  * The underlying message structure. This is public to simplify calls to
84  * der_encode()/der_decode(). The Asn1<T> smart pointers should be used
85  * in preference to poking around inside msg_.
86  */
87  AKIpUptaneMes_t msg_{}; // Note that this must be zero-initialized
88 
89  private:
90  int ref_count_{0};
91 
92  Asn1Message() = default;
93 
94  explicit Asn1Message(AKIpUptaneMes_t** msg) {
95  if (msg != nullptr && *msg != nullptr) {
96  memmove(&msg_, *msg, sizeof(AKIpUptaneMes_t));
97  free(*msg); // Be careful. This needs to be the same free() used in der_decode
98  *msg = nullptr;
99  }
100  }
101 };
102 
103 /**
104  * Adaptor to write output of der_encode to a string
105  */
106 int Asn1StringAppendCallback(const void* buffer, size_t size, void* priv);
107 
108 /**
109  * Adaptor to write output of der_encode to a socket
110  * priv is a pointer to an int holding the fd
111  */
112 int Asn1SocketWriteCallback(const void* buffer, size_t size, void* priv);
113 
114 /**
115  * Convert OCTET_STRING_t into std::string
116  */
117 std::string ToString(const OCTET_STRING_t& octet_str);
118 
119 void SetString(OCTET_STRING_t* dest, const std::string& str);
120 
121 /**
122  * Open a TCP connection to client; send a message and wait for a
123  * response.
124  */
125 Asn1Message::Ptr Asn1Rpc(const Asn1Message::Ptr& tx, int con_fd);
126 Asn1Message::Ptr Asn1Rpc(const Asn1Message::Ptr& tx, const std::pair<std::string, uint16_t>& addr);
127 #endif // ASN1_MESSAGE_H_
Asn1Message::Empty
static Asn1Message::Ptr Empty()
Create a new Asn1Message, in order to fill it with data and send it.
Definition: asn1_message.h:46
Asn1Message
Reference counted holder for the top-level ASN1 message structure.
Definition: asn1_message.h:34
Asn1Message::FromRaw
static Asn1Message::Ptr FromRaw(AKIpUptaneMes_t **msg)
Destructively copy from a raw msg pointer created by parsing an incomming message.
Definition: asn1_message.h:53
Asn1Sub
Definition: asn1_message.h:11
Asn1Message::msg_
AKIpUptaneMes_t msg_
The underlying message structure.
Definition: asn1_message.h:87