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

randombit / botan / 26141725099

19 May 2026 08:32PM UTC coverage: 89.343% (+0.009%) from 89.334%
26141725099

push

github

web-flow
Merge pull request #5609 from randombit/jack/improve-http

Improve the HTTP 1.0 client used for OCSP/CRL

109341 of 122383 relevant lines covered (89.34%)

11264402.07 hits per line

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

96.34
/src/tests/test_dns_name.cpp
1
/*
2
* (C) 2026 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_DNS_NAME)
10
   #include <botan/dns_name.h>
11
#endif
12

13
namespace Botan_Tests {
14

15
#if defined(BOTAN_HAS_DNS_NAME)
16

17
namespace {
18

19
class DNS_Wildcard_Tests final : public Text_Based_Test {
×
20
   public:
21
      DNS_Wildcard_Tests() : Text_Based_Test("utils/dns_wildcards.vec", "Issued,Hostname") {}
2✔
22

23
      Test::Result run_one_test(const std::string& type, const VarMap& vars) override {
50✔
24
         Test::Result result("DNS wildcard matching");
50✔
25

26
         const auto issued = vars.get_req_str("Issued");
50✔
27
         const auto hostname = vars.get_req_str("Hostname");
50✔
28
         const bool should_accept = (type == "Invalid") ? false : true;
50✔
29

30
         result.test_bool_eq("match", Botan::DNSName::host_wildcard_match(issued, hostname), should_accept);
50✔
31

32
         return result;
50✔
33
      }
50✔
34
};
35

36
BOTAN_REGISTER_TEST("utils", "dns_wildcard", DNS_Wildcard_Tests);
37

38
class DNS_Check_Tests final : public Text_Based_Test {
×
39
   public:
40
      DNS_Check_Tests() : Text_Based_Test("utils/dns.vec", "DNS") {}
2✔
41

42
      Test::Result run_one_test(const std::string& type, const VarMap& vars) override {
66✔
43
         Test::Result result("DNS name validation");
66✔
44

45
         const std::string name = vars.get_req_str("DNS");
66✔
46
         const bool from_string_ok = Botan::DNSName::from_string(name).has_value();
66✔
47
         const bool from_san_string_ok = Botan::DNSName::from_san_string(name).has_value();
66✔
48

49
         if(type == "Valid") {
66✔
50
            // Both factories accept literal hostnames.
51
            result.test_is_true("from_string accepts: " + name, from_string_ok);
23✔
52
            result.test_is_true("from_san_string accepts: " + name, from_san_string_ok);
46✔
53
         } else if(type == "ValidWildcard") {
43✔
54
            // Wildcard label: strict from_string rejects, from_san_string accepts.
55
            result.test_is_false("from_string rejects wildcard: " + name, from_string_ok);
5✔
56
            result.test_is_true("from_san_string accepts wildcard: " + name, from_san_string_ok);
10✔
57
         } else {
58
            // Invalid syntactic form: both reject.
59
            result.test_is_false("from_string rejects: " + name, from_string_ok);
38✔
60
            result.test_is_false("from_san_string rejects: " + name, from_san_string_ok);
76✔
61
         }
62

63
         return result;
66✔
64
      }
198✔
65
};
66

67
BOTAN_REGISTER_TEST("utils", "dns_check", DNS_Check_Tests);
68

69
class DNSName_Tests final : public Test {
1✔
70
   private:
71
      static Test::Result test_parse_valid() {
1✔
72
         Test::Result result("DNSName::from_string valid");
1✔
73

74
         const std::vector<std::pair<std::string, std::string>> cases{
1✔
75
            {"example.com", "example.com"},
76
            {"Example.COM", "example.com"},
77
            {"a.b.c.example.org", "a.b.c.example.org"},
78
            {"sub-domain.example.com", "sub-domain.example.com"},
79
         };
5✔
80

81
         for(const auto& [input, expected] : cases) {
5✔
82
            const auto parsed = Botan::DNSName::from_string(input);
4✔
83
            if(!result.test_is_true("DNSName accepted valid", parsed.has_value())) {
4✔
84
               continue;
×
85
            }
86
            result.test_str_eq("DNSName canonical", parsed->to_string(), expected);
4✔
87
         }
4✔
88

89
         return result;
1✔
90
      }
2✔
91

92
      static Test::Result test_parse_invalid() {
1✔
93
         Test::Result result("DNSName::from_string invalid");
1✔
94

95
         const std::vector<std::string> invalid = {
1✔
96
            "",
97
            ".leading.dot",
98
            "double..dot",
99
            "trailing.dot.",
100
            "with space.example.com",
101
            "label-",
102
            std::string("evil.com\0.example.com", 21),
103
            std::string("a\0b", 3),
104
         };
10✔
105

106
         for(const auto& s : invalid) {
9✔
107
            result.test_is_false("rejects '" + s + "'", Botan::DNSName::from_string(s).has_value());
24✔
108
            result.test_is_false("from_san_string also rejects '" + s + "'",
24✔
109
                                 Botan::DNSName::from_san_string(s).has_value());
16✔
110
         }
111

112
         return result;
1✔
113
      }
5✔
114

115
      static Test::Result test_wildcard_factories() {
1✔
116
         Test::Result result("DNSName::from_san_string and is_wildcard");
1✔
117

118
         // RFC 6125 6.4.3 wildcard form (single "*" in the leftmost label,
119
         // complete or partial): from_string rejects, from_san_string accepts,
120
         // is_wildcard reports true.
121
         const std::vector<std::string> usable_wildcards = {
1✔
122
            "*.example.com",
123
            "*.sub.example.org",
124
            "*",
125
            "foo*.example.com",
126
            "*bar.example.com",
127
            "foo*bar.example.com",
128
         };
1✔
129
         for(const auto& w : usable_wildcards) {
7✔
130
            result.test_is_false("from_string rejects: " + w, Botan::DNSName::from_string(w).has_value());
12✔
131

132
            const auto parsed = Botan::DNSName::from_san_string(w);
6✔
133
            if(result.test_is_true("from_san_string accepts: " + w, parsed.has_value())) {
6✔
134
               result.test_is_true("is_wildcard true for: " + w, parsed->is_wildcard());
12✔
135
            }
136
         }
6✔
137

138
         // Invalid wildcards: multiple "*", or "*" outside the leftmost label.
139
         const std::vector<std::string> malformed = {
1✔
140
            "*.*.example.com",
141
            "foo.*.example.com",
142
            "*foo.*.example.com",
143
            "bar.foo*.example.com",
144
         };
1✔
145
         for(const auto& w : malformed) {
5✔
146
            result.test_is_false("from_san_string rejects malformed: " + w,
8✔
147
                                 Botan::DNSName::from_san_string(w).has_value());
8✔
148
         }
149

150
         // Both constructors accept a plain hostname; is_wildcard is false.
151
         const auto literal = Botan::DNSName::from_san_string("example.com");
1✔
152
         if(result.test_is_true("from_san_string accepts literal", literal.has_value())) {
1✔
153
            result.test_is_false("is_wildcard false for literal", literal->is_wildcard());
1✔
154
         }
155

156
         return result;
2✔
157
      }
1✔
158

159
      static Test::Result test_wildcard() {
1✔
160
         Test::Result result("DNSName::matches_wildcard");
1✔
161

162
         const auto sub = Botan::DNSName::from_string("foo.example.com").value();
2✔
163
         result.test_is_true("*.example.com matches foo.example.com", sub.matches_wildcard("*.example.com"));
1✔
164
         result.test_is_false("*.other.com does not match foo.example.com", sub.matches_wildcard("*.other.com"));
1✔
165

166
         const auto deeper = Botan::DNSName::from_string("a.b.example.com").value();
2✔
167
         result.test_is_false("*.example.com does not match a.b.example.com", deeper.matches_wildcard("*.example.com"));
1✔
168

169
         return result;
1✔
170
      }
1✔
171

172
   public:
173
      std::vector<Test::Result> run() override {
1✔
174
         return {test_parse_valid(), test_parse_invalid(), test_wildcard_factories(), test_wildcard()};
5✔
175
      }
1✔
176
};
177

178
BOTAN_REGISTER_TEST("utils", "dns_name", DNSName_Tests);
179

180
}  // namespace
181

182
#endif
183

184
}  // namespace Botan_Tests
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