5 #include <stdbool.h> // needs to be above <openarc/arc.h>
7 #include <openarc/arc.h>
9 #include "iobuffer.hpp"
11 #include <fmt/format.h>
12 #include <fmt/ostream.h>
14 #include <glog/logging.h>
17 u_char
* uc(char const* cp
)
19 return reinterpret_cast<u_char
*>(const_cast<char*>(cp
));
22 char const* c(u_char
* ucp
) { return reinterpret_cast<char const*>(ucp
); }
31 get_option(ARC_OPTS_FLAGS
, &arcl_flags
, sizeof(arcl_flags
));
32 arcl_flags
|= ARC_LIBFLAGS_FIXCRLF
;
33 set_option(ARC_OPTS_FLAGS
, &arcl_flags
, sizeof(arcl_flags
));
35 char const* signhdrs
[] = {"cc",
37 "content-transfer-encoding",
63 set_option(ARC_OPTS_SIGNHDRS
, signhdrs
, sizeof(char**));
65 char const* oversignhdrs
[] = {"from", nullptr};
66 set_option(ARC_OPTS_OVERSIGNHDRS
, oversignhdrs
, sizeof(char**));
71 set_option(ARC_OPTS_SIGNHDRS
, nullptr, sizeof(char**));
72 set_option(ARC_OPTS_OVERSIGNHDRS
, nullptr, sizeof(char**));
77 void OpenARC::lib::get_option(int arg
, void* val
, size_t valsz
)
79 CHECK_EQ(arc_options(arc_
, ARC_OP_GETOPT
, arg
, val
, valsz
), ARC_STAT_OK
);
82 void OpenARC::lib::set_option(int arg
, void* val
, size_t valsz
)
84 CHECK_EQ(arc_options(arc_
, ARC_OP_SETOPT
, arg
, val
, valsz
), ARC_STAT_OK
);
87 void OpenARC::lib::set_cv_unkn() { arc_set_cv(msg_
, ARC_CHAIN_UNKNOWN
); }
88 void OpenARC::lib::set_cv_none() { arc_set_cv(msg_
, ARC_CHAIN_NONE
); }
89 void OpenARC::lib::set_cv_fail() { arc_set_cv(msg_
, ARC_CHAIN_FAIL
); }
90 void OpenARC::lib::set_cv_pass() { arc_set_cv(msg_
, ARC_CHAIN_PASS
); }
92 void OpenARC::lib::header(std::string_view header
)
94 CHECK_EQ(arc_header_field(msg_
, uc(header
.data()), header
.length()),
98 void OpenARC::lib::eoh() { CHECK_EQ(arc_eoh(msg_
), ARC_STAT_OK
); }
100 void OpenARC::lib::body(std::string_view body
)
102 CHECK_EQ(arc_body(msg_
, uc(body
.data()), body
.length()), ARC_STAT_OK
);
105 void OpenARC::lib::eom() { CHECK_EQ(arc_eom(msg_
), ARC_STAT_OK
); }
107 OpenARC::sign::sign()
110 msg_
= arc_message(arc_
, ARC_CANON_RELAXED
, ARC_CANON_RELAXED
,
111 ARC_SIGN_RSASHA256
, ARC_MODE_SIGN
, &error
);
115 OpenARC::sign::~sign() { arc_free(msg_
); }
117 bool OpenARC::sign::seal(char const* authservid
,
118 char const* selector
,
125 auto const stat
= arc_getseal(msg_
,
127 const_cast<char*>(authservid
),
128 const_cast<char*>(selector
),
129 const_cast<char*>(domain
),
135 return stat
== ARC_STAT_OK
;
138 static std::string
get_name(arc_hdrfield
* hdr
)
142 auto const p
= c(arc_hdr_name(hdr
, &len
));
143 return std::string(p
, len
);
146 static std::string
get_value(arc_hdrfield
* hdr
)
149 auto const p
= c(arc_hdr_value(hdr
));
150 return std::string(p
, strlen(p
));
153 std::string
OpenARC::sign::name() const { return get_name(seal_
); }
155 std::string
OpenARC::sign::value() const { return get_value(seal_
); }
157 std::vector
<std::string
> OpenARC::sign::whole_seal() const
159 std::vector
<std::string
> hdrs
;
161 auto const re
= std::regex("(?:\\r\\n|\\n|\\r)");
162 for (auto sealhdr
= seal_
; sealhdr
; sealhdr
= arc_hdr_next(sealhdr
)) {
164 fmt::format("{}:{}", get_name(sealhdr
), get_value(sealhdr
));
165 hdrs
.emplace_back(std::regex_replace(hdr
, re
, "\r\n"));
171 OpenARC::verify::verify()
174 msg_
= arc_message(arc_
, ARC_CANON_RELAXED
, ARC_CANON_RELAXED
,
175 ARC_SIGN_RSASHA256
, ARC_MODE_VERIFY
, &error
);
179 OpenARC::verify::~verify() { arc_free(msg_
); }
181 char const* OpenARC::verify::chain_status_str() const
183 return arc_chain_status_str(msg_
);
186 std::string
OpenARC::verify::chain_custody_str() const
188 for (iobuffer
<char> buf
{256}; buf
.size() < 10 * 1024 * 1024;
189 buf
.resize(buf
.size() * 2)) {
190 size_t len
= arc_chain_custody_str(msg_
, uc(buf
.data()), buf
.size());
191 if (len
< buf
.size())
192 return std::string(buf
.data(), len
);
194 LOG(FATAL
) << "custody chain way too large...";