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