aboutsummaryrefslogtreecommitdiffstats
path: root/src/x509find.cpp
blob: 9a6f75fe46bec2a72ffa3d335f4f5004ecffd689 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*************************************************
* X.509 Certificate Store Searching Source File  *
* (C) 1999-2006 The Botan Project                *
*************************************************/

#include <botan/x509stor.h>
#include <botan/charset.h>
#include <algorithm>
#include <memory>

namespace Botan {

namespace X509_Store_Search {

namespace {

/*************************************************
* Comparison Function Pointer                    *
*************************************************/
typedef bool (*compare_fn)(const std::string&, const std::string&);

/*************************************************
* Compare based on case-insensive substrings     *
*************************************************/
bool substring_match(const std::string& searching_for,
                     const std::string& found)
   {
   if(std::search(found.begin(), found.end(), searching_for.begin(),
                  searching_for.end(), Charset::caseless_cmp) != found.end())
      return true;
   return false;
   }

/*************************************************
* Compare based on case-insensive match          *
*************************************************/
bool ignore_case(const std::string& searching_for, const std::string& found)
   {
   if(searching_for.size() != found.size())
      return false;

   return std::equal(found.begin(), found.end(),
                     searching_for.begin(), Charset::caseless_cmp);
   }

/*************************************************
* Search based on the contents of a DN entry     *
*************************************************/
class DN_Check : public X509_Store::Search_Func
   {
   public:
      bool match(const X509_Certificate& cert) const
         {
         std::vector<std::string> info = cert.subject_info(dn_entry);

         for(u32bit j = 0; j != info.size(); ++j)
            if(compare(info[j], looking_for))
               return true;
         return false;
         }

      DN_Check(const std::string& entry, const std::string& target,
               compare_fn func) :
         compare(func), dn_entry(entry), looking_for(target) {}
   private:
      compare_fn compare;
      const std::string dn_entry;
      const std::string looking_for;
   };

}

/*************************************************
* Search for a certificate by email address      *
*************************************************/
std::vector<X509_Certificate> by_email(const X509_Store& store,
                                       const std::string& email)
   {
   DN_Check search_params("RFC822", email, ignore_case);
   return store.get_certs(search_params);
   }

/*************************************************
* Search for a certificate by CommonName         *
*************************************************/
std::vector<X509_Certificate> by_name(const X509_Store& store,
                                      const std::string& name)
   {
   DN_Check search_params("CommonName", name, substring_match);
   return store.get_certs(search_params);
   }

/*************************************************
* Search for a certificate by DNS name           *
*************************************************/
std::vector<X509_Certificate> by_dns(const X509_Store& store,
                                     const std::string& dns)
   {
   DN_Check search_params("DNS", dns, ignore_case);
   return store.get_certs(search_params);
   }

/*************************************************
* Search for a certificate by issuer/serial      *
*************************************************/
std::vector<X509_Certificate> by_iands(const X509_Store& store,
                                       const X509_DN& issuer,
                                       const MemoryRegion<byte>& serial)
   {
   class IandS_Match : public X509_Store::Search_Func
      {
      public:
         bool match(const X509_Certificate& cert) const
            {
            if(cert.serial_number() != serial)
               return false;
            return (cert.issuer_dn() == issuer);
            }
         IandS_Match(const X509_DN& i, const MemoryRegion<byte>& s) :
            issuer(i), serial(s) {}
      private:
         X509_DN issuer;
         MemoryVector<byte> serial;
      };

   IandS_Match search_params(issuer, serial);
   return store.get_certs(search_params);
   }

/*************************************************
* Search for a certificate by subject keyid      *
*************************************************/
std::vector<X509_Certificate> by_SKID(const X509_Store& store,
                                      const MemoryRegion<byte>& skid)
   {
   class SKID_Match : public X509_Store::Search_Func
      {
      public:
         bool match(const X509_Certificate& cert) const
            {
            return (cert.subject_key_id() == skid);
            }
         SKID_Match(const MemoryRegion<byte>& s) : skid(s) {}
      private:
         MemoryVector<byte> skid;
      };

   SKID_Match search_params(skid);
   return store.get_certs(search_params);
   }

}

}