OpenVPN 3 Core Library
Loading...
Searching...
No Matches
peer_fingerprint.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11//
12
13#pragma once
14
16
17namespace openvpn {
18
20{
21 PeerFingerprint(const std::string &fp, const std::size_t size)
22 {
23 std::istringstream input(fp);
24 input.setf(std::ios_base::hex, std::ios_base::basefield);
25 input.unsetf(std::ios_base::skipws);
26 fingerprint_.reserve(size);
27
28 unsigned int val;
29 if (input >> val && val < 256)
30 {
31 fingerprint_.emplace_back(val);
32
33 while (input)
34 {
35 char sep;
36 if (input >> sep >> val && sep == ':' && val < 256)
37 fingerprint_.emplace_back(val);
38 else
39 break;
40 }
41 }
42
43 if (fingerprint_.size() != fingerprint_.capacity())
44 throw option_error(ERR_INVALID_OPTION_VAL, "malformed peer-fingerprint: " + fp);
45 }
46
47 explicit PeerFingerprint(const std::vector<uint8_t> &fingerprint)
48 : fingerprint_(fingerprint)
49 {
50 }
51
52 bool operator==(const PeerFingerprint &that) const
53 {
54 return fingerprint_ == that.fingerprint_;
55 }
56
57 std::string str() const
58 {
59 std::ostringstream output;
60 output.setf(std::ios_base::hex, std::ios_base::basefield);
61 output.fill('0');
62 output.width(2);
63
64 for (const int v : fingerprint_)
65 output << v << ':';
66
67 std::string str(output.str());
68 if (str.size())
69 str.erase(str.size() - 1);
70
71 return str;
72 }
73
74 protected:
75 std::vector<uint8_t> fingerprint_;
76};
77
84{
85 PeerFingerprints() = default;
86
87 PeerFingerprints(const OptionList &opt, const std::size_t fp_size)
88 {
89 const auto indices = opt.get_index_ptr("peer-fingerprint");
90 if (indices == nullptr)
91 return;
92
93 for (const auto i : *indices)
94 {
95 std::istringstream fps(opt[i].get(1, Option::MULTILINE));
96 std::string fp;
97
98 opt[i].touch();
99 while (std::getline(fps, fp))
100 {
101 // Ignore empty lines and comments in fingerprint blocks
102 std::string trimmed = string::trim_copy(fp);
103 if (trimmed.empty()
104 || string::starts_with(trimmed, "#")
105 || string::starts_with(trimmed, ";"))
106 {
107 continue;
108 }
109
110 fingerprints_.emplace_back(PeerFingerprint(fp, fp_size));
111 }
112 }
113 }
114
115 bool match(const PeerFingerprint &fp) const
116 {
117 for (const auto &fingerprint : fingerprints_)
118 {
119 if (fingerprint == fp)
120 return true;
121 }
122
123 return false;
124 }
125
126 explicit operator bool()
127 {
128 return !fingerprints_.empty();
129 }
130
131 protected:
132 std::vector<PeerFingerprint> fingerprints_;
133};
134
135} // namespace openvpn
const IndexList * get_index_ptr(const std::string &name) const
Definition options.hpp:1276
void touch(const std::string &name) const
Definition options.hpp:1456
bool starts_with(const STRING &str, const std::string &prefix)
Definition string.hpp:79
std::string trim_copy(const std::string &str)
Definition string.hpp:559
bool operator==(const PeerFingerprint &that) const
std::vector< uint8_t > fingerprint_
PeerFingerprint(const std::string &fp, const std::size_t size)
PeerFingerprint(const std::vector< uint8_t > &fingerprint)
PeerFingerprints(const OptionList &opt, const std::size_t fp_size)
std::vector< PeerFingerprint > fingerprints_
bool match(const PeerFingerprint &fp) const
static const char * input[]