Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Unified Diff: crypto/cup.h

Issue 15793005: Per discussion, implement the Omaha Client Update Protocol (CUP) in src/crypto. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « crypto/crypto.gyp ('k') | crypto/cup.cc » ('j') | crypto/cup.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: crypto/cup.h
===================================================================
--- crypto/cup.h (revision 0)
+++ crypto/cup.h (revision 0)
@@ -0,0 +1,131 @@
+// Copyright (c) 2013 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.
Ryan Sleevi 2013/05/30 02:28:08 As per http://google-styleguide.googlecode.com/svn
Ryan Myers (chromium) 2013/05/30 21:01:10 ACK. I'll make this change in the final patchset,
+
+#ifndef CRYPTO_CUP_H_
+#define CRYPTO_CUP_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/strings/string_piece.h"
+#include "crypto/crypto_export.h"
+
+#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+#include "crypto/scoped_nss_types.h"
+#endif
+
+namespace crypto {
+
+// CUP, or Client Update Protocol, is used by Google Update (Omaha) servers to
Ryan Sleevi 2013/05/30 02:28:08 Client Update Protocol, or CUP, ... [to match file
Ryan Myers (chromium) 2013/05/30 21:01:10 Done.
+// ensure freshness and authenticity of update checks over HTTP, without the
+// overhead of HTTPS -- namely, no PKI, no guarantee of privacy, and no request
+// replay protection (since update checks are idempotent).
+//
+// http://omaha.googlecode.com/svn/wiki/cup.html
+//
+// This implementation does not persist client proofs by design.
+
Ryan Sleevi 2013/05/30 02:28:08 Delete newline
Ryan Myers (chromium) 2013/05/30 21:01:10 Done.
+class CRYPTO_EXPORT ClientUpdateProtocol {
+ public:
+ explicit ClientUpdateProtocol();
+ ~ClientUpdateProtocol();
+
+ // Initializes this instance of CUP with a versioned public key. |key_version|
+ // must be non-negative. |public_key| is expected to be in PEM format with no
+ // header/footer. (i.e. a Base64 encoding of a DER encoding of an ASN.1 key.)
Ryan Sleevi 2013/05/30 02:28:08 Design: Can you explain why you're using PEM, rath
Ryan Myers (chromium) 2013/05/30 21:01:10 Switched to DER. Done.
+ //
+ // Returns true on success. Only call Init() once; it will return false on
+ // subsequent calls.
+ bool Init(int key_version, const char* public_key);
Ryan Sleevi 2013/05/30 02:28:08 Design: Rather than the Init() pattern, it seems m
Ryan Myers (chromium) 2013/05/30 21:01:10 Done.
+
+ // Generates freshness/authentication data for an outgoing update check. A
+ // shared key is generated and encrypted with the public key, and a challenge
+ // and proof are built.
+ //
+ // On success, returns true on success. Out parameters are as follows:
+ // * |url_query_out| receives a modified query string to use in the URL.
+ // * |cp_out| receives the client proof in a Base64 encoding, which should be
+ // sent in the If-Match HTTP header.
+ //
+ // On failure, returns false, and output parameters are not modified.
+ //
+ // This method will store internal state in this instance used by calls to
+ // ValidateResponse(); if you need to have multiple update checks in flight,
+ // initialize a separate CUP instance for each one.
+ bool SignRequest(const base::StringPiece& url_host,
+ const base::StringPiece& url_path,
+ const base::StringPiece& url_query,
+ const base::StringPiece& request_body,
+ std::string* url_query_out,
+ std::string* cp_out);
+
+ // Validates a response to a update check request that was previously signed
+ // with SignRequest(). Returns true on success, false if it cannot validate.
+ // Internal state from the previous call to SignRequest() is used.
+ bool ValidateResponse(const base::StringPiece& response_body,
+ const base::StringPiece& c_in,
+ const base::StringPiece& sp_in);
+
+ private:
+ int v_;
+
+ std::vector<uint8> r_;
+ std::vector<uint8> sk_;
+ std::vector<uint8> w_;
+ std::vector<uint8> hw_;
+ std::string vw_;
Ryan Sleevi 2013/05/30 02:28:08 These field names should all be updated to more me
Ryan Myers (chromium) 2013/05/30 21:01:10 Done. (Renamed them, with added comments to descr
+
+#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
+ ScopedSECKEYPublicKey pkv_;
+#endif
Ryan Sleevi 2013/05/30 02:28:08 No OpenSSL handling?
Ryan Myers (chromium) 2013/05/30 21:01:10 I hadn't coded one yet, because this isn't used on
+
+ // Decodes |public_key| into the appropriate internal structures for pk[v].
+ // Returns the length of the public key (modulus) in bytes, or 0 on failure.
+ size_t LoadPublicKey(const char* public_key);
+
+ // Helper function for BuildSharedKey() -- encrypts r using pk[v] to generate
+ // challenge w. Returns true on success.
+ bool EncryptSharedKey();
+
+ // Initializes r with random data. (No-fail, but requires that a public key
+ // be loaded so that we know how much entropy to generate.)
+ void InitializeEntropy(size_t public_key_length);
+
+ // Given a valid r, generates sk', calls EncryptSharedKey() to generate w,
+ // and generates the encoded v|w string. Returns true on success.
+ bool BuildSharedKey();
+
+ // Encodes a buffer of bytes as URL-safe B64 with no padding.
+ static std::string UrlSafeB64Encode(const std::vector<uint8>& data);
Ryan Sleevi 2013/05/30 02:28:08 Design: All of these static-but-private member fun
Ryan Myers (chromium) 2013/05/30 21:01:10 I explicitly added them here for unit tests -- I'v
+
+ // Returns the length of the digest for our hashing algorithm.
+ static size_t HashDigestSize();
+
+ // Computes the hash of a vector of bytes.
+ static std::vector<uint8> Hash(const std::vector<uint8>& data);
+
+ // Computes the hash of a std::string, not including the null terminator.
+ static std::vector<uint8> Hash(const base::StringPiece& sdata);
+
+ // Computes the HMAC of hashes: SYMSign[key](id|h1|h2|h3)
+ // NULL arguments are not included in the signature computation.
+ // Returns an empty vector on failure.
+ static std::vector<uint8> SymSign(const std::vector<uint8>& key,
+ uint8 id,
+ const std::vector<uint8>* h1,
+ const std::vector<uint8>* h2,
+ const std::vector<uint8>* h3);
+
+ // Pads some entropy with a hash of itself to generate a shared key.
+ static std::vector<uint8> RsaPad(size_t key_size,
+ const std::vector<uint8>& entropy);
+
+ friend class CupUnitTest;
Ryan Sleevi 2013/05/30 02:28:08 per general Chromium style, move this friend to li
Ryan Myers (chromium) 2013/05/30 21:01:10 Done.
+};
+
+} // namespace crypto
+
+#endif // CRYPTO_CUP_H_
+
« no previous file with comments | « crypto/crypto.gyp ('k') | crypto/cup.cc » ('j') | crypto/cup.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698