File: test_util.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (123 lines) | stat: -rw-r--r-- 4,266 bytes parent folder | download | duplicates (3)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "test_util.h"

#include <array>
#include <optional>
#include <string>

#include "base/check.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/string_number_conversions.h"
#include "device/fido/enclave/types.h"
#include "device/fido/fido_constants.h"
#include "net/base/port_util.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif

base::span<const uint8_t, 16> TestProtobufCredId() {
  return base::span<const uint8_t>(kTestProtobuf).subspan<20, 16>();
}

base::span<const uint8_t, 1> TestProtobufUserId() {
  return base::span<const uint8_t>(kTestProtobuf).subspan<55, 1>();
}

std::pair<base::Process, uint16_t> StartWebAuthnEnclave(base::FilePath cwd) {
  base::FilePath data_root;
  CHECK(base::PathService::Get(base::DIR_OUT_TEST_DATA_ROOT, &data_root));
  const base::FilePath enclave_bin_path =
      data_root.AppendASCII("cloud_authenticator_test_service");
  base::LaunchOptions subprocess_opts;
  subprocess_opts.current_directory = cwd;

  std::optional<base::Process> enclave_process;
  uint16_t port;
  char port_str[6];

  for (int i = 0; i < 10; i++) {
#if BUILDFLAG(IS_WIN)
    HANDLE read_handle;
    HANDLE write_handle;
    SECURITY_ATTRIBUTES security_attributes;

    security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    security_attributes.bInheritHandle = TRUE;
    security_attributes.lpSecurityDescriptor = NULL;
    CHECK(CreatePipe(&read_handle, &write_handle, &security_attributes, 0));

    subprocess_opts.stdin_handle = INVALID_HANDLE_VALUE;
    subprocess_opts.stdout_handle = write_handle;
    subprocess_opts.stderr_handle = INVALID_HANDLE_VALUE;
    subprocess_opts.handles_to_inherit.push_back(write_handle);
    enclave_process = base::LaunchProcess(base::CommandLine(enclave_bin_path),
                                          subprocess_opts);
    CloseHandle(write_handle);
    CHECK(enclave_process->IsValid());

    DWORD read_bytes;
    CHECK(ReadFile(read_handle, port_str, sizeof(port_str), &read_bytes, NULL));
    CloseHandle(read_handle);
#else
    int fds[2];
    CHECK(!pipe(fds));
    subprocess_opts.fds_to_remap.emplace_back(fds[1], 1);
    enclave_process = base::LaunchProcess(base::CommandLine(enclave_bin_path),
                                          subprocess_opts);
    CHECK(enclave_process->IsValid());
    close(fds[1]);

    const ssize_t read_bytes =
        HANDLE_EINTR(read(fds[0], port_str, sizeof(port_str)));
    close(fds[0]);
#endif

    CHECK(read_bytes > 0);
    port_str[read_bytes - 1] = 0;
    unsigned u_port;
    CHECK(base::StringToUint(port_str, &u_port)) << port_str;
    port = base::checked_cast<uint16_t>(u_port);

    if (net::IsPortAllowedForScheme(port, "wss")) {
      break;
    }
    LOG(INFO) << "Port " << port << " not allowed. Trying again.";

    // The kernel randomly picked a port that Chromium will refuse to connect
    // to. Try again.
    enclave_process->Terminate(/*exit_code=*/1, /*wait=*/false);
  }

  return std::make_pair(std::move(*enclave_process), port);
}

device::enclave::ScopedEnclaveOverride TestWebAuthnEnclaveIdentity(
    uint16_t port) {
  constexpr std::array<uint8_t, device::kP256X962Length> kTestPublicKey = {
      0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
      0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
      0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
      0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
      0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
  };
  const std::string url = "ws://127.0.0.1:" + base::NumberToString(port);
  device::enclave::EnclaveIdentity identity;
  identity.url = GURL(url);
  identity.public_key = kTestPublicKey;

  return device::enclave::ScopedEnclaveOverride(std::move(identity));
}