Chromium Code Reviews| 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 |