chromium/chrome/updater/certificate_tag_internal.h

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_UPDATER_CERTIFICATE_TAG_INTERNAL_H_
#define CHROME_UPDATER_CERTIFICATE_TAG_INTERNAL_H_

#include <cstdint>
#include <cstring>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/containers/span.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_span.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/crypto.h"

namespace updater::tagging::internal {

// PEBinary represents a Windows PE binary and provides functions to extract and
// set data outside of the signed area (called a "tag"). This allows a binary to
// contain arbitrary data without invalidating any Authenticode signature.
class PEBinary : public BinaryInterface {};

#pragma pack(push)
#pragma pack(1)

// SectorFormat represents parameters of an MSI file sector.
struct SectorFormat {};

// MSIDirEntry represents a parsed MSI directory entry for a stream.
struct MSIDirEntry {};

// MSIHeader represents a parsed MSI header.
struct MSIHeader {};

struct SignedDataDir {};
#pragma pack(pop)

// MSIBinary represents a Windows MSI binary and provides functions to extract
// and set a "tag" outside of the signed area. This allows the MSI to contain
// arbitrary data without invalidating any Authenticode signature.
class MSIBinary : public BinaryInterface {};

// CBS is a structure from BoringSSL used for parsing binary and ASN.1-based
// formats. This implementation detail is not exposed in the interface of this
// code so these utility functions convert to/from base::span.
CBS CBSFromSpan(base::span<const uint8_t> span);
base::span<const uint8_t> SpanFromCBS(const CBS* cbs);

// kTagOID contains the DER-serialised form of the extension OID that we stuff
// the tag into: 1.3.6.1.4.1.11129.2.1.9999.
inline constexpr uint8_t kTagOID[] =;

// Certificate constants. See
// http://msdn.microsoft.com/en-us/library/ms920091.aspx.
//
// Despite MSDN claiming that 0x100 is the only, current revision - in
// practice it's 0x200.
inline constexpr uint16_t kAttributeCertificateRevision =;
inline constexpr uint16_t kAttributeCertificateTypePKCS7SignedData =;

// AddName appends an X.500 Name structure to |cbb| containing a single
// commonName with the given value.
bool AddName(CBB* cbb, const char* common_name);

// CopyASN1 copies a single ASN.1 element from |in| to |out|.
bool CopyASN1(CBB* out, CBS* in);

struct ParseResult {};

// Parses the `signed_data` PKCS7 object to find the final certificate in the
// list and see whether it has an extension with `kTagOID`, and if so, returns a
// `base::span` of the tag within this `signed_data`. `success` is set to `true`
// if there were no parse errors, even if a tag could not be found.
ParseResult ParseTagImpl(base::span<const uint8_t> signed_data);

// Returns an updated version of the ContentInfo signedData PKCS7 object with
// the given `tag` added, or `nullopt` on error. If the input `signed_data`
// already contains a tag, then it will be replaced with `tag`.
std::optional<std::vector<uint8_t>> SetTagImpl(
    base::span<const uint8_t> signed_data,
    base::span<const uint8_t> tag);

// Compound file binary format constants.
inline constexpr int kNumHeaderContentBytes =;
inline constexpr int kNumHeaderTotalBytes =;
inline constexpr int kNumDifatHeaderEntries =;
inline constexpr int kNumDirEntryBytes =;
inline constexpr int kMiniStreamSectorSize =;
inline constexpr int kMiniStreamCutoffSize =;

// An unallocated sector (used in the fat or difat).
inline constexpr uint32_t kFatFreeSector =;

// End of a linked chain (in the fat); or end of difat sector chain.
inline constexpr uint32_t kFatEndOfChain =;

// Used in the fat table to indicate a fat sector entry.
inline constexpr uint32_t kFatFatSector =;

// Used in the fat table to indicate a difat sector entry.
inline constexpr uint32_t kFatDifSector =;

// Reserved value.
inline constexpr uint32_t kFatReserved =;

inline constexpr uint8_t kMsiHeaderSignature[] =;
inline constexpr uint8_t kMsiHeaderClsid[16] =;

// UTF-16 for "\05DigitalSignature".
inline constexpr uint8_t kSignatureName[] =;

std::optional<SectorFormat> NewSectorFormat(uint16_t sector_shift);

// Returns whether the index corresponds to the last entry in a sector.
//
// The last entry in each difat sector is a pointer to the next difat sector, or
// is an end-of-chain marker.
// This does not apply to the last entry stored in the MSI header.
bool IsLastInSector(const SectorFormat& format, int index);

}  // namespace updater::tagging::internal

#endif  // CHROME_UPDATER_CERTIFICATE_TAG_INTERNAL_H_