aboutsummaryrefslogtreecommitdiffstats
path: root/src/x509find.cpp
blob: a50ce0bfaac569f7d25b0a1a9d695440a1230cc7 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*************************************************
* 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&);

/*************************************************
* Predicate for caseless searching               *
*************************************************/
bool caseless_cmp(char a, char b)
   {
   return (to_lower(a) == to_lower(b));
   }

/*************************************************
* 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(), 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(), 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
         {
         return compare(looking_for, cert.subject_info(dn_entry));
         }

      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 based on the key id                     *
*************************************************/
class KeyID_Match : public X509_Store::Search_Func
   {
   public:
      bool match(const X509_Certificate& cert) const
         {
         std::auto_ptr<X509_PublicKey> key(cert.subject_public_key());
         return (key->key_id() == key_id);
         }
      KeyID_Match(u64bit id) : key_id(id) {}
   private:
      u64bit key_id;
   };

/*************************************************
* Search based on the issuer and serial number   *
*************************************************/
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;
   };

/*************************************************
* Search based on the subject key id             *
*************************************************/
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;
   };

}

/*************************************************
* 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 key id             *
*************************************************/
std::vector<X509_Certificate> by_keyid(const X509_Store& store, u64bit key_id)
   {
   KeyID_Match search_params(key_id);
   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)
   {
   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)
   {
   SKID_Match search_params(skid);
   return store.get_certs(search_params);
   }

}

}