blob: 1fd28fbf6eea94ca578d211f784f97c90e685efe [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// Copyright 2011 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BSSL_PKI_PEM_H_
6#define BSSL_PKI_PEM_H_
7
Bob Beckbc97b7a2023-04-18 08:35:15 -06008#include <stddef.h>
9
10#include <string>
Bob Beck3cd30cc2023-11-22 16:59:00 -070011#include <string_view>
Bob Beckbc97b7a2023-04-18 08:35:15 -060012#include <vector>
13
Bob Beck3cd30cc2023-11-22 16:59:00 -070014#include <openssl/base.h>
Bob Beckbc97b7a2023-04-18 08:35:15 -060015
16namespace bssl {
17
18// PEMTokenizer is a utility class for the parsing of data encapsulated
19// using RFC 1421, Privacy Enhancement for Internet Electronic Mail. It
20// does not implement the full specification, most notably it does not
21// support the Encapsulated Header Portion described in Section 4.4.
22class OPENSSL_EXPORT PEMTokenizer {
23 public:
24 // Create a new PEMTokenizer that iterates through |str| searching for
25 // instances of PEM encoded blocks that are of the |allowed_block_types|.
26 // |str| must remain valid for the duration of the PEMTokenizer.
27 PEMTokenizer(std::string_view str,
Bob Beck5c7a2a02023-11-20 17:28:21 -070028 const std::vector<std::string> &allowed_block_types);
Bob Beckbc97b7a2023-04-18 08:35:15 -060029
Bob Beck5c7a2a02023-11-20 17:28:21 -070030 PEMTokenizer(const PEMTokenizer &) = delete;
31 PEMTokenizer &operator=(const PEMTokenizer &) = delete;
Bob Beckbc97b7a2023-04-18 08:35:15 -060032
33 ~PEMTokenizer();
34
35 // Attempts to decode the next PEM block in the string. Returns false if no
36 // PEM blocks can be decoded. The decoded PEM block will be available via
37 // data().
38 bool GetNext();
39
40 // Returns the PEM block type (eg: CERTIFICATE) of the last successfully
41 // decoded PEM block.
42 // GetNext() must have returned true before calling this method.
Bob Beck5c7a2a02023-11-20 17:28:21 -070043 const std::string &block_type() const { return block_type_; }
Bob Beckbc97b7a2023-04-18 08:35:15 -060044
45 // Returns the raw, Base64-decoded data of the last successfully decoded
46 // PEM block.
47 // GetNext() must have returned true before calling this method.
Bob Beck5c7a2a02023-11-20 17:28:21 -070048 const std::string &data() const { return data_; }
Bob Beckbc97b7a2023-04-18 08:35:15 -060049
50 private:
51 void Init(std::string_view str,
Bob Beck5c7a2a02023-11-20 17:28:21 -070052 const std::vector<std::string> &allowed_block_types);
Bob Beckbc97b7a2023-04-18 08:35:15 -060053
54 // A simple cache of the allowed PEM header and footer for a given PEM
55 // block type, so that it is only computed once.
56 struct PEMType;
57
58 // The string to search, which must remain valid for as long as this class
59 // is around.
60 std::string_view str_;
61
62 // The current position within |str_| that searching should begin from,
63 // or std::string_view::npos if iteration is complete
64 std::string_view::size_type pos_;
65
66 // The type of data that was encoded, as indicated in the PEM
67 // Pre-Encapsulation Boundary (eg: CERTIFICATE, PKCS7, or
68 // PRIVACY-ENHANCED MESSAGE).
69 std::string block_type_;
70
71 // The types of PEM blocks that are allowed. PEM blocks that are not of
72 // one of these types will be skipped.
73 std::vector<PEMType> block_types_;
74
75 // The raw (Base64-decoded) data of the last successfully decoded block.
76 std::string data_;
77};
78
79// Encodes |data| in the encapsulated message format described in RFC 1421,
80// with |type| as the PEM block type (eg: CERTIFICATE).
81OPENSSL_EXPORT std::string PEMEncode(std::string_view data,
Bob Beck5c7a2a02023-11-20 17:28:21 -070082 const std::string &type);
Bob Beckbc97b7a2023-04-18 08:35:15 -060083
Bob Beck5c7a2a02023-11-20 17:28:21 -070084} // namespace bssl
Bob Beckbc97b7a2023-04-18 08:35:15 -060085
86#endif // BSSL_PKI_PEM_H_