message_payload_parser.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright 2017 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. #ifndef COMPONENTS_GCM_DRIVER_CRYPTO_MESSAGE_PAYLOAD_PARSER_H_
  5. #define COMPONENTS_GCM_DRIVER_CRYPTO_MESSAGE_PAYLOAD_PARSER_H_
  6. #include <stdint.h>
  7. #include "base/check.h"
  8. #include "base/strings/string_piece.h"
  9. #include "third_party/abseil-cpp/absl/types/optional.h"
  10. namespace gcm {
  11. enum class GCMDecryptionResult;
  12. // Parses and validates the binary message payload included in messages that
  13. // are encrypted per draft-ietf-webpush-encryption-08:
  14. //
  15. // https://tools.ietf.org/html/draft-ietf-httpbis-encryption-encoding-08#section-2.1
  16. //
  17. // In summary, such messages start with a binary header block that includes the
  18. // parameters needed to decrypt the content, other than the key. All content
  19. // following this binary header is considered the ciphertext.
  20. //
  21. // +-----------+--------+-----------+-----------------+
  22. // | salt (16) | rs (4) | idlen (1) | public_key (65) |
  23. // +-----------+--------+-----------+-----------------+
  24. //
  25. // Specific to Web Push encryption, the `public_key` parameter of this header
  26. // must be set to the ECDH public key of the sender. This is a point on the
  27. // P-256 elliptic curve in uncompressed form, 65 bytes long starting with 0x04.
  28. //
  29. // https://tools.ietf.org/html/draft-ietf-webpush-encryption-08#section-3.1
  30. class MessagePayloadParser {
  31. public:
  32. explicit MessagePayloadParser(base::StringPiece message);
  33. MessagePayloadParser(const MessagePayloadParser&) = delete;
  34. MessagePayloadParser& operator=(const MessagePayloadParser&) = delete;
  35. ~MessagePayloadParser();
  36. // Returns whether the parser represents a valid message.
  37. bool IsValid() const { return is_valid_; }
  38. // Returns the failure reason when the given payload could not be parsed. Must
  39. // only be called when IsValid() returns false.
  40. GCMDecryptionResult GetFailureReason() const {
  41. DCHECK(failure_reason_.has_value());
  42. return failure_reason_.value();
  43. }
  44. // Returns the 16-byte long salt for the message. Must only be called after
  45. // validity of the message has been verified.
  46. const std::string& salt() const {
  47. CHECK(is_valid_);
  48. return salt_;
  49. }
  50. // Returns the record size for the message. Must only be called after validity
  51. // of the message has been verified.
  52. uint32_t record_size() const {
  53. CHECK(is_valid_);
  54. return record_size_;
  55. }
  56. // Returns the sender's ECDH public key for the message. This will be a point
  57. // on the P-256 elliptic curve in uncompressed form. Must only be called after
  58. // validity of the message has been verified.
  59. const std::string& public_key() const {
  60. CHECK(is_valid_);
  61. return public_key_;
  62. }
  63. // Returns the ciphertext for the message. This will be at least the size of
  64. // a single record, which is 18 octets. Must only be called after validity of
  65. // the message has been verified.
  66. const std::string& ciphertext() const {
  67. CHECK(is_valid_);
  68. return ciphertext_;
  69. }
  70. private:
  71. bool is_valid_ = false;
  72. absl::optional<GCMDecryptionResult> failure_reason_;
  73. std::string salt_;
  74. uint32_t record_size_ = 0;
  75. std::string public_key_;
  76. std::string ciphertext_;
  77. };
  78. } // namespace gcm
  79. #endif // COMPONENTS_GCM_DRIVER_CRYPTO_MESSAGE_PAYLOAD_PARSER_H_