1
#pragma once
2

            
3
#include "envoy/extensions/matching/common_inputs/ssl/v3/ssl_inputs.pb.h"
4
#include "envoy/extensions/matching/common_inputs/ssl/v3/ssl_inputs.pb.validate.h"
5
#include "envoy/matcher/matcher.h"
6

            
7
#include "absl/strings/str_join.h"
8

            
9
namespace Envoy {
10
namespace Ssl {
11
namespace Matching {
12

            
13
template <class InputType, class ProtoType, class MatchingDataType>
14
class BaseFactory : public Matcher::DataInputFactory<MatchingDataType> {
15
protected:
16
96
  explicit BaseFactory(const std::string& name) : name_(name) {}
17

            
18
public:
19
1626
  std::string name() const override { return "envoy.matching.inputs." + name_; }
20

            
21
  Matcher::DataInputFactoryCb<MatchingDataType>
22
6
  createDataInputFactoryCb(const Protobuf::Message&, ProtobufMessage::ValidationVisitor&) override {
23
6
    return []() { return std::make_unique<InputType>(); };
24
6
  };
25
63
  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
26
63
    return std::make_unique<ProtoType>();
27
63
  }
28

            
29
private:
30
  const std::string name_;
31
};
32

            
33
template <class MatchingDataType> class UriSanInput : public Matcher::DataInput<MatchingDataType> {
34
public:
35
6
  Matcher::DataInputGetResult get(const MatchingDataType& data) const override {
36
6
    const auto& ssl = data.ssl();
37
6
    if (!ssl) {
38
1
      return Matcher::DataInputGetResult::NoData(Matcher::DataAvailability::NotAvailable);
39
1
    }
40
5
    const auto& uri = ssl->uriSanPeerCertificate();
41
5
    if (!uri.empty()) {
42
4
      return Matcher::DataInputGetResult::CreateString(absl::StrJoin(uri, ","));
43
4
    }
44
1
    return Matcher::DataInputGetResult::NoData();
45
5
  }
46
};
47

            
48
template <class MatchingDataType>
49
class UriSanInputBaseFactory
50
    : public BaseFactory<UriSanInput<MatchingDataType>,
51
                         envoy::extensions::matching::common_inputs::ssl::v3::UriSanInput,
52
                         MatchingDataType> {
53
public:
54
  UriSanInputBaseFactory()
55
32
      : BaseFactory<UriSanInput<MatchingDataType>,
56
32
                    envoy::extensions::matching::common_inputs::ssl::v3::UriSanInput,
57
32
                    MatchingDataType>("uri_san") {}
58
};
59

            
60
template <class MatchingDataType> class DnsSanInput : public Matcher::DataInput<MatchingDataType> {
61
public:
62
6
  Matcher::DataInputGetResult get(const MatchingDataType& data) const override {
63
6
    const auto& ssl = data.ssl();
64
6
    if (!ssl) {
65
1
      return Matcher::DataInputGetResult::NoData(Matcher::DataAvailability::NotAvailable);
66
1
    }
67
5
    const auto& dns = ssl->dnsSansPeerCertificate();
68
5
    if (!dns.empty()) {
69
4
      return Matcher::DataInputGetResult::CreateString(absl::StrJoin(dns, ","));
70
4
    }
71
1
    return Matcher::DataInputGetResult::NoData();
72
5
  }
73
};
74

            
75
template <class MatchingDataType>
76
class DnsSanInputBaseFactory
77
    : public BaseFactory<DnsSanInput<MatchingDataType>,
78
                         envoy::extensions::matching::common_inputs::ssl::v3::DnsSanInput,
79
                         MatchingDataType> {
80
public:
81
  DnsSanInputBaseFactory()
82
32
      : BaseFactory<DnsSanInput<MatchingDataType>,
83
32
                    envoy::extensions::matching::common_inputs::ssl::v3::DnsSanInput,
84
32
                    MatchingDataType>("dns_san") {}
85
};
86

            
87
template <class MatchingDataType> class SubjectInput : public Matcher::DataInput<MatchingDataType> {
88
public:
89
5
  Matcher::DataInputGetResult get(const MatchingDataType& data) const override {
90
5
    const auto& ssl = data.ssl();
91
5
    if (!ssl) {
92
1
      return Matcher::DataInputGetResult::NoData(Matcher::DataAvailability::NotAvailable);
93
1
    }
94
4
    const std::string& subject = ssl->subjectPeerCertificate();
95
4
    if (!subject.empty()) {
96
3
      return Matcher::DataInputGetResult::CreateStringView(subject);
97
3
    }
98
1
    return Matcher::DataInputGetResult::NoData();
99
4
  }
100
};
101

            
102
template <class MatchingDataType>
103
class SubjectInputBaseFactory
104
    : public BaseFactory<SubjectInput<MatchingDataType>,
105
                         envoy::extensions::matching::common_inputs::ssl::v3::SubjectInput,
106
                         MatchingDataType> {
107
public:
108
  SubjectInputBaseFactory()
109
32
      : BaseFactory<SubjectInput<MatchingDataType>,
110
32
                    envoy::extensions::matching::common_inputs::ssl::v3::SubjectInput,
111
32
                    MatchingDataType>("subject") {}
112
};
113

            
114
} // namespace Matching
115
} // namespace Ssl
116
} // namespace Envoy