OpenVPN 3 Core Library
Loading...
Searching...
No Matches
cclist.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#ifndef OPENVPN_PKI_CCLIST_H
13#define OPENVPN_PKI_CCLIST_H
14
15#include <string>
16#include <sstream>
17#include <fstream>
18
23
24namespace openvpn {
25
26// Parse a concatenated list of certs and CRLs (PEM format).
27// Abstracts CertList and CRLList, so can be used with any crypto lib.
28// CertList and CRLList must define Item type.
29template <typename CertList, typename CRLList>
31{
32 public:
33 OPENVPN_EXCEPTION(parse_cert_crl_error);
34
36
37 explicit CertCRLListTemplate(const std::string &content, const std::string &title)
38 {
39 from_string(content, title, &certs, &crls);
40 }
41
42 void parse_pem(const std::string &content, const std::string &title)
43 {
44 from_string(content, title, &certs, &crls);
45 }
46
47 void parse_pem_file(const std::string &filename)
48 {
49 from_file(filename, &certs, &crls);
50 }
51
52 std::string render_pem() const
53 {
54 return certs.render_pem() + crls.render_pem();
55 }
56
57 static void from_istream(std::istream &in, const std::string &title, CertList *cert_list, CRLList *crl_list)
58 {
59 static const char cert_start[] = "-----BEGIN CERTIFICATE-----";
60 static const char cert_end[] = "-----END CERTIFICATE-----";
61 static const char crl_start[] = "-----BEGIN X509 CRL-----";
62 static const char crl_end[] = "-----END X509 CRL-----";
63
64 enum
65 {
66 S_OUTSIDE, // outside of CERT or CRL block
67 S_IN_CERT, // in CERT block
68 S_IN_CRL, // in CRL block
69 };
70
71 std::string line;
72 int state = S_OUTSIDE;
73 std::string item = "";
74 int line_num = 0;
75
76 while (std::getline(in, line))
77 {
78 line_num++;
79 string::trim(line);
80 if (state == S_OUTSIDE)
81 {
82 if (line == cert_start)
83 {
84 if (!cert_list)
85 OPENVPN_THROW(parse_cert_crl_error, title << ":" << line_num << " : not expecting a CERT");
86 state = S_IN_CERT;
87 }
88 else if (line == crl_start)
89 {
90 if (!crl_list)
91 OPENVPN_THROW(parse_cert_crl_error, title << ":" << line_num << " : not expecting a CRL");
92 state = S_IN_CRL;
93 }
94 }
95 if (state != S_OUTSIDE)
96 {
97 item += line;
98 item += "\n";
99 }
100 if (state == S_IN_CERT && line == cert_end)
101 {
102 try
103 {
104 cert_list->emplace_back(item, title);
105 }
106 catch (const std::exception &e)
107 {
108 OPENVPN_THROW(parse_cert_crl_error, title << ":" << line_num << " : error parsing CERT: " << e.what());
109 }
110 state = S_OUTSIDE;
111 item = "";
112 }
113 if (state == S_IN_CRL && line == crl_end)
114 {
115 try
116 {
117 crl_list->emplace_back(item);
118 }
119 catch (const std::exception &e)
120 {
121 OPENVPN_THROW(parse_cert_crl_error, title << ":" << line_num << " : error parsing CRL: " << e.what());
122 }
123 state = S_OUTSIDE;
124 item = "";
125 }
126 }
127 if (state != S_OUTSIDE)
128 OPENVPN_THROW(parse_cert_crl_error, title << " : CERT/CRL content ended unexpectedly without END marker");
129 }
130
131 static void from_string(const std::string &content, const std::string &title, CertList *cert_list, CRLList *crl_list = nullptr)
132 {
133 std::stringstream in(content);
134 from_istream(in, title, cert_list, crl_list);
135 }
136
137 static void from_file(const std::string &filename, CertList *cert_list, CRLList *crl_list = nullptr)
138 {
139 std::ifstream ifs(filename.c_str());
140 if (!ifs)
141 OPENVPN_THROW(open_file_error, "cannot open CERT/CRL file " << filename);
142 from_istream(ifs, filename, cert_list, crl_list);
143 if (ifs.bad())
144 OPENVPN_THROW(open_file_error, "cannot read CERT/CRL file " << filename);
145 }
146
147 CertList certs;
148 CRLList crls;
149};
150
151} // namespace openvpn
152
153#endif // OPENVPN_PKI_CCLIST_H
void parse_pem_file(const std::string &filename)
Definition cclist.hpp:47
static void from_istream(std::istream &in, const std::string &title, CertList *cert_list, CRLList *crl_list)
Definition cclist.hpp:57
OPENVPN_EXCEPTION(parse_cert_crl_error)
std::string render_pem() const
Definition cclist.hpp:52
static void from_file(const std::string &filename, CertList *cert_list, CRLList *crl_list=nullptr)
Definition cclist.hpp:137
void parse_pem(const std::string &content, const std::string &title)
Definition cclist.hpp:42
CertCRLListTemplate(const std::string &content, const std::string &title)
Definition cclist.hpp:37
static void from_string(const std::string &content, const std::string &title, CertList *cert_list, CRLList *crl_list=nullptr)
Definition cclist.hpp:131
#define OPENVPN_THROW(exc, stuff)
void trim(std::string &str)
Definition string.hpp:550