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.empty())
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 const std::string trimmed = string::trim_copy(fp);
103 if (trimmed.empty() || trimmed.starts_with("#") || trimmed.starts_with(";"))
104 {
105 continue;
106 }
107
108 fingerprints_.emplace_back(PeerFingerprint(fp, fp_size));
109 }
110 }
111 }
112
113 bool match(const PeerFingerprint &fp) const
114 {
115 for (const auto &fingerprint : fingerprints_)
116 {
117 if (fingerprint == fp)
118 return true;
119 }
120
121 return false;
122 }
123
124 explicit operator bool()
125 {
126 return !fingerprints_.empty();
127 }
128
129 protected:
130 std::vector<PeerFingerprint> fingerprints_;
131};
132
133} // namespace openvpn
const IndexList * get_index_ptr(const std::string &name) const
Definition options.hpp:1260
void touch(const std::string &name) const
Definition options.hpp:1435
std::string trim_copy(const std::string &str)
Definition string.hpp:519
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[]