• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.73
/src/lib/pubkey/pem/pem.cpp
1
/*
2
* PEM Encoding/Decoding
3
* (C) 1999-2007 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/pem.h>
9

10
#include <botan/base64.h>
11
#include <botan/data_src.h>
12
#include <botan/exceptn.h>
13
#include <botan/internal/fmt.h>
14

15
namespace Botan::PEM_Code {
16

17
namespace {
18

19
std::string linewrap(size_t width, std::string_view in) {
592✔
20
   std::string out;
592✔
21
   for(size_t i = 0; i != in.size(); ++i) {
2,253,348✔
22
      if(i > 0 && i % width == 0) {
2,252,756✔
23
         out.push_back('\n');
34,853✔
24
      }
25
      out.push_back(in[i]);
2,252,756✔
26
   }
27
   if(!out.empty() && out[out.size() - 1] != '\n') {
592✔
28
      out.push_back('\n');
592✔
29
   }
30

31
   return out;
592✔
32
}
×
33

34
}
35

36
/*
37
* PEM encode BER/DER-encoded objects
38
*/
39
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width) {
592✔
40
   const std::string PEM_HEADER = fmt("-----BEGIN {}-----\n", label);
592✔
41
   const std::string PEM_TRAILER = fmt("-----END {}-----\n", label);
592✔
42

43
   return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER);
1,775✔
44
}
1,184✔
45

46
/*
47
* Decode PEM down to raw BER/DER
48
*/
49
secure_vector<uint8_t> decode_check_label(DataSource& source, std::string_view label_want) {
133✔
50
   std::string label_got;
133✔
51
   secure_vector<uint8_t> ber = decode(source, label_got);
133✔
52
   if(label_got != label_want) {
131✔
53
      throw Decoding_Error(fmt("PEM: Label mismatch, wanted '{}' got '{}'", label_want, label_got));
2✔
54
   }
55

56
   return ber;
130✔
57
}
131✔
58

59
/*
60
* Decode PEM down to raw BER/DER
61
*/
62
secure_vector<uint8_t> decode(DataSource& source, std::string& label) {
12,052✔
63
   const size_t RANDOM_CHAR_LIMIT = 8;
12,052✔
64

65
   label.clear();
12,052✔
66

67
   const std::string PEM_HEADER1 = "-----BEGIN ";
12,052✔
68
   const std::string PEM_HEADER2 = "-----";
13,357✔
69
   size_t position = 0;
12,052✔
70

71
   while(position != PEM_HEADER1.length()) {
148,900✔
72
      uint8_t b;
138,019✔
73
      if(!source.read_byte(b))
138,019✔
74
         throw Decoding_Error("PEM: No PEM header found");
1,168✔
75
      if(static_cast<char>(b) == PEM_HEADER1[position])
136,851✔
76
         ++position;
120,385✔
77
      else if(position >= RANDOM_CHAR_LIMIT)
16,466✔
78
         throw Decoding_Error("PEM: Malformed PEM header");
3✔
79
      else
80
         position = 0;
81
   }
82
   position = 0;
83
   while(position != PEM_HEADER2.length()) {
185,691✔
84
      uint8_t b;
174,833✔
85
      if(!source.read_byte(b))
174,833✔
86
         throw Decoding_Error("PEM: No PEM header found");
13✔
87
      if(static_cast<char>(b) == PEM_HEADER2[position])
174,820✔
88
         ++position;
54,310✔
89
      else if(position)
120,510✔
90
         throw Decoding_Error("PEM: Malformed PEM header");
10✔
91

92
      if(position == 0)
174,810✔
93
         label += static_cast<char>(b);
295,310✔
94
   }
95

96
   std::vector<char> b64;
10,858✔
97

98
   const std::string PEM_TRAILER = fmt("-----END {}-----", label);
111✔
99
   position = 0;
10,858✔
100
   while(position != PEM_TRAILER.length()) {
15,935,084✔
101
      uint8_t b;
15,924,307✔
102
      if(!source.read_byte(b))
15,924,307✔
103
         throw Decoding_Error("PEM: No PEM trailer found");
59✔
104
      if(static_cast<char>(b) == PEM_TRAILER[position])
15,924,248✔
105
         ++position;
270,328✔
106
      else if(position)
15,653,920✔
107
         throw Decoding_Error("PEM: Malformed PEM trailer");
22✔
108

109
      if(position == 0)
15,924,226✔
110
         b64.push_back(b);
15,654,009✔
111
   }
112

113
   return base64_decode(b64.data(), b64.size());
10,777✔
114
}
23,010✔
115

116
secure_vector<uint8_t> decode_check_label(std::string_view pem, std::string_view label_want) {
11✔
117
   DataSource_Memory src(pem);
11✔
118
   return decode_check_label(src, label_want);
11✔
119
}
8✔
120

121
secure_vector<uint8_t> decode(std::string_view pem, std::string& label) {
4✔
122
   DataSource_Memory src(pem);
4✔
123
   return decode(src, label);
4✔
124
}
4✔
125

126
/*
127
* Search for a PEM signature
128
*/
129
bool matches(DataSource& source, std::string_view extra, size_t search_range) {
34,971✔
130
   const std::string PEM_HEADER = fmt("-----BEGIN {}", extra);
34,971✔
131

132
   secure_vector<uint8_t> search_buf(search_range);
34,971✔
133
   const size_t got = source.peek(search_buf.data(), search_buf.size(), 0);
34,971✔
134

135
   if(got < PEM_HEADER.length())
34,971✔
136
      return false;
137

138
   size_t index = 0;
139

140
   for(size_t j = 0; j != got; ++j) {
20,160,991✔
141
      if(static_cast<char>(search_buf[j]) == PEM_HEADER[index]) {
20,126,197✔
142
         ++index;
72,226✔
143
      } else {
144
         index = 0;
145
      }
146

147
      if(index == PEM_HEADER.size()) {
20,126,197✔
148
         return true;
149
      }
150
   }
151

152
   return false;
153
}
34,971✔
154

155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc