6 #include <stdbool.h> // needs to be above <openarc/arc.h>
8 #include <openarc/arc.h>
10 #include "iobuffer.hpp"
12 #include <fmt/format.h>
13 #include <fmt/ostream.h>
15 #include <glog/logging.h>
18 u_char
* uc(char const* cp
)
20 return reinterpret_cast<u_char
*>(const_cast<char*>(cp
));
23 char const* c(u_char
* ucp
) { return reinterpret_cast<char const*>(ucp
); }
32 get_option(ARC_OPTS_FLAGS
, &arcl_flags
, sizeof(arcl_flags
));
33 arcl_flags
|= ARC_LIBFLAGS_FIXCRLF
;
34 set_option(ARC_OPTS_FLAGS
, &arcl_flags
, sizeof(arcl_flags
));
36 char const* signhdrs
[] = {"cc",
38 "content-transfer-encoding",
64 set_option(ARC_OPTS_SIGNHDRS
, signhdrs
, sizeof(char**));
66 char const* oversignhdrs
[] = {"from", nullptr};
67 set_option(ARC_OPTS_OVERSIGNHDRS
, oversignhdrs
, sizeof(char**));
72 set_option(ARC_OPTS_SIGNHDRS
, nullptr, sizeof(char**));
73 set_option(ARC_OPTS_OVERSIGNHDRS
, nullptr, sizeof(char**));
78 void OpenARC::lib::get_option(int arg
, void* val
, size_t valsz
)
80 CHECK_EQ(arc_options(arc_
, ARC_OP_GETOPT
, arg
, val
, valsz
), ARC_STAT_OK
);
83 void OpenARC::lib::set_option(int arg
, void* val
, size_t valsz
)
85 CHECK_EQ(arc_options(arc_
, ARC_OP_SETOPT
, arg
, val
, valsz
), ARC_STAT_OK
);
88 void OpenARC::lib::set_cv_unkn() { arc_set_cv(msg_
, ARC_CHAIN_UNKNOWN
); }
89 void OpenARC::lib::set_cv_none() { arc_set_cv(msg_
, ARC_CHAIN_NONE
); }
90 void OpenARC::lib::set_cv_fail() { arc_set_cv(msg_
, ARC_CHAIN_FAIL
); }
91 void OpenARC::lib::set_cv_pass() { arc_set_cv(msg_
, ARC_CHAIN_PASS
); }
93 void OpenARC::lib::header(std::string_view header
)
95 CHECK_EQ(arc_header_field(msg_
, uc(header
.data()), header
.length()),
99 void OpenARC::lib::eoh() { CHECK_EQ(arc_eoh(msg_
), ARC_STAT_OK
); }
101 void OpenARC::lib::body(std::string_view body
)
103 CHECK_EQ(arc_body(msg_
, uc(body
.data()), body
.length()), ARC_STAT_OK
);
106 void OpenARC::lib::eom() { CHECK_EQ(arc_eom(msg_
), ARC_STAT_OK
); }
108 OpenARC::sign::sign()
111 msg_
= arc_message(arc_
, ARC_CANON_RELAXED
, ARC_CANON_RELAXED
,
112 ARC_SIGN_RSASHA256
, ARC_MODE_SIGN
, &error
);
116 OpenARC::sign::~sign() { arc_free(msg_
); }
118 bool OpenARC::sign::seal(char const* authservid
,
119 char const* selector
,
126 auto const stat
= arc_getseal(msg_
,
128 const_cast<char*>(authservid
),
129 const_cast<char*>(selector
),
130 const_cast<char*>(domain
),
136 return stat
== ARC_STAT_OK
;
139 static std::string
get_name(arc_hdrfield
* hdr
)
143 auto const p
= c(arc_hdr_name(hdr
, &len
));
144 return std::string(p
, len
);
147 static std::string
get_value(arc_hdrfield
* hdr
)
150 auto const p
= c(arc_hdr_value(hdr
));
151 return std::string(p
, strlen(p
));
154 std::string
OpenARC::sign::name() const { return get_name(seal_
); }
156 std::string
OpenARC::sign::value() const { return get_value(seal_
); }
158 std::vector
<std::string
> OpenARC::sign::whole_seal() const
160 std::vector
<std::string
> hdrs
;
162 auto const re
= std::regex("(?:\\r\\n|\\n|\\r)");
163 for (auto sealhdr
= seal_
; sealhdr
; sealhdr
= arc_hdr_next(sealhdr
)) {
165 fmt::format("{}:{}", get_name(sealhdr
), get_value(sealhdr
));
166 hdrs
.emplace_back(std::regex_replace(hdr
, re
, "\r\n"));
172 OpenARC::verify::verify()
175 msg_
= arc_message(arc_
, ARC_CANON_RELAXED
, ARC_CANON_RELAXED
,
176 ARC_SIGN_RSASHA256
, ARC_MODE_VERIFY
, &error
);
180 OpenARC::verify::~verify() { arc_free(msg_
); }
182 char const* OpenARC::verify::chain_status_str() const
184 return arc_chain_status_str(msg_
);
187 std::string
OpenARC::verify::chain_custody_str() const
189 for (iobuffer
<char> buf
{256}; buf
.size() < 10 * 1024 * 1024;
190 buf
.resize(buf
.size() * 2)) {
191 size_t len
= arc_chain_custody_str(msg_
, uc(buf
.data()), buf
.size());
192 if (len
< buf
.size())
193 return std::string(buf
.data(), len
);
195 LOG(FATAL
) << "custody chain way too large...";