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