1
#include "source/common/tls/cert_validator/san_matcher.h"
2

            
3
#include <memory>
4

            
5
#include "envoy/config/core/v3/extension.pb.h"
6
#include "envoy/extensions/transport_sockets/tls/v3/common.pb.h"
7
#include "envoy/registry/registry.h"
8
#include "envoy/ssl/certificate_validation_context_config.h"
9

            
10
#include "source/common/tls/utility.h"
11

            
12
namespace Envoy {
13
namespace Extensions {
14
namespace TransportSockets {
15
namespace Tls {
16

            
17
2563
bool StringSanMatcher::typeCompatible(const GENERAL_NAME* general_name) const {
18
2563
  if (general_name->type != general_name_type_) {
19
34
    return false;
20
34
  }
21
2529
  if (general_name->type == GEN_OTHERNAME) {
22
123
    if (OBJ_cmp(general_name->d.otherName->type_id, general_name_oid_.get())) {
23
99
      return false;
24
99
    }
25
123
  }
26

            
27
2430
  return true;
28
2529
}
29

            
30
178
bool StringSanMatcher::match(GENERAL_NAME const* general_name) const {
31
178
  if (!typeCompatible(general_name)) {
32
118
    return false;
33
118
  }
34

            
35
60
  return matcher_.match(Utility::generalNameAsString(general_name));
36
178
}
37

            
38
bool StringSanMatcher::match(GENERAL_NAME const* general_name,
39
2385
                             const StreamInfo::StreamInfo& stream_info) const {
40
2385
  if (!typeCompatible(general_name)) {
41
15
    return false;
42
15
  }
43

            
44
2370
  Matchers::StringMatcher::Context context{makeOptRef(stream_info)};
45
2370
  return matcher_.match(Utility::generalNameAsString(general_name), context);
46
2385
}
47

            
48
8143
bool DnsExactStringSanMatcher::match(GENERAL_NAME const* general_name) const {
49
8143
  if (general_name->type != GEN_DNS) {
50
4069
    return false;
51
4069
  }
52
4074
  return Utility::dnsNameMatch(dns_exact_match_, Utility::generalNameAsString(general_name));
53
8143
}
54

            
55
SanMatcherPtr createStringSanMatcher(
56
    envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher const& matcher,
57
5172
    Server::Configuration::CommonFactoryContext& context) {
58
  // Verify that a new san type has not been added.
59
5172
  static_assert(envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::SanType_MAX ==
60
5172
                5);
61

            
62
5172
  switch (matcher.san_type()) {
63
    PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
64
1631
  case envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::DNS:
65
    // For DNS SAN, if the StringMatcher type is exact, we have to follow DNS matching semantics.
66
1631
    if (matcher.matcher().match_pattern_case() ==
67
1631
        envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kExact) {
68
1229
      return SanMatcherPtr{std::make_unique<DnsExactStringSanMatcher>(matcher.matcher().exact())};
69
1607
    } else {
70
402
      return SanMatcherPtr{std::make_unique<StringSanMatcher>(GEN_DNS, matcher.matcher(), context)};
71
402
    }
72
1136
  case envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::EMAIL:
73
1136
    return SanMatcherPtr{std::make_unique<StringSanMatcher>(GEN_EMAIL, matcher.matcher(), context)};
74
1255
  case envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::URI:
75
1255
    return SanMatcherPtr{std::make_unique<StringSanMatcher>(GEN_URI, matcher.matcher(), context)};
76
1146
  case envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::IP_ADDRESS:
77
1146
    return SanMatcherPtr{std::make_unique<StringSanMatcher>(GEN_IPADD, matcher.matcher(), context)};
78
2
  case envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::OTHER_NAME: {
79
    // Invalid/Empty OID returns a nullptr from OBJ_txt2obj
80
2
    bssl::UniquePtr<ASN1_OBJECT> oid(OBJ_txt2obj(matcher.oid().c_str(), 0));
81
2
    if (oid == nullptr) {
82
1
      return nullptr;
83
1
    }
84
1
    return SanMatcherPtr{std::make_unique<StringSanMatcher>(GEN_OTHERNAME, matcher.matcher(),
85
1
                                                            context, std::move(oid))};
86
2
  }
87
  case envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher::SAN_TYPE_UNSPECIFIED:
88
    PANIC("unhandled value");
89
5172
  }
90
2
  return nullptr;
91
5172
}
92

            
93
} // namespace Tls
94
} // namespace TransportSockets
95
} // namespace Extensions
96
} // namespace Envoy