stdex Additional custom or not Standard C++ covered algorithms

Loading...
Searching...
No Matches
minisign.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#pragma once
7
8#include "assert.hpp"
9#include "base64.hpp"
10#include "compat.hpp"
11#include "parser.hpp"
12#include "stream.hpp"
13#include <stdint.h>
14#include <string>
15#include <vector>
16
17 namespace stdex
18{
19 namespace minisign
20 {
24 class untrusted_comment : public stdex::parser::parser
25 {
26 protected:
27 virtual bool do_match(
28 _In_reads_or_z_opt_(end) const char* text,
29 _In_ size_t start = 0,
30 _In_ size_t end = SIZE_MAX,
31 _In_ int flags = stdex::parser::match_default)
32 {
33 _Unreferenced_(flags);
34 stdex_assert(text || start + 17 >= end);
35 if (start + 17 < end &&
36 text[start + 0] == 'u' &&
37 text[start + 1] == 'n' &&
38 text[start + 2] == 't' &&
39 text[start + 3] == 'r' &&
40 text[start + 4] == 'u' &&
41 text[start + 5] == 's' &&
42 text[start + 6] == 't' &&
43 text[start + 7] == 'e' &&
44 text[start + 8] == 'd' &&
45 text[start + 9] == ' ' &&
46 text[start + 10] == 'c' &&
47 text[start + 11] == 'o' &&
48 text[start + 12] == 'm' &&
49 text[start + 13] == 'm' &&
50 text[start + 14] == 'e' &&
51 text[start + 15] == 'n' &&
52 text[start + 16] == 't' &&
53 text[start + 17] == ':')
54 {
55 this->interval.end = (this->interval.start = start) + 18;
56 return true;
57 }
58 this->interval.invalidate();
59 return false;
60 }
61 };
62
66 class line_break : public stdex::parser::parser
67 {
68 protected:
69 virtual bool do_match(
70 _In_reads_or_z_opt_(end) const char* text,
71 _In_ size_t start = 0,
72 _In_ size_t end = SIZE_MAX,
73 _In_ int flags = stdex::parser::match_default)
74 {
75 _Unreferenced_(flags);
76 stdex_assert(text || start + 1 >= end);
77 if (start + 1 < end &&
78 text[start + 0] == '\r' &&
79 text[start + 1] == '\n')
80 {
81 this->interval.end = (this->interval.start = start) + 2;
82 return true;
83 }
84 stdex_assert(text || start >= end);
85 if (start < end && text[start] == '\n') {
86 this->interval.end = (this->interval.start = start) + 1;
87 return true;
88 }
89 this->interval.invalidate();
90 return false;
91 }
92 };
93
102 inline void parse_minisig(_Inout_ stdex::stream::basic& minisig, _Out_ uint8_t& algorithm, _Out_writes_all_(8) uint8_t key_id[8], _Out_writes_all_(64) uint8_t signature[64])
103 {
104 std::vector<uint8_t> data;
105 minisign::untrusted_comment untrusted_comment;
106 std::string line;
107 for (;;) {
108 minisig.readln(line);
109 if (!minisig.ok())
110 break;
111 if (line.empty() ||
112 untrusted_comment.match(line.data(), 0, line.size()))
113 continue;
114 stdex::base64_dec decoder; bool is_last;
115 decoder.decode(data, is_last, line.data(), line.size());
116 break;
117 }
118 if (data.size() < 74)
119 throw std::runtime_error("Minisign signature is too short");
120 if (data[0] != 'E')
121 throw std::runtime_error("not a Minisign signature");
122 algorithm = data[1];
123 memcpy(&key_id[0], &data[2], 8);
124 memcpy(&signature[0], &data[10], 64);
125 }
126 }
127}
128
stdex::base64_dec
Base64 decoding session.
Definition base64.hpp:275
stdex::base64_dec::decode
void decode(std::vector< T_to, AX > &out, bool &is_last, const T_from *data, size_t size)
Decodes one block of information, and appends it to the output.
Definition base64.hpp:297
stdex::minisign::line_break
Test for CRLF or LF.
Definition minisign.hpp:67
stdex::minisign::untrusted_comment
Test for "untrusted comment:".
Definition minisign.hpp:25
stdex::parser::basic_parser< char >
stdex::stream::basic
Basic stream operations.
Definition stream.hpp:85
stdex::interval
Numerical interval.
Definition interval.hpp:18
stdex::interval::end
T end
interval end
Definition interval.hpp:20
stdex::interval::invalidate
void invalidate()
Invalidates interval.
Definition interval.hpp:59
stdex::interval::start
T start
interval start
Definition interval.hpp:19