OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef NET_CERT_INTERNAL_PATH_BUILDER_H_ | |
6 #define NET_CERT_INTERNAL_PATH_BUILDER_H_ | |
7 | |
8 #include <memory> | |
9 #include <string> | |
10 #include <unordered_map> | |
11 #include <vector> | |
12 | |
13 #include "base/callback.h" | |
14 #include "net/base/completion_callback.h" | |
15 #include "net/base/net_errors.h" | |
16 #include "net/base/net_export.h" | |
17 #include "net/cert/internal/verify_certificate_chain.h" | |
18 #include "net/der/input.h" | |
19 | |
20 namespace net { | |
21 | |
22 class NET_EXPORT CertSource { | |
23 public: | |
24 using IssuerCallback = base::Callback<void(CertVector)>; | |
Ryan Sleevi
2016/05/04 02:42:42
Musing outloud: Should we return an explicit CertV
mattm
2016/05/04 23:21:16
Hm, could perhaps avoid some copies? It's always h
| |
25 | |
26 class Request { | |
27 public: | |
28 Request() {} | |
29 // Destruction of the Request cancels it. | |
30 virtual ~Request() {} | |
31 | |
32 private: | |
33 DISALLOW_COPY_AND_ASSIGN(Request); | |
34 }; | |
35 | |
36 virtual ~CertSource() {} | |
37 | |
38 // Append certs to |issuers|. Any existing contents of |issuers| will not be | |
39 // modified. | |
40 virtual void SyncGetIssuersOf(const CertThing* cert, CertVector* issuers) = 0; | |
41 // Returns ERR_IO_PENDING if async callback will be made, or OK if no async | |
42 // results are available from this source. | |
43 // If |*out_req| is destroyed, the callback will not be run. | |
44 // XXX should this take a scoped_refptr? | |
45 virtual int AsyncGetIssuersOf(const CertThing* cert, | |
46 const IssuerCallback& issuers_callback, | |
47 std::unique_ptr<Request>* out_req) = 0; | |
Ryan Sleevi
2016/05/04 02:42:42
Musing outloud: Do we need two methods, or should
mattm
2016/05/04 23:21:16
Did consider that, the question then is when doing
| |
48 }; | |
49 | |
50 class NET_EXPORT StaticCertSource : public CertSource { | |
Ryan Sleevi
2016/05/04 02:42:41
Musing outloud: Does it make sense to have an aggr
mattm
2016/05/04 23:21:16
One issue is that CertIssuersIter currently handle
| |
51 public: | |
52 StaticCertSource(const CertVector& certs); | |
53 ~StaticCertSource() override; | |
54 | |
55 // CertSource implementation: | |
56 void SyncGetIssuersOf(const CertThing* cert, CertVector* issuers) override; | |
57 int AsyncGetIssuersOf(const CertThing* cert, | |
58 const IssuerCallback& issuers_callback, | |
59 std::unique_ptr<Request>* out_req) override; | |
60 | |
61 private: | |
62 // The certificates that the StaticCertSource can return, keyed on the | |
63 // normalized subject value. | |
64 std::unordered_multimap<base::StringPiece, | |
65 scoped_refptr<CertThing>, | |
66 base::StringPieceHash> | |
67 intermediates_; | |
68 }; | |
Ryan Sleevi
2016/05/04 02:42:42
There's a part of me that leans to suggest separat
mattm
2016/05/04 23:21:16
I'll look at sorting out the file layout some in a
| |
69 | |
70 // XXX possible cert sources: | |
71 // * intermediates supplied by server (synchronous) | |
72 // * AIA fetch (async) | |
73 // * intermediates in OS cert store (async?) | |
Ryan Sleevi
2016/05/04 02:42:41
Aye
| |
74 // * certs cached from previous requests (sync?) | |
75 | |
76 class CertPathIter; | |
77 | |
78 class NET_EXPORT CertPathBuilder { | |
79 public: | |
80 using CertSources = std::vector<CertSource*>; | |
81 | |
82 struct ResultPath { | |
83 ResultPath(); | |
84 ~ResultPath(); | |
85 | |
86 std::vector<scoped_refptr<CertThing>> path; | |
87 int rv; | |
88 }; | |
89 | |
90 struct Result { | |
91 Result(); | |
92 ~Result(); | |
93 | |
94 // Returns the overall result. This is the same value that was returned by | |
95 // Run (if synchronous) or by the CompletionCallback (if asynchronous). | |
96 int result() { | |
97 if (paths.empty()) | |
98 return ERR_CERT_AUTHORITY_INVALID; | |
99 return paths[best_result_index]->rv; | |
100 } | |
101 | |
102 // List of paths that were attempted and the result for each. | |
103 std::vector<std::unique_ptr<ResultPath>> paths; | |
104 // Index into |paths|. Before use, |paths.empty()| must be checked. | |
105 size_t best_result_index = 0; | |
106 }; | |
107 | |
108 // TODO: allow caller specified filters / checkers, initial values of name | |
109 // constraints, etc | |
110 // | |
111 // Creates a CertPathBuilder that attempts to find a path from |cert| to a | |
112 // trust anchor in |trust_store|, using intermediates from |cert_sources| if | |
113 // necessary, which satisfies |signature_policy| and is valid at |time|. | |
114 // Details of attempted path(s) are stored in |*result|. | |
115 // | |
116 // The caller must keep |cert_sources|, |trust_store|, |signature_policy|, and | |
117 // |*result| valid for the lifetime of the CertPathBuilder. | |
118 CertPathBuilder(scoped_refptr<CertThing> cert, | |
119 const CertSources& cert_sources, | |
120 const TrustStore& trust_store, | |
121 const SignaturePolicy* signature_policy, | |
122 const der::GeneralizedTime& time, | |
123 Result* result); | |
Ryan Sleevi
2016/05/04 02:42:42
I'm wondering whether we should have a CertPathBui
mattm
2016/05/04 23:21:16
I like the idea. For now I changed it so the const
| |
124 ~CertPathBuilder(); | |
125 | |
126 // Begins verification of |cert|. If the return value is ERR_IO_PENDING, | |
127 // |callback| will be called asynchronously with the result. Otherwise, the | |
128 // result is returned synchronously and |callback| is not called. | |
129 int Run(const CompletionCallback& callback); | |
130 | |
131 private: | |
132 enum State { | |
133 STATE_NONE, | |
134 STATE_GET_NEXT_PATH, | |
135 STATE_GET_NEXT_PATH_COMPLETE, | |
136 }; | |
137 | |
138 int DoLoop(int result); | |
139 | |
140 int DoGetNextPath(); | |
141 void HandleGotNextPath(int result); | |
142 int DoGetNextPathComplete(int result); | |
143 | |
144 void AddResultPath(const CertVector& path, bool result); | |
145 | |
146 CompletionCallback callback_; | |
147 | |
148 std::unique_ptr<CertPathIter> cert_path_iter_; | |
149 const TrustStore& | |
150 trust_store_; // XXX should be a pointer to signify we don't own it? | |
151 const SignaturePolicy* signature_policy_; | |
152 const der::GeneralizedTime time_; | |
153 | |
154 CertVector next_path_; | |
155 State next_state_; | |
156 | |
157 Result* out_result_; | |
158 | |
159 DISALLOW_COPY_AND_ASSIGN(CertPathBuilder); | |
160 }; | |
161 | |
162 } // namespace net | |
163 | |
164 #endif // NET_CERT_INTERNAL_PATH_BUILDER_H_ | |
OLD | NEW |