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

randombit / botan / 11844561993

14 Nov 2024 07:58PM UTC coverage: 91.178% (+0.1%) from 91.072%
11844561993

Pull #4435

github

web-flow
Merge 81dcb29da into e430f157a
Pull Request #4435: Test duration values ​​are now presented in seconds with six digits of precision. Tests without time measurements have been edited.

91856 of 100744 relevant lines covered (91.18%)

9311006.71 hits per line

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

79.19
/src/tests/test_certstor_system.cpp
1
/*
2
* (C) 1999-2021 Jack Lloyd
3
* (C) 2019,2021 René Meusel
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include "tests.h"
9

10
#if defined(BOTAN_HAS_CERTSTOR_SYSTEM)
11

12
   #include "test_certstor_utils.h"
13
   #include <botan/ber_dec.h>
14
   #include <botan/certstor_system.h>
15
   #include <botan/der_enc.h>
16
   #include <botan/hex.h>
17
   #include <memory>
18

19
namespace Botan_Tests {
20

21
namespace {
22

23
Test::Result find_certificate_by_pubkey_sha1(Botan::Certificate_Store& certstore) {
1✔
24
   Test::Result result("System Certificate Store - Find Certificate by SHA1(pubkey)");
1✔
25
   result.start_timer();
1✔
26

27
   try {
1✔
28
      result.start_timer();
1✔
29
      auto cert = certstore.find_cert_by_pubkey_sha1(get_key_id());
1✔
30
      result.end_timer();
1✔
31

32
      if(result.test_not_nullopt("found certificate", cert)) {
3✔
33
         auto cns = cert->subject_dn().get_attribute("CN");
1✔
34
         result.test_is_eq("exactly one CN", cns.size(), size_t(1));
1✔
35
         result.test_eq("CN", cns.front(), get_subject_cn());
2✔
36
      }
1✔
37
   } catch(std::exception& e) {
1✔
38
      result.test_failure(e.what());
×
39
   }
×
40

41
   result.test_throws("on invalid SHA1 hash data", [&] { certstore.find_cert_by_pubkey_sha1({}); });
3✔
42

43
   result.end_timer();
1✔
44
   return result;
1✔
45
}
×
46

47
Test::Result find_certificate_by_pubkey_sha1_with_unmatching_key_id(Botan::Certificate_Store& certstore) {
1✔
48
   Test::Result result("System Certificate Store - Find Certificate by SHA1(pubkey) - regression test for GH #2779");
1✔
49
   result.start_timer();
1✔
50

51
   if(!certstore.find_cert(get_dn_of_cert_with_different_key_id(), {}).has_value()) {
2✔
52
      result.note_missing("OS does not trust the certificate used for this regression test, skipping");
×
53
      return result;
×
54
   }
55

56
   try {
1✔
57
      result.start_timer();
1✔
58
      auto cert = certstore.find_cert_by_pubkey_sha1(get_pubkey_sha1_of_cert_with_different_key_id());
1✔
59
      result.end_timer();
1✔
60

61
      if(result.test_not_nullopt("found certificate", cert)) {
3✔
62
         auto cns = cert->subject_dn().get_attribute("CN");
1✔
63
         result.test_is_eq("exactly one CN", cns.size(), size_t(1));
1✔
64
         result.test_eq("CN", cns.front(), "SecureTrust CA");
2✔
65
      }
1✔
66
   } catch(std::exception& e) {
1✔
67
      result.test_failure(e.what());
×
68
   }
×
69
   
70
   result.end_timer();
1✔
71
   return result;
72
}
×
73

74
Test::Result find_cert_by_subject_dn(Botan::Certificate_Store& certstore) {
1✔
75
   Test::Result result("System Certificate Store - Find Certificate by subject DN");
1✔
76
   result.start_timer();
1✔
77

78
   try {
1✔
79
      auto dn = get_dn();
1✔
80

81
      result.start_timer();
1✔
82
      auto cert = certstore.find_cert(dn, std::vector<uint8_t>());
1✔
83
      result.end_timer();
1✔
84

85
      if(result.test_not_nullopt("found certificate", cert)) {
3✔
86
         auto cns = cert->subject_dn().get_attribute("CN");
1✔
87
         result.test_is_eq("exactly one CN", cns.size(), size_t(1));
1✔
88
         result.test_eq("CN", cns.front(), get_subject_cn());
2✔
89
      }
1✔
90
   } catch(std::exception& e) {
1✔
91
      result.test_failure(e.what());
×
92
   }
×
93

94
   result.end_timer();
1✔
95
   return result;
1✔
96
}
×
97

98
Test::Result find_cert_by_utf8_subject_dn(Botan::Certificate_Store& certstore) {
1✔
99
   Test::Result result("System Certificate Store - Find Certificate by UTF8 subject DN");
1✔
100
   result.start_timer();
1✔
101

102
   try {
1✔
103
      const auto DNs = get_utf8_dn_alternatives();
1✔
104

105
      unsigned int found = 0;
1✔
106

107
      result.start_timer();
1✔
108
      for(const auto& [cn, dn] : DNs) {
6✔
109
         if(auto cert = certstore.find_cert(dn, {})) {
10✔
110
            auto cns = cert->subject_dn().get_attribute("CN");
5✔
111
            result.test_is_eq("exactly one CN", cns.size(), size_t(1));
5✔
112
            result.test_eq("CN", cns.front(), cn);
5✔
113

114
            ++found;
5✔
115
         }
10✔
116
      }
117
      result.end_timer();
1✔
118

119
      if(found == 0) {
1✔
120
         std::string tried_cns;
×
121
         for(const auto& [cn, dn] : DNs) {
×
122
            tried_cns += cn + ", ";
×
123
         }
124

125
         result.test_note("Tried to find any of those CNs: " + tried_cns);
×
126
         result.test_failure("Did not find any certificate via an UTF-8 encoded DN");
×
127
      }
×
128

129
      result.test_gte("found at least one certificate", found, 1);
1✔
130
   } catch(std::exception& e) {
1✔
131
      result.test_failure(e.what());
×
132
   }
×
133

134
   result.end_timer();
1✔
135
   return result;
1✔
136
}
×
137

138
Test::Result find_cert_by_subject_dn_and_key_id(Botan::Certificate_Store& certstore) {
1✔
139
   Test::Result result("System Certificate Store - Find Certificate by subject DN and key ID");
1✔
140
   result.start_timer();
1✔
141
   
142
   try {
1✔
143
      auto dn = get_dn();
1✔
144

145
      result.start_timer();
1✔
146
      auto cert = certstore.find_cert(dn, get_key_id());
1✔
147
      result.end_timer();
1✔
148

149
      if(result.test_not_nullopt("found certificate", cert)) {
3✔
150
         auto cns = cert->subject_dn().get_attribute("CN");
1✔
151
         result.test_is_eq("exactly one CN", cns.size(), size_t(1));
1✔
152
         result.test_eq("CN", cns.front(), get_subject_cn());
2✔
153
      }
1✔
154
   } catch(std::exception& e) {
1✔
155
      result.test_failure(e.what());
×
156
   }
×
157

158
   result.end_timer();
1✔
159
   return result;
1✔
160
}
×
161

162
Test::Result find_certs_by_subject_dn_and_key_id(Botan::Certificate_Store& certstore) {
1✔
163
   Test::Result result("System Certificate Store - Find Certificates by subject DN and key ID");
2✔
164
   result.start_timer();
1✔
165

166
   try {
1✔
167
      auto dn = get_dn();
1✔
168

169
      result.start_timer();
1✔
170
      auto certs = certstore.find_all_certs(dn, get_key_id());
1✔
171
      result.end_timer();
1✔
172

173
      if(result.confirm("result not empty", !certs.empty()) &&
2✔
174
         result.test_eq("exactly one certificate", certs.size(), 1)) {
2✔
175
         auto cns = certs.front().subject_dn().get_attribute("CN");
1✔
176
         result.test_is_eq("exactly one CN", cns.size(), size_t(1));
1✔
177
         result.test_eq("CN", cns.front(), get_subject_cn());
2✔
178
      }
1✔
179
   } catch(std::exception& e) {
1✔
180
      result.test_failure(e.what());
×
181
   }
×
182

183
   result.end_timer();
1✔
184
   return result;
1✔
185
}
×
186

187
Test::Result find_all_certs_by_subject_dn(Botan::Certificate_Store& certstore) {
1✔
188
   Test::Result result("System Certificate Store - Find all Certificates by subject DN");
1✔
189
   result.start_timer();
1✔
190

191
   try {
1✔
192
      auto dn = get_dn();
1✔
193

194
      result.start_timer();
1✔
195
      auto certs = certstore.find_all_certs(dn, std::vector<uint8_t>());
1✔
196
      result.end_timer();
1✔
197

198
      // check for duplications
199
      sort(certs.begin(), certs.end());
1✔
200
      for(size_t i = 1; i < certs.size(); ++i) {
1✔
201
         if(certs[i - 1] == certs[i]) {
×
202
            result.test_failure("find_all_certs produced duplicated result");
×
203
         }
204
      }
205

206
      if(result.confirm("result not empty", !certs.empty())) {
2✔
207
         auto cns = certs.front().subject_dn().get_attribute("CN");
1✔
208
         result.test_gte("at least one CN", cns.size(), size_t(1));
1✔
209
         result.test_eq("CN", cns.front(), get_subject_cn());
2✔
210
      }
1✔
211
   } catch(std::exception& e) {
1✔
212
      result.test_failure(e.what());
×
213
   }
×
214

215
   result.end_timer();
1✔
216
   return result;
1✔
217
}
×
218

219
Test::Result find_all_subjects(Botan::Certificate_Store& certstore) {
1✔
220
   Test::Result result("System Certificate Store - Find all Certificate Subjects");
1✔
221
   result.start_timer();
1✔
222

223
   try {
1✔
224
      result.start_timer();
1✔
225
      auto subjects = certstore.all_subjects();
1✔
226
      result.end_timer();
1✔
227

228
      if(result.confirm("result not empty", !subjects.empty())) {
2✔
229
         auto dn = get_dn();
1✔
230
         auto needle = std::find_if(
1✔
231
            subjects.cbegin(), subjects.cend(), [=](const Botan::X509_DN& subject) { return subject == dn; });
88✔
232

233
         if(result.confirm("found expected certificate", needle != subjects.end())) {
2✔
234
            result.confirm("expected certificate", *needle == dn);
2✔
235
         }
236
      }
1✔
237
   } catch(std::exception& e) {
1✔
238
      result.test_failure(e.what());
×
239
   }
×
240

241
   result.end_timer();
1✔
242
   return result;
1✔
243
}
×
244

245
Test::Result no_certificate_matches(Botan::Certificate_Store& certstore) {
1✔
246
   Test::Result result("System Certificate Store - can deal with no matches (regression test)");
1✔
247
   result.start_timer();
1✔
248

249
   try {
1✔
250
      auto dn = get_unknown_dn();
1✔
251
      auto kid = get_unknown_key_id();
1✔
252

253
      result.start_timer();
1✔
254
      auto certs = certstore.find_all_certs(dn, kid);
1✔
255
      auto cert = certstore.find_cert(dn, kid);
1✔
256
      auto pubk_cert = certstore.find_cert_by_pubkey_sha1(kid);
1✔
257
      result.end_timer();
1✔
258

259
      result.confirm("find_all_certs did not find the dummy", certs.empty());
2✔
260
      result.confirm("find_cert did not find the dummy", !cert);
2✔
261
      result.confirm("find_cert_by_pubkey_sha1 did not find the dummy", !pubk_cert);
2✔
262
   } catch(std::exception& e) {
2✔
263
      result.test_failure(e.what());
×
264
   }
×
265

266
   result.end_timer();
1✔
267
   return result;
1✔
268
}
×
269

270
   #if defined(BOTAN_HAS_CERTSTOR_MACOS)
271

272
Test::Result certificate_matching_with_dn_normalization(Botan::Certificate_Store& certstore) {
273
   Test::Result result("System Certificate Store - normalization of X.509 DN (regression test)");
274
   result.start_timer();
275

276
   try {
277
      auto dn = get_skewed_dn();
278

279
      result.start_timer();
280
      auto certs = certstore.find_all_certs(dn, std::vector<uint8_t>());
281
      auto cert = certstore.find_cert(dn, std::vector<uint8_t>());
282
      result.end_timer();
283

284
      if(result.confirm("find_all_certs did find the skewed DN", !certs.empty()) &&
285
         result.confirm("find_cert did find the skewed DN", cert.has_value())) {
286
         result.test_eq(
287
            "it is the correct cert", certs.front().subject_dn().get_first_attribute("CN"), get_subject_cn());
288
         result.test_eq("it is the correct cert", cert->subject_dn().get_first_attribute("CN"), get_subject_cn());
289
      }
290
   } catch(std::exception& e) {
291
      result.test_failure(e.what());
292
   }
293

294
   result.end_timer();
295
   return result;
296
}
297

298
   #endif
299

300
class Certstor_System_Tests final : public Test {
×
301
   public:
302
      std::vector<Test::Result> run() override {
1✔
303
         Test::Result open_result("System Certificate Store - Open Keychain");
1✔
304
         open_result.start_timer();
1✔
305

306
         std::unique_ptr<Botan::Certificate_Store> system;
1✔
307

308
         try {
1✔
309
            open_result.start_timer();
1✔
310
            system = std::make_unique<Botan::System_Certificate_Store>();
1✔
311
            open_result.end_timer();
1✔
312
         } catch(Botan::Not_Implemented& e) {
×
313
            BOTAN_UNUSED(e);
×
314
            open_result.test_note("Skipping due to not available in current build");
×
315
            return {open_result};
×
316
         } catch(std::exception& e) {
×
317
            open_result.test_failure(e.what());
×
318
            return {open_result};
×
319
         }
×
320

321
         open_result.test_success();
1✔
322

323
         std::vector<Test::Result> results;
1✔
324
         results.push_back(open_result);
1✔
325

326
         results.push_back(find_certificate_by_pubkey_sha1(*system));
2✔
327
         results.push_back(find_certificate_by_pubkey_sha1_with_unmatching_key_id(*system));
2✔
328
         results.push_back(find_cert_by_subject_dn(*system));
2✔
329
         results.push_back(find_cert_by_subject_dn_and_key_id(*system));
2✔
330
         results.push_back(find_all_certs_by_subject_dn(*system));
2✔
331
         results.push_back(find_certs_by_subject_dn_and_key_id(*system));
2✔
332
         results.push_back(find_all_subjects(*system));
2✔
333
         results.push_back(no_certificate_matches(*system));
2✔
334
         results.push_back(find_cert_by_utf8_subject_dn(*system));
2✔
335
   #if defined(BOTAN_HAS_CERTSTOR_MACOS)
336
         results.push_back(certificate_matching_with_dn_normalization(*system));
337
   #endif
338

339
         open_result.end_timer();
1✔
340
         return results;
1✔
341
      }
2✔
342
};
343

344
BOTAN_REGISTER_TEST("x509", "certstor_system", Certstor_System_Tests);
345

346
}  // namespace
347

348
}  // namespace Botan_Tests
349

350
#endif
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

© 2025 Coveralls, Inc