Chromium Code Reviews| Index: net/cert/internal/path_builder.h |
| diff --git a/net/cert/internal/path_builder.h b/net/cert/internal/path_builder.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..77150bc329466d1722d6bec6a0c1b4748ea54289 |
| --- /dev/null |
| +++ b/net/cert/internal/path_builder.h |
| @@ -0,0 +1,165 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef NET_CERT_INTERNAL_PATH_BUILDER_H_ |
| +#define NET_CERT_INTERNAL_PATH_BUILDER_H_ |
| + |
| +#include <memory> |
| +#include <string> |
| +#include <unordered_map> |
| +#include <vector> |
| + |
| +#include "base/callback.h" |
| +#include "net/base/completion_callback.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/base/net_export.h" |
| +#include "net/cert/internal/verify_certificate_chain.h" |
| +#include "net/der/input.h" |
| + |
| +namespace net { |
| + |
| +using CertVector = std::vector<std::unique_ptr<CertThing>>; |
| + |
| +class NET_EXPORT CertSource { |
| + public: |
| + using IssuerCallback = base::Callback<void(CertVector)>; |
| + |
| + class Request { |
| + public: |
| + Request() {} |
| + // Destruction of the Request cancels it. |
| + virtual ~Request() {} |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(Request); |
| + }; |
| + |
| + virtual ~CertSource() {} |
| + |
| + // Append certs to |issuers|. Any existing contents of |issuers| will not be |
| + // modified. |
| + virtual bool SyncGetIssuersOf(const CertThing& cert, CertVector* issuers) = 0; |
| + // Returns ERR_IO_PENDING if async callback will be made, or OK if no async |
| + // results are available from this source. |
| + // If |*out_req| is destroyed, the callback will not be run. |
| + virtual int AsyncGetIssuersOf(const CertThing& cert, |
| + const IssuerCallback& issuers_callback, |
| + std::unique_ptr<Request>* out_req) = 0; |
| +}; |
| + |
| +class NET_EXPORT StaticCertsSource : public CertSource { |
| + public: |
| + StaticCertsSource(); |
| + ~StaticCertsSource() override; |
| + |
| + // Initialize the StaticCertsSource with the given certificates. The data |
| + // referred to by |certs| must outlive the StaticCertsSource object. |
| + // XXX Should this just take a CertVector? |
| + bool Init(std::vector<der::Input> certs); |
| + |
| + // CertSource implementation: |
| + bool SyncGetIssuersOf(const CertThing& cert, CertVector* issuers) override; |
| + int AsyncGetIssuersOf(const CertThing& cert, |
| + const IssuerCallback& issuers_callback, |
| + std::unique_ptr<Request>* out_req) override; |
| + |
| + private: |
| + // The certificates that the StaticCertsSource can return, keyed on the |
| + // normalized subject value. |
| + // XXX key using StringPiece to avoid copy? |
| + std::unordered_multimap<std::string, std::unique_ptr<CertThing>> |
| + intermediates_; |
| +}; |
| + |
| +// XXX possible cert sources: |
| +// * intermediates supplied by server (synchronous) |
| +// * AIA fetch (async) |
| +// * intermediates in OS cert store (async?) |
| +// * certs cached from previous requests (sync?) |
| + |
| +class CertPathIter; |
| + |
| +class NET_EXPORT CertPathBuilder { |
| + public: |
| + using CertSources = std::vector<CertSource*>; |
| + |
| + struct ResultPath { |
| + ResultPath(); |
| + ~ResultPath(); |
| + |
| + std::vector<std::unique_ptr<CertThing>> path; |
| + int rv; |
| + }; |
| + |
| + struct Result { |
| + Result(); |
| + ~Result(); |
| + |
| + // Returns the overall result. This is the same value that was returned by |
| + // Run (if synchronous) or by the CompletionCallback (if asynchronous). |
| + int result() { |
| + if (paths.empty()) |
| + return ERR_CERT_AUTHORITY_INVALID; |
| + return paths[best_result_index]->rv; |
| + } |
| + |
| + // List of paths that were attempted and the result for each. |
| + std::vector<std::unique_ptr<ResultPath>> paths; |
| + // Index into |paths|. |
| + size_t best_result_index = 0; |
| + }; |
| + |
| + // TODO: allow caller specified filters / checkers, initial values of name |
| + // constraints, etc |
| + // |
| + // Creates a CertPathBuilder that attempts to find a path from |cert| to a |
| + // trust anchor in |trust_store|, using intermediates from |cert_sources| if |
| + // necessary, which satisfies |signature_policy| and is valid at |time|. |
| + // Details of attempted path(s) are stored in |*result|. |
| + CertPathBuilder(std::unique_ptr<CertThing> cert, |
| + const CertSources& cert_sources, |
| + const TrustStore& trust_store, |
| + const SignaturePolicy* signature_policy, |
| + const der::GeneralizedTime& time, |
| + Result* result); |
| + ~CertPathBuilder(); |
| + |
| + // Begins verification of |cert|. If the return value is ERR_IO_PENDING, |
| + // |callback| will be called asynchronously with the result. Otherwise, the |
| + // result is returned synchronously and |callback| is not called. |
| + int Run(const CompletionCallback& callback); |
| + |
| + private: |
| + enum State { |
| + STATE_NONE, |
| + STATE_GET_NEXT_PATH, |
| + STATE_GET_NEXT_PATH_COMPLETE, |
| + }; |
| + |
| + int DoLoop(int result); |
| + |
| + int DoGetNextPath(); |
| + void HandleGotNextPath(int result); |
| + int DoGetNextPathComplete(int result); |
| + |
| + void AddResultPath(const CertVector& path, bool result); |
| + |
| + CompletionCallback callback_; |
| + |
| + std::unique_ptr<CertPathIter> cert_path_iter_; |
| + const TrustStore& trust_store_; |
| + const SignaturePolicy* signature_policy_; |
| + const der::GeneralizedTime& time_; |
|
eroman
2016/04/26 22:10:11
Why a const reference? This seems like a problem s
mattm
2016/04/26 22:54:16
Good catch. Just a bad copy/paste.
|
| + |
| + CertVector next_path_; |
| + State next_state_; |
| + |
| + Result* out_result_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(CertPathBuilder); |
| +}; |
| + |
| +} // namespace net |
| + |
| +#endif // NET_CERT_INTERNAL_PATH_BUILDER_H_ |