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