aboutsummaryrefslogtreecommitdiffstats
path: root/src/cert/x509/x509stor.h
blob: 8f2d5b4058802e1183727a680e7b69a769f003f2 (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
/*
* X.509 Certificate Store
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#ifndef BOTAN_X509_CERT_STORE_H__
#define BOTAN_X509_CERT_STORE_H__

#include <botan/x509cert.h>
#include <botan/x509_crl.h>
#include <botan/certstor.h>
#include <functional>

namespace Botan {

/**
* X.509 Certificate Validation Result
*/
enum X509_Code {
   VERIFIED,
   UNKNOWN_X509_ERROR,
   CANNOT_ESTABLISH_TRUST,
   CERT_CHAIN_TOO_LONG,
   SIGNATURE_ERROR,
   POLICY_ERROR,
   INVALID_USAGE,

   CERT_FORMAT_ERROR,
   CERT_ISSUER_NOT_FOUND,
   CERT_NOT_YET_VALID,
   CERT_HAS_EXPIRED,
   CERT_IS_REVOKED,

   CRL_FORMAT_ERROR,
   CRL_ISSUER_NOT_FOUND,
   CRL_NOT_YET_VALID,
   CRL_HAS_EXPIRED,

   CA_CERT_CANNOT_SIGN,
   CA_CERT_NOT_FOR_CERT_ISSUER,
   CA_CERT_NOT_FOR_CRL_ISSUER
};

/**
* X.509 Certificate Store
*/
class BOTAN_DLL X509_Store
   {
   public:
      enum Cert_Usage {
         ANY              = 0x00,
         TLS_SERVER       = 0x01,
         TLS_CLIENT       = 0x02,
         CODE_SIGNING     = 0x04,
         EMAIL_PROTECTION = 0x08,
         TIME_STAMPING    = 0x10,
         CRL_SIGNING      = 0x20
      };

      X509_Code validate_cert(const X509_Certificate&, Cert_Usage = ANY);

      /**
      * @param match the matching function
      * @return list of certs for which match returns true
      */
      std::vector<X509_Certificate>
         get_certs(std::function<bool (const X509_Certificate&)> match) const;

      std::vector<X509_Certificate> get_cert_chain(const X509_Certificate&);
      std::string PEM_encode() const;

      X509_Code add_crl(const X509_CRL&);
      void add_cert(const X509_Certificate&, bool = false);
      void add_certs(DataSource&);
      void add_trusted_certs(DataSource&);

      void add_new_certstore(Certificate_Store*);

      static X509_Code check_sig(const X509_Object&, Public_Key*);

      X509_Store& operator=(const X509_Store&) = delete;

      /**
      * @param slack the slack in checking validity times against current clock
      * @param cache how long to cache validation results before rechecking
      */
      X509_Store(std::chrono::seconds slack = std::chrono::seconds(24*60*60),
                 std::chrono::seconds cache = std::chrono::seconds(30*60));

      X509_Store(const X509_Store&);
      ~X509_Store();
   private:
      class BOTAN_DLL CRL_Data
         {
         public:
            X509_DN issuer;
            MemoryVector<byte> serial, auth_key_id;
            bool operator==(const CRL_Data&) const;
            bool operator!=(const CRL_Data&) const;
            bool operator<(const CRL_Data&) const;
         };

      class BOTAN_DLL Cert_Info
         {
         public:
            bool is_verified(std::chrono::seconds cache_timeout) const;
            bool is_trusted() const;
            X509_Code verify_result() const;
            void set_result(X509_Code) const;
            Cert_Info(const X509_Certificate&, bool = false);

            X509_Certificate cert;
            bool trusted;
         private:
            mutable bool checked;
            mutable X509_Code result;
            mutable std::chrono::system_clock::time_point last_checked;
         };

      u32bit find_cert(const X509_DN&, const MemoryRegion<byte>&) const;
      X509_Code check_sig(const Cert_Info&, const Cert_Info&) const;
      void recompute_revoked_info() const;

      void do_add_certs(DataSource&, bool);
      X509_Code construct_cert_chain(const X509_Certificate&,
                                     std::vector<u32bit>&, bool = false);

      u32bit find_parent_of(const X509_Certificate&);
      bool is_revoked(const X509_Certificate&) const;

      static const u32bit NO_CERT_FOUND = 0xFFFFFFFF;

      std::vector<Cert_Info> certs;
      std::vector<CRL_Data> revoked;
      std::vector<Certificate_Store*> stores;

      std::chrono::seconds time_slack, validation_cache_timeout;
      mutable bool revoked_info_valid;
   };

}

#endif