diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index e1985da0305..850da97c37c 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -199,3 +199,7 @@ poetry( load("//bazel/format:shfmt.bzl", "shfmt") shfmt() + +load("//bazel/gpg:gpg.bzl", "gpg") + +gpg() diff --git a/bazel/BUILD.bazel b/bazel/BUILD.bazel index 0b4b39015dc..126b14ae0f9 100644 --- a/bazel/BUILD.bazel +++ b/bazel/BUILD.bazel @@ -34,6 +34,13 @@ py_binary( ], ) +py_binary( + name = "gpg_signer", + srcs = ["gpg_signer.py"], + main = "gpg_signer.py", + visibility = ["//visibility:public"], +) + filegroup( name = "test_wrapper", srcs = ["test_wrapper.sh"], diff --git a/bazel/gpg/BUILD.bazel b/bazel/gpg/BUILD.bazel new file mode 100644 index 00000000000..ffd0fb0cdc5 --- /dev/null +++ b/bazel/gpg/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/bazel/gpg/gpg.bzl b/bazel/gpg/gpg.bzl new file mode 100644 index 00000000000..592101dd878 --- /dev/null +++ b/bazel/gpg/gpg.bzl @@ -0,0 +1,79 @@ +"""Repository rules for gpg bundle download""" + +load("//bazel:utils.bzl", "retry_download_and_extract") +load("@bazel_rules_mongo//utils:platforms_normalize.bzl", "ARCH_NORMALIZE_MAP", "OS_NORMALIZE_MAP") + +URLS_MAP = { + "linux_aarch64": { + "sha": "d7197d8b8ad4dc4ef6c27eb03c6cc565e00f994b33011da89f37dacc92810228", + "url": "https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/gpg_bundle-aarch64.tar.gz", + }, + "linux_x86_64": { + "sha": "66608c5dcfd4580ec7e7dfcf8dd16df73b563674222bf3b9785d853b3d2052ee", + "url": "https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/gpg_bundle-x86_64.tar.gz", + }, + "linux_s390x": { + "sha": "1fff70fce14abfa83b08df7465929c0b98e5c12c7bff001c4fbd82adaf82c8bd", + "url": "https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/gpg_bundle-s390x.tar.gz", + }, + "linux_ppc64le": { + "sha": "3f2ecdfb99c49d148f92973e5164821de663984e5a02cd6a1686ce32f1c1d9f9", + "url": "https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/gpg_bundle-ppc64le.tar.gz", + }, +} + +def _gpg_bundle_repo_impl(ctx): + os = ctx.os.name + os_norm = OS_NORMALIZE_MAP.get(ctx.os.name) + if os_norm != "linux": + ctx.file( + "BUILD.bazel", + content = """package(default_visibility = ["//visibility:public"]) +filegroup(name = "gpg_bins", srcs = glob([])) +filegroup(name = "gpg_libs", srcs = glob([])) +""", + ) + return + + arch = ctx.os.arch + os_constraint = OS_NORMALIZE_MAP[os] + arch_constraint = ARCH_NORMALIZE_MAP[arch] + platform_key = "{os}_{arch}".format(os = os_constraint, arch = arch_constraint) + + if platform_key not in URLS_MAP: + fail("Unsupported platform for gpg bundle: {k}. Supported: {supported}".format( + k = platform_key, + supported = ", ".join(sorted(URLS_MAP.keys())), + )) + + platform_info = URLS_MAP[platform_key] + ctx.report_progress("downloading gpg bundle") + retry_download_and_extract( + ctx = ctx, + tries = 5, + url = platform_info["url"], + sha256 = platform_info["sha"], + ) + + # BUILD file: include all bin/* and libs/** in runfiles + ctx.file( + "BUILD.bazel", + content = """package(default_visibility = ["//visibility:public"]) +filegroup( + name = "gpg_libs", + srcs = glob(["gpg_bundle-*/libs/**"]),) + +filegroup( + name = "gpg_bins", + srcs = glob(["gpg_bundle-*/bin/*"]),) + +""", + ) + +_gpg_bundle_repo = repository_rule( + implementation = _gpg_bundle_repo_impl, + attrs = {}, +) + +def gpg(): + _gpg_bundle_repo(name = "gpg") diff --git a/bazel/gpg_signer.py b/bazel/gpg_signer.py new file mode 100644 index 00000000000..2e2c8df04a5 --- /dev/null +++ b/bazel/gpg_signer.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Action helper to sign a file with a provided private key using GPG. + +This replaces the inline `_gpg_sign.sh` that `bazel/signing.bzl` used to generate. + +Args (positional): + 1) GPG: path to the gpg binary to execute + 2) KEY: path to the ascii-armored private key file to import + 3) PASSPHRASE: optional path to a file containing the passphrase (or "" if none) + 4) OUT: output signature path + 5) INP: input file path to sign +""" + +from __future__ import annotations + +import os +import shutil +import subprocess +import sys +import tempfile +from typing import List, Optional + + +def _debug(msg: str) -> None: + print(msg, file=sys.stderr) + + +def _run(argv: List[str], *, capture_stdout: bool = False) -> subprocess.CompletedProcess: + if capture_stdout: + return subprocess.run( + argv, check=True, text=True, stdout=subprocess.PIPE, stderr=sys.stderr + ) + return subprocess.run(argv, check=True) + + +def _extract_fingerprint(colons_output: str) -> Optional[str]: + # gpg --with-colons output: lines like "fpr:::::::::FINGERPRINT:" + for line in colons_output.splitlines(): + if not line.startswith("fpr:"): + continue + parts = line.split(":") + if len(parts) > 9 and parts[9]: + return parts[9] + return None + + +def main(argv: List[str]) -> int: + _debug("Starting gpg_signer.py") + + if len(argv) != 6: + print( + "usage: gpg_signer.py ", + file=sys.stderr, + ) + return 2 + + gpg = argv[1] + key = argv[2] + passphrase_file = argv[3] or None + out_path = argv[4] + inp_path = argv[5] + + # Use helpers from the same bundle as `gpg` to avoid accidentally picking up system gpg-agent/gpgconf, + # especially under remote execution. + bindir = os.path.dirname(gpg) + gpg_agent = os.path.join(bindir, "gpg-agent") + gpgconf = os.path.join(bindir, "gpgconf") + + # Unique temp homedir for this action. + base_tmp = os.environ.get("TMPDIR") or os.getcwd() + gpgdir = tempfile.mkdtemp(prefix="gpg.", dir=base_tmp) + os.chmod(gpgdir, 0o700) + + try: + # Disable agent caching for this home directory. + with open(os.path.join(gpgdir, "gpg-agent.conf"), "w", encoding="utf-8") as fh: + fh.write( + "default-cache-ttl 0\n" + "max-cache-ttl 0\n" + "ignore-cache-for-signing\n" + "allow-loopback-pinentry\n" + ) + + _debug("Starting gpg-agent") + # Inherit stdout/stderr so logs show up in action output (like the old shell script). + _run([gpg_agent, "--homedir", gpgdir, "--daemon", "--verbose"]) + _debug("gpg-agent importing key to home dir") + + # Import the private key into the temp homedir. + _run([gpg, "--homedir", gpgdir, "--batch", "--import", key]) + + # Find fingerprint. + cp = _run([gpg, "--homedir", gpgdir, "--list-keys", "--with-colons"], capture_stdout=True) + fpr = _extract_fingerprint(cp.stdout) + if not fpr: + print( + "Failed to determine key fingerprint from gpg --with-colons output", file=sys.stderr + ) + return 1 + + # Build passphrase options if provided. + pass_opts: List[str] = [] + if passphrase_file: + pass_opts = ["--pinentry-mode", "loopback", "--passphrase-file", passphrase_file] + + _run( + [ + gpg, + "--homedir", + gpgdir, + "--batch", + "--yes", + *pass_opts, + "--detach-sign", + "-u", + fpr, + "-o", + out_path, + inp_path, + ] + ) + return 0 + finally: + # Cleanup. + try: + subprocess.run([gpgconf, "--homedir", gpgdir, "--kill", "gpg-agent"], check=False) + finally: + shutil.rmtree(gpgdir, ignore_errors=True) + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) diff --git a/bazel/signing.bzl b/bazel/signing.bzl new file mode 100644 index 00000000000..ae324225894 --- /dev/null +++ b/bazel/signing.bzl @@ -0,0 +1,191 @@ +"""Custom signing macros for test extensions.""" + +load("//bazel:mongo_src_rules.bzl", "mongo_cc_extension_shared_library") + +def _gpg_sign_impl(ctx): + outs = [] + + python = ctx.toolchains["@bazel_tools//tools/python:toolchain_type"].py3_runtime + + for src in ctx.files.srcs: + out = ctx.actions.declare_file(src.basename + ".sig") + outs.append(out) + + # Inputs to this action + inputs = [src, ctx.file.key, ctx.file._gpg_signer] + pass_arg = "" + if ctx.file.passphrase: + inputs.append(ctx.file.passphrase) + pass_arg = ctx.file.passphrase.path + + dep_files = ctx.files.gpg_bins + dep_dirs = [f.dirname for f in dep_files] + + # Prefer explicit override (if provided). Otherwise, locate the real gpg binary from the bundle. + gpg_file = ctx.file.gpg_main_script + if gpg_file == None: + for f in dep_files: + if f.basename == "gpg" or f.basename == "gpg.exe": + gpg_file = f + break + if gpg_file == None: + fail("Unable to find gpg in gpg_bins. Ensure @gpg//:gpg_bins contains a 'gpg' binary.") + + env = dict(ctx.configuration.default_shell_env) + sep = ctx.configuration.host_path_separator # ":" or ";" + base_path = env.get("PATH", "") + env["PATH"] = sep.join(dep_dirs + ([base_path] if base_path else [])) + + inputs += dep_files + + # Needed for remote execution: gpg binaries use RUNPATH=$ORIGIN/../libs. + inputs += ctx.files.gpg_libs + + inputs += python.files.to_list() + + # Run the signer via the hermetic python toolchain (no shell involved) + ctx.actions.run( + inputs = inputs, + outputs = [out], + tools = [], + executable = python.interpreter.path, + env = env, + arguments = [ + ctx.file._gpg_signer.path, + gpg_file.path, # $1 + ctx.file.key.path, # $2 + pass_arg, # $3 (empty if none) + out.path, # $4 + src.path, # $5, + ], + progress_message = "Signing {}".format(src.basename), + mnemonic = "GpgSign", + ) + + return [ + DefaultInfo(files = depset(outs)), + OutputGroupInfo(signatures = depset(outs), originals = depset(ctx.files.srcs)), + ] + +gpg_sign = rule( + implementation = _gpg_sign_impl, + attrs = { + "srcs": attr.label_list(allow_files = True), + "key": attr.label(allow_single_file = True, mandatory = True), + "passphrase": attr.label(allow_single_file = True), + "gpg_main_script": attr.label( + allow_single_file = True, + doc = "Optional override for the gpg binary path. If unset, uses @gpg//:gpg_bins to locate 'gpg'.", + ), + "gpg_bins": attr.label(default = Label("@gpg//:gpg_bins")), + "gpg_libs": attr.label(default = Label("@gpg//:gpg_libs")), + "_gpg_signer": attr.label( + allow_single_file = True, + default = Label("//bazel:gpg_signer.py"), + ), + }, + toolchains = ["@bazel_tools//tools/python:toolchain_type"], + fragments = ["py"], +) + +# Extensions must be signed in order to be loaded into the server. This macros allows users to build +# the extension shared object, and sign it with the provided PGP key. The target for the packaged +# output is name + "_signed_lib". It's necessary to reference this target as a dependency to ensure +# the signed artifacts are generated. +def signed_mongo_cc_extension_shared_library( + name, + srcs = [], + deps = [], + private_hdrs = [], + visibility = None, + data = [], + tags = [], + copts = [], + linkopts = [], + includes = [], + linkstatic = False, + local_defines = [], + target_compatible_with = [], + defines = [], + additional_linker_inputs = [], + features = [], + exec_properties = {}, + # signing + # path to the GPG key, we are currently going to get this from the mongo repo + key = "//src/mongo/db/extension/test_examples/test_extensions_signing_keys:test_extensions_signing_private_key.asc", + passphrase = None, + sign_visibility = None, + sign_tags = None, + **kwargs): + """Build an extension shared library and sign it with a temporary GPG homedir. + + Args: + name: Name of the extension shared library target. + srcs: Sources for the extension library. + deps: Dependencies for the extension library. + private_hdrs: Private headers for the extension library. + visibility: Visibility for created targets. + data: Runtime data deps for the extension library. + tags: Tags for created targets. + copts: C/C++ compile options for the extension library. + linkopts: Link options for the extension library. + includes: Include paths for the extension library. + linkstatic: Whether to link statically (see underlying rule semantics). + local_defines: Local preprocessor defines for the extension library. + target_compatible_with: Platform constraints for created targets. + defines: Preprocessor defines for the extension library. + additional_linker_inputs: Extra linker inputs for the extension library. + features: Bazel features to enable/disable on the extension library. + exec_properties: Exec properties for created actions. + key: Label of the signing key file (private key). + passphrase: Optional label of a file containing the signing key passphrase. + sign_visibility: Optional visibility override for signing targets. + sign_tags: Optional tags for signing targets. + **kwargs: Forwarded to the underlying extension rule. + """ + if key == None: + fail("signed_mongo_cc_extension_shared_library requires a pgp key") + + sig_name = name + "_sig" + + # 1) Build the shared object + mongo_cc_extension_shared_library( + name = name, + srcs = srcs, + deps = deps, + private_hdrs = private_hdrs, + visibility = visibility, + data = data, + tags = tags, + copts = copts, + linkopts = linkopts, + includes = includes, + linkstatic = linkstatic, + local_defines = local_defines, + target_compatible_with = target_compatible_with, + defines = defines, + additional_linker_inputs = additional_linker_inputs, + features = features, + exec_properties = exec_properties, + **kwargs + ) + + # 2) Sign the produced library (ctx.files.srcs for a rule label includes its default outputs) + gpg_sign( + name = sig_name, + srcs = [":" + name], + key = key, + passphrase = passphrase, + visibility = sign_visibility if sign_visibility != None else visibility, + tags = (sign_tags if sign_tags != None else []), + ) + + # 3) Aggregate both files under name + "_signed_lib" for consumption + signed_bundle_name = name + "_signed_lib" + + native.filegroup( + name = signed_bundle_name, + srcs = [":" + name, ":" + sig_name], + visibility = visibility, + tags = tags, + ) diff --git a/buildscripts/mongo_gpg_builds/README.md b/buildscripts/mongo_gpg_builds/README.md new file mode 100644 index 00000000000..d160d324c3d --- /dev/null +++ b/buildscripts/mongo_gpg_builds/README.md @@ -0,0 +1,75 @@ +# mongo gpg builds + +This directory contains a script to produce **portable `gpg` binaries** for all our supported linux platforms: + +- **Linux** (`manylinux2014` glibc 2.17 baseline): `x86_64`, `aarch64`, `s390x`, `ppc64le` + +In particular, it builds gnupg-2.5.16 from source. + +This script is used to generate the binaries that we use bring into bazel as a dependency to sign test extensions. +All artifacts are placed in the `dist/` directory. + +--- + +## 📁 Contents + +| Script | Platform | Output | +| :----------------------- | :-------------------------------------- | :-------------------------- | +| `build_gpg_manylinux.sh` | Linux (x86_64, aarch64, s390x, ppc64le) | `dist/gpg-manylinux-` | + +--- + +## 🚀 Quick Start + +### 🐧 Linux (manylinux2014 glibc 2.17) + +**Requirements:** Docker. +To cross-build using QEMU (for aarch64/s390x/ppc64le), enable binfmt once: + +```bash +docker run --privileged --rm tonistiigi/binfmt --install all +``` + +#### Build native architecture + +```bash +./build_gpg_manylinux.sh +``` + +#### Cross-build via QEMU + +```bash +ARCH=x86_64 PLATFORM=linux/amd64 ./build_gpg_manylinux.sh +ARCH=aarch64 PLATFORM=linux/arm64 ./build_gpg_manylinux.sh +ARCH=s390x PLATFORM=linux/s390x ./build_gpg_manylinux.sh +ARCH=ppc64le PLATFORM=linux/ppc64le ./build_gpg_manylinux.sh +``` + +--- + +## ⚙️ Build Behavior (All Platforms) + +--- + +## 🧩 Environment Variables + +| Variable | Purpose | Default | +| :--------- | :---------------- | :--------- | +| `OUT_DIR` | Output directory | `./dist` | +| `ARCH` | Linux target arch | `uname -m` | +| `PLATFORM` | Docker platform | auto | + +## 📜 License & Attribution + +These scripts build **gpg** and its required dependencies from sources originally obtained from: +👉 and + +The exact sources can be obtained at the following URLs: + +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/gnupg-w32-2.5.16_20251230.tar.xz +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/libassuan-3.0.2.tar.bz2 +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/libgcrypt-1.11.2.tar.bz2 +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/libgpg-error-1.58.tar.bz2 +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/libksba-1.6.7.tar.bz2 +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/npth-1.8.tar.bz2 +- https://mdb-build-public.s3.us-east-1.amazonaws.com/gpg-binaries/SERVER-115285/sources/ntbtls-0.3.2.tar.bz2 diff --git a/buildscripts/mongo_gpg_builds/build_gpg_manylinux.sh b/buildscripts/mongo_gpg_builds/build_gpg_manylinux.sh new file mode 100755 index 00000000000..45a1bcd216e --- /dev/null +++ b/buildscripts/mongo_gpg_builds/build_gpg_manylinux.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash +set -euo pipefail + +# -------- config (overridable via env) -------------------------------------- +ARCH="${ARCH:-$(uname -m)}" # x86_64 | aarch64 | s390x | ppc64le +GPG_DIR="gnupg-2.5.16" +OUT_DIR="${OUT_DIR:-$(pwd)/dist}" +PLATFORM="${PLATFORM:-}" # e.g. linux/arm64 if you want to force +DOCKER_IMAGE="" # filled below +CPU_BASELINE="${CPU_BASELINE:-}" # default per-arch below + +# Map arch -> image + defaults +case "$ARCH" in +x86_64 | amd64) + ARCH=x86_64 + DOCKER_IMAGE="quay.io/pypa/manylinux2014_x86_64" + CPU_BASELINE="${CPU_BASELINE:-x86-64}" # or x86-64-v2 / v3 + ;; +aarch64 | arm64) + ARCH=aarch64 + DOCKER_IMAGE="quay.io/pypa/manylinux2014_aarch64" + CPU_BASELINE="${CPU_BASELINE:-generic}" + ;; +s390x | 390x) + ARCH=s390x + DOCKER_IMAGE="quay.io/pypa/manylinux2014_s390x" + CPU_BASELINE="${CPU_BASELINE:-generic}" + ;; +ppc64le | ppc) + ARCH=ppc64le + DOCKER_IMAGE="quay.io/pypa/manylinux2014_ppc64le" + CPU_BASELINE="${CPU_BASELINE:-generic}" + ;; +*) + echo "Unsupported ARCH='$ARCH'. Expected x86_64|aarch64|s390x|ppc64le." >&2 + exit 1 + ;; +esac + +mkdir -p "$OUT_DIR" + +echo "==> Build gpg for manylinux2014 ($ARCH)" +echo " Image: $DOCKER_IMAGE" +echo " CPU_BASELINE: $CPU_BASELINE" +[ -n "$PLATFORM" ] && echo " docker --platform: $PLATFORM" + +# Compose optional --platform flag +PLATFORM_ARGS=() +[ -n "$PLATFORM" ] && PLATFORM_ARGS=(--platform "$PLATFORM") + +MY_LD_FLAGS="-Wl,-rpath,\$\$ORIGIN/../libs -Wl,--enable-new-dtags" + +docker run --rm -t "${PLATFORM_ARGS[@]}" \ + -v "$OUT_DIR":/out \ + "$DOCKER_IMAGE" \ + bash -lc \ + ' + set -euo pipefail + + echo "==> glibc baseline:" + ldd --version > /tmp/lddv && head -1 /tmp/lddv + + mkdir mongo_gpg + cd mongo_gpg + GPG_ROOT_DIR=$(pwd) + mkdir gpg_bundle + mkdir gpg_bundle/bin + mkdir gpg_bundle/libs + + GPG_BUNDLE_DIR=$GPG_ROOT_DIR/gpg_bundle + + BUNDLE_BIN_DIR=$GPG_BUNDLE_DIR/bin + BUNDLE_LIBS_DIR=$GPG_BUNDLE_DIR/libs + + # download key + echo "Downloading signing key" + curl -fL -o signature_key.asc https://gnupg.org/signature_key.asc + echo "Importing signing key" + if ! out=$(gpg --batch --no-tty --import signature_key.asc 2>&1); then + echo "Ignoring keys without valid self-signed UIDs during import" + fi + + verify_gpg_sig() { + local artifact="$1" # e.g., libgpg-error-1.58.tar.bz2 + local sig_url="$2" # e.g., https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.58.tar.bz2.sig + local sig_file="${3:-$(basename "$artifact").sig}" # optional override for sig filename + echo "Verifying $sig_file" + curl -fL -o "$sig_file" "$sig_url" + if ! gpg --batch --no-tty --verify "$sig_file" "$artifact"; then + echo "Signature verification failed for $artifact" + exit 1 + fi + } + + # libgpg-error + echo "Downloading gpg-error" + curl -fL -o libgpg-error-1.58.tar.bz2 https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.58.tar.bz2 + #verify_gpg_sig "libgpg-error-1.58.tar.bz2" "https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.58.tar.bz2.sig" + + tar -xvf libgpg-error-1.58.tar.bz2 + echo "Making gpg-error" + + cd libgpg-error-1.58 + ./configure + make -j20 + make install + cp src/.libs/libgpg-error.so.0.41.1 $BUNDLE_LIBS_DIR/libgpg-error.so.0 + + # libgpgcrypt + cd $GPG_ROOT_DIR + echo "Downloading gpgcrypt" + + curl -fL -o libgcrypt-1.11.2.tar.bz2 https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.2.tar.bz2 + #verify_gpg_sig "libgcrypt-1.11.2.tar.bz2" "https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.2.tar.bz2.sig" + + tar -xvf libgcrypt-1.11.2.tar.bz2 + cd libgcrypt-1.11.2 + ./configure + make -j20 + make install + cp src/.libs/libgcrypt.so.20.6.0 $BUNDLE_LIBS_DIR/libgcrypt.so.20 + + echo "Downloading libksba" + + # libksba + cd $GPG_ROOT_DIR + curl -fL -o libksba-1.6.7.tar.bz2 https://www.gnupg.org/ftp/gcrypt/libksba/libksba-1.6.7.tar.bz2 + #verify_gpg_sig "libksba-1.6.7.tar.bz2" "https://gnupg.org/ftp/gcrypt/libksba/libksba-1.6.7.tar.bz2.sig" + + tar -xvf libksba-1.6.7.tar.bz2 + cd libksba-1.6.7 + ./configure + make -j20 + make install + cp src/.libs/libksba.so.8.14.7 $BUNDLE_LIBS_DIR/libksba.so.8 + + # libassuan + cd $GPG_ROOT_DIR + echo "Downloading libassuan" + + curl -fL -o libassuan-3.0.2.tar.bz2 https://www.gnupg.org/ftp/gcrypt/libassuan/libassuan-3.0.2.tar.bz2 + #verify_gpg_sig "libassuan-3.0.2.tar.bz2" "https://gnupg.org/ftp/gcrypt/libassuan/libassuan-3.0.2.tar.bz2.sig" + + tar -xvf libassuan-3.0.2.tar.bz2 + cd libassuan-3.0.2 + ./configure + make -j20 + make install + cp src/.libs/libassuan.so.9.0.2 $BUNDLE_LIBS_DIR/libassuan.so.9 + + # ntbtls + echo "Downloading ntbtls" + cd $GPG_ROOT_DIR + curl -fL -o ntbtls-0.3.2.tar.bz2 https://www.gnupg.org/ftp/gcrypt/ntbtls/ntbtls-0.3.2.tar.bz2 + #verify_gpg_sig "ntbtls-0.3.2.tar.bz2" "https://gnupg.org/ftp/gcrypt/ntbtls/ntbtls-0.3.2.tar.bz2.sig" + + tar -xvf ntbtls-0.3.2.tar.bz2 + cd ntbtls-0.3.2 + ./configure + make -j20 + make install + cp src/.libs/libntbtls.so.0.1.3 $BUNDLE_LIBS_DIR/libntbtls.so.0 + + # npth + echo "Downloading npth" + cd $GPG_ROOT_DIR + curl -fL -o npth-1.8.tar.bz2 https://www.gnupg.org/ftp/gcrypt/npth/npth-1.8.tar.bz2 + #verify_gpg_sig "npth-1.8.tar.bz2" "https://gnupg.org/ftp/gcrypt/npth/npth-1.8.tar.bz2.sig" + + tar -xvf npth-1.8.tar.bz2 + cd npth-1.8 + ./configure + make -j20 + make install + cp src/.libs/libnpth.so.0.3.0 $BUNDLE_LIBS_DIR/libnpth.so.0 + + # gpg + cd $GPG_ROOT_DIR + echo "Downloading gpg" + curl -fL -o gnupg-w32-2.5.16_20251230.tar.xz https://www.gnupg.org/ftp/gcrypt/gnupg/gnupg-w32-2.5.16_20251230.tar.xz + # verify_gpg_sig "gnupg-w32-2.5.16_20251230.tar.xz" "https://gnupg.org/ftp/gcrypt/gnupg/gnupg-w32-2.5.16_20251230.tar.xz.sig" + + tar -xvf gnupg-w32-2.5.16_20251230.tar.xz + echo "making gpg" + + cd gnupg-w32-2.5.16 + echo "Currently in path $(pwd)" + GPG_SRC_DIR=$(pwd) + echo $GPG_SRC_DIR + mkdir build + cd build + echo "Currently in path $(pwd)" + echo "running configure on path $GPG_SRC_DIR" + + $GPG_SRC_DIR/configure --disable-sqlite + + make -j20 LDFLAGS='"'"'-Wl,-rpath,\$$ORIGIN/../libs -Wl,--enable-new-dtags'"'"' + + cp -L bin/gpg $BUNDLE_BIN_DIR/gpg + cp -L bin/gpg-agent $BUNDLE_BIN_DIR/gpg-agent + cp -L bin/gpg-card $BUNDLE_BIN_DIR/gpg-card + cp -L bin/gpgconf $BUNDLE_BIN_DIR/gpgconf + cp -L bin/gpgconf.ctl $BUNDLE_BIN_DIR/gpgconf.ctl + cp -L bin/gpg-connect-agent $BUNDLE_BIN_DIR/gpg-connect-agent + cp -L bin/gpgsm $BUNDLE_BIN_DIR/gpgsm + cp -L bin/gpgtar $BUNDLE_BIN_DIR/gpgtar + cp -L bin/gpgv $BUNDLE_BIN_DIR/gpgv + + OUT_NAME=gpg_bundle-'"$ARCH"' + cp -r $GPG_BUNDLE_DIR /out/$OUT_NAME + ' + +echo "Built: $OUT_DIR/gpg_bundle-$ARCH" diff --git a/src/mongo/db/extension/test_examples/BUILD.bazel b/src/mongo/db/extension/test_examples/BUILD.bazel index f859f72c27c..88d73e52edf 100644 --- a/src/mongo/db/extension/test_examples/BUILD.bazel +++ b/src/mongo/db/extension/test_examples/BUILD.bazel @@ -1,7 +1,7 @@ load("//bazel/install_rules:install_rules.bzl", "extensions_with_config") -load("//bazel:mongo_src_rules.bzl", "mongo_cc_extension_shared_library") load("@poetry//:dependencies.bzl", "dependency") load("//bazel/config:render_template.bzl", "render_template") +load("//bazel:signing.bzl", "signed_mongo_cc_extension_shared_library") package(default_visibility = ["//visibility:public"]) @@ -31,34 +31,34 @@ extensions_with_config( # null_chars_string_input.js will break as not all stages from $listMqlEntities # will have a null character test. To resolve this, ensure that these new stages # are added to the "skips" list in that test. - ":bar_mongo_extension", - ":foo_mongo_extension", - ":limit_mongo_extension", - ":logging_mongo_extension", - ":debug_logging_mongo_extension", - ":parse_options_mongo_extension", - ":test_options_mongo_extension", - ":toaster_mongo_extension", - ":extension_errors_mongo_extension", - ":shapify_mongo_extension", - ":sharded_execution_serialization_mongo_extension", - ":read_n_documents_mongo_extension", - ":explain_mongo_extension", - ":metadata_mongo_extension", - ":idle_threads_mongo_extension", - ":interrupt_mongo_extension", - ":match_topN_mongo_extension", - ":native_vector_search_mongo_extension", - ":metrics_mongo_extension", - ":other_metrics_mongo_extension", + ":bar_mongo_extension_signed_lib", + ":foo_mongo_extension_signed_lib", + ":limit_mongo_extension_signed_lib", + ":logging_mongo_extension_signed_lib", + ":debug_logging_mongo_extension_signed_lib", + ":parse_options_mongo_extension_signed_lib", + ":test_options_mongo_extension_signed_lib", + ":toaster_mongo_extension_signed_lib", + ":extension_errors_mongo_extension_signed_lib", + ":shapify_mongo_extension_signed_lib", + ":sharded_execution_serialization_mongo_extension_signed_lib", + ":read_n_documents_mongo_extension_signed_lib", + ":explain_mongo_extension_signed_lib", + ":metadata_mongo_extension_signed_lib", + ":idle_threads_mongo_extension_signed_lib", + ":interrupt_mongo_extension_signed_lib", + ":match_topN_mongo_extension_signed_lib", + ":native_vector_search_mongo_extension_signed_lib", + ":metrics_mongo_extension_signed_lib", + ":other_metrics_mongo_extension_signed_lib", #################### EXTENSIONS FOR NO-PASSTHROUGH TESTS #################### # Any extension that is just loaded in a no-passthrough test MUST NOT have the # "_mongo_extension" suffix. - ":no_symbol_bad_extension", - ":duplicate_stage_descriptor_bad_extension", - ":foo_extension_v2", - ":vector_search_extension", + ":no_symbol_bad_extension_signed_lib", + ":duplicate_stage_descriptor_bad_extension_signed_lib", + ":foo_extension_v2_signed_lib", + ":vector_search_extension_signed_lib", ], ) @@ -71,7 +71,7 @@ pkg_name = "//" + package_name() + "/" # Extensions under test_examples/ [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_mongo_extension", srcs = [extension_name + ".cpp"], ) @@ -86,7 +86,7 @@ pkg_name = "//" + package_name() + "/" # Extensions under test_examples/desugar/ [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_mongo_extension", srcs = [pkg_name + "desugar:" + extension_name + ".cpp"], ) @@ -137,7 +137,7 @@ filegroup( # Extensions under test_examples/extension_options/ [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_mongo_extension", srcs = [pkg_name + "extension_options:" + extension_name + ".cpp"], ) @@ -150,7 +150,7 @@ filegroup( # Extensions under test_examples/loading/ [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_mongo_extension", srcs = [pkg_name + "loading:" + extension_name + ".cpp"], ) @@ -163,7 +163,7 @@ filegroup( # Extensions under test_examples/host_services/ [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_mongo_extension", srcs = [pkg_name + "host_services:" + extension_name + ".cpp"], ) @@ -177,7 +177,7 @@ filegroup( # Extensions under test_examples/observability/ [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_mongo_extension", srcs = [pkg_name + "observability:" + extension_name + ".cpp"], ) @@ -200,7 +200,7 @@ filegroup( # Extensions under test_examples/fail_to_load/ # Each of these should fail startup. [ - mongo_cc_extension_shared_library( + signed_mongo_cc_extension_shared_library( name = extension_name + "_bad_extension", srcs = [pkg_name + "fail_to_load:" + extension_name + ".cpp"], ) @@ -224,7 +224,7 @@ filegroup( # "foo_v2" is used for testing upgrade scenarios as the upgrade of "foo" from above. We cannot use # the "mongo_extension" suffix since loading this extension in passthroughs with "foo" V1 should # cause duplicate stage errors. -mongo_cc_extension_shared_library( +signed_mongo_cc_extension_shared_library( name = "foo_extension_v2", srcs = ["foo_v2.cpp"], ) @@ -232,12 +232,12 @@ mongo_cc_extension_shared_library( # "vector_search" is used to test that we can override the existing $vectorSearch implementation. # It must not have the _mongo_extension suffix so that it doesn't get loaded in the # Extensions-enabled variant since that would break real $vectorSearch tests. -mongo_cc_extension_shared_library( +signed_mongo_cc_extension_shared_library( name = "vector_search_extension", srcs = ["vector_search.cpp"], ) -mongo_cc_extension_shared_library( +signed_mongo_cc_extension_shared_library( name = "mongothost_extension", srcs = [pkg_name + "extension_options:mongothost.cpp"], ) diff --git a/src/mongo/db/extension/test_examples/test_extensions_signing_keys/BUILD.bazel b/src/mongo/db/extension/test_examples/test_extensions_signing_keys/BUILD.bazel new file mode 100644 index 00000000000..0da0ca36682 --- /dev/null +++ b/src/mongo/db/extension/test_examples/test_extensions_signing_keys/BUILD.bazel @@ -0,0 +1,4 @@ +exports_files( + ["test_extensions_signing_private_key.asc"], + visibility = ["//visibility:public"], +) diff --git a/src/mongo/db/extension/test_examples/test_extensions_signing_keys/test_extensions_signing_private_key.asc b/src/mongo/db/extension/test_examples/test_extensions_signing_keys/test_extensions_signing_private_key.asc new file mode 100644 index 00000000000..70b795e41cd --- /dev/null +++ b/src/mongo/db/extension/test_examples/test_extensions_signing_keys/test_extensions_signing_private_key.asc @@ -0,0 +1,106 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQcYBGlefocBEACuH1QiwjzsdekBRM6FAYBWAK2KnvGlyaKNBvH8eOEFpfmqf1XG +p8Z0DuN3X6ZNtTwDazsGBqmg3t+UkFd2EMKBklL+CIx8ELKMkKZl4ctvAa+9k8fm +cyJyWxmatoOBcih5I4GtuMpD5/+ymPxLLtTiDjuyA/+4kuon0uG3jfMYkkO+VqwL +2mfPSTz4pSC+DkTGuTGaPikN9y70qmzP4gDR5or+44mVv875XeevXQ3/bhnYDhy8 +ZQJlzB2DlxU1Yva6fZVcNOzJVbc9TIwJ19fhaIspTxW4uV6co2r92jClrFCiRfO9 ++QIVc1pXMuIwyNw+/c22O3mWRp7VQSZzzBr8PoJrlvCRbh1+mVELfT7aehCobpEz +E5cpcazmdzdishbpdn0PvIRkn6L9yse90dGvrIzaP37loYynd/VWD8E0K6qQepRr +Mfx7lK8JzrGHDbytxNY6M9eBbZUT6wZOA96dr8jo7a6XymPc+tJ8QE2ZL0rf5azW +W2fESQbW29R+sAZiO5Z6ZLEXOPGnDyeSroH9AXlisfSkrha2VndFkemNJ8dEJTPy +dCfCAiXAdduPdhszD65f2oyigBkgDUaVKqXUvc6IHEfFaLphLyg4Rs1HVIgwO7+G +seYhz9Fx1fqFHLzEfe9xIhnru1g/LmF7j3kE8CnCHY51H5f6ijmlxdD65QARAQAB +AA/+Jcd3XllNlbKZnSRcOMCUI1TfUnndDW8b3UR6AaEKlcqmyob5SfKCHRFT6kUv +FKIzhLxh4JNWf6iL0zSkPWIyiaGBb0vUi2CmFNiXufhNRucTRetIDqjBexVoD0j1 +bIMj4/C/xL0Y6bXvJUWLTBa7qtaSvjOe6uG5e22GeuiKK7UkjKpKhwHazz9hQsO1 +QHdhFcr9x60gBD8zCXPmyw4KxoAifV5KLlshIbrtt39Vt6ugYN/i/T9fT04Dw1bn +C5/Oz7TK0OhMzfxSlzLCGaqi1O31b7+Qg3V44TyVzMFoF7I1Bpht47Sg7p2KJuxL +5nDWVLaFyTnLTj9BXBzYJnzNB70u0mzCAspHk8Nicu6P6nywugmyOMzeS6It0SW2 +k1ueW6BZdXxNxVw/83mIWkoLZhTyBi42FBIaPmU7PJfii2cXIZOjxelPLXoMcMjn +IiWLOaTgNi9t+YTDLdoM0CXxJkdykkNgxIdm1LRmemURTolCScX0j9aM4RaJzxp5 +ePj5/FFgbpLJCPlQrQeHXusR+LoaiRdm9pRhhr+ewPkSn3a6BtJgHz1N7mCJFeAW +CO39jInI/cH41so9nQ/UNxCbmkIN960HxZzKvSBDN3bXfV3jMpyJ8XTscQAfRxiG +Auj9QSEfjSnmyA7HZMNaND4NkWbeP948Es6uSYJKwLU+YBEIAMwlT4oSu8opCDoo +zBvN1uNii5/otI1cs8MKUE5+6z7tbruprhxCerIq44TUA2lHF8P7mq9mV9STkt1t +WxZ5MyfHfMKEERMkNy4guNNpTheOgs22Us8ih03U0vI8cbVTCD7sy5b2BCvM81xV +5FxhdIUzeVIs6S1Q0YNuCUcW1M2CEHmFBIQaAvyHnMFqPPGPQfm2ugSzPHjNSESV +kgIaPsadpzMt6ykeI7nc2xZ048b6hQzG11lBwqRHACR+dTagZTCwA3hVTbaK5qb3 +NrzURpApHk7NybfbTKJW3AWqMPnr6iceXX8K4xvPHYJH50ghGSFR4Wv2MrEVz3s8 +voFhxkkIANpZu2NpBv3d1M85j6qzQb5bGoETn7GtjkHgjrtq6lzDCQ+xQkARx1Ma +HJGo339P9oBaPtj1z6m8DICmGnEL9RFFn/hP1xuhK+chB4fDtQ5jZpBdEcn5M7jG +10vmAWFczD3ZiUwdzX0PhAfNtic+IQkZSA5SewJYqtvMB4CDPABweWnEC+oDVD/8 +NojR13+9CflcpdnytJBGO2WB8ssA3na9ZwktT1gffTzV0c8PXyRZNcTx7e/nZpO3 +/wbsa/Lt057d1itHrOCHbUyoKGFd4a1l1t64eCSYZSsGfrykoYhltlWdwLIn1Yvb +2PzosroVM3+01rhY3A87hzwZjk2o370IAKFCnSlRc1lU7BWT0LWmEiweeVhAHG54 +u8OaPC8g5Xh3nmIjVgJQ0h9pkXcdbmjURrNAFgDKYtfP2/pCJzZGMPbpHOJK5TjI +h6tM6S+DSuF+We3xsOQzB16zgYVzECmGW9HUhQoh9T0Wti6Gv/n/XEWykc6VNK2x +cHFsuMhX4gjBxPEqVDB3+oP8i3/R15bVCsc+6ShsvxUztte8lP1d908iCOE2W45E +HD4fJyXhsBPgiRyV35eti0rxlJNPHkOz161Yuw7xr2Fv71gOJ29WMQ0boA2ofWSA +2zo1qAPmDXO0jHWXP7KDyXS64hECqHGKUvU7B3eFHLCHVk/NaeWdPC52o7RJc2Fu +dGlhZ28ucm9jaGUgKHRlc3QgZXh0ZW5zaW9ucyBzaWduaW5nIGtleSkgPHNhbnRp +YWdvLnJvY2hlQG1vbmdvZGIuY29tPokCTgQTAQoAOBYhBBxy4XjOel1OH+iNs0f1 +okoPj2xBBQJpXn6HAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEEf1okoP +j2xBKDYP/RMHSPvHkSaN+tcX+5X5gCi0d6UxAO77xNNKggtWQfLv5ye1my9kd5rz +H0uVZubA6uoZ6XWYH1Bc8jcgXO5O36UDi76gra70dgWBSGTdhb/xsv1iDyTxFk4u +q4S1nOH20rWE+knnOp5RO0OFqX0johhLg5Mf1v1nv9FMgsgSzZ48eOuzYDh9Xtep +A0wTagzPXETSk/uS8atXDJstvJUjlM/pxwOSJgh0NSE2gvUivip4+dMg2l0kPehc +t1wYJaCbk/fPFLI9RyQJEkyMKdh63AaKUZBt8IhmTmkArczvrg22XRVvlfqpQZDk +Nz6h5igPom3ADXR5CxJXGUgICRge00xAGy2J8CPmzwVbwFFhlaU6K3MZahuZ1HKW ++XUekoAhe+fOpt9911gXPRtTlf3MjfNuQ3RpCmg23Llq42VKFRpdQAMJtES3TfJE +a7M+kPWdps6kq2e+4UfMkLyXrHUJR1hVOehs65jxwNLE+byJVWxhxhExlDaoshVu +5COGOZyWJ8JqOHPyh8mmhMPi2tK5/QgCpWknK53++XuZ20iCjC7ULw0En2kUmT1o +BRQcO2x7JiJscrDOgXxmdBfj7ZSMpPB0H3YpthHo1/AHzwOMWFRDMSSJyrTlPhPh +C4yRBHF+TR5AQpilT7WQED0pCr5JdGy2KqOXFbXsf3nLHS7rih9VnQcYBGlefocB +EACcAvusRqrT0blLn30a8SrCKtgOa7/bPZ1+Yb3+aqMVTrBEQWSOol+EL/Od3n9c +7llF+Q+mDxAEuNyglg/x11Ow2PiwwZS+fmg2FVy0082JKgL3QGznksPmeZj/Z7eV +8gmpEHlIM7Q69r9DtNq8JDiJviM+QkKlOxtSnLhl8ygqAKtkxcegv4erzyddxZM0 +f+TwYnzlwQVFLeFRuzyFuHFc5VZ1BsHFCj5rX0kqo5NwktB8I8x5/ZX5JzMWQEuP +NdrmehTqhMfnWec0fIDMjRr/nwTuGxY2TSBCPqgKy78erbTypa8gf9CPzoi6HM4L +ayLOw5vqfcSvS5P19L6x4NyBIuuATX6jA219A4qIcs3C/Xm73x/x8OJc9V6qaQhN +ihjfshNyCxJ7GPmw0wp2v/4bjzqI3YInOnAzuz4FM6vwT1sF721Znbkzk9vxnOJt +y0DTMD8g7k0+N0fssBhpMlAukiaUeYD2dbzyRixZ1RYcOvF9IGVoZB/Kj5tV4kaI +jq8Mbu/v+62QWe5cazFxYBlj15f+uH23IHnUPMRnjROoFtGoP5j8CwvT20zT1a6R +BlAbAPHrd1PLEAzrI+lGfOKIPaGrKVi2gJ+1JLo6avRHNeJJbLq5F3TMpHst+pIE +xc7ybMGMdsDojw2nBDDMQ6Ypi/Mk7XwTQwUPRXR54DDxgQARAQABAA/+KnUnX+GV +gPLs/hcn+WqTq+b0CKyrOHPCxk+8YJ5NxrE1CEZRov2uh+9y2c5hE/3rvr7C0vr7 +bYWPyYY9TaA/rvvFZnkwTU1ieAGFStLvdzo/N2HJoZYQCUujZzKnRD/sAB4zG4Ky +tG9NaxQviQ9EcbwUpE9tCsGUtH1hM6Gilxe6jUDEDMvDFO9Z88uevaVmvULYYcCP +eh272b3egTfKZjElv9B4cHLSvO7gHyIIMJVL9tTZQ4PPSlCwNwiFZ7KM4bdstMwx +CRWu9dpCRSjLpbB1q4UknN+NfWnG2rVLTIKSoYyUpgAS1ugqzpejPXlJLkMOzhiv +K9OiL0gNk6Qx7egvr7+TXw5JLzdGHpCtFSLloOHaMiRmWwUedx3Iss+96JDIV1hD +PgNW2Rd1az+rWEEt+cpTmWunC2iFaDCHdXKdwHiCEMFhPkCzPJDwHejzVVowARnr +q2yTtD/iQdsBJIIkr9qoO1C+UrQe5c1UIsvWy9FvKFXgX7uZLmLU3+/MTsJQ+Y9o +QUPSw9ID1Bq7/mbIGqdI7UO5ciSqmwNrzGbDTA3yx7QQveCtljSqFPg0Q7XiKPf9 +mFeU3dYBnrSOAGqpgbHNo2EmE7+SKa2Q+2tQd1sZOM0IWjAh+qIM0qkojuK/RPDf +BoH6e9EP5Iw16XmzWiv3F04pJiyrvkOipK8IAMMYAOaE3btgliMLISu3/tZtLuHb +M8+Xb4H7gyA52WOlLtCfAdaXV63K+yaCHJzUubOrJy2e0nJGEoHFwQwHshhdks9A +c/f9t2lbDEki6Ggbt+N+mm51TURZTCbXFYCkH4VGwQ0+EXQLKtHU3eXFh49tFhWJ +0zs11+Z9CV2EeyKdLLOdzFoTkKIwGt5kqGA9bsgxUDqXigx93dJlZEP9IoJCUNJ2 +FPXYeFCW88bQaaTgJn1LhPajhlxNrcful4pVCkG5cBNCHCoDAmf5QOjT0rooPXQ8 +GcoIA6RajNYfFKfwCRJ6dK+/LQ4NOw3y53KNdQ+zkpoFxJ2Ta+65GwGj1E8IAMy3 +hEOoTIJ8nxp3Wn3iWQ4SAEMA3ZWKdsjN+aiW3mqbGdgl4zPy3P4ZQJiYeaRMPZYW +Gl4s+2n+EGE9EAgKWnm+rIOWI7oDhAD425B3sRBO2WGsl2/+VONbW0ed9ADcHSB6 +bvrlnpFTr6odgwlYdX6pWIyiYz7SQYwarMW0EYDSQkXvd/HeT7jyzUE4Ua+ZzO5o +5Jk4O9ae1RtaJPrOqCn4AH3PaCLsWiaU6DqOLpT4RxoA8ZlrJRJnmVofAGozG/SE +KTY8MRovV1UwKrVduQJkVxaXsvhZpEjjvREFtKEZyAbgBLih4AEpyoknKA3E1eB8 +3MebJgPu1oEKK/H62S8IAISgNv9YPjfP6jiUpE810J6/DIvyo993rlcfwyb1bJAF +kCxox5OCe2g+FdOY8FfdByUTLj/vzdAphnNyRN+T4q6kkMYXjOzEC0QP3UE5vNy1 +PJvgtv9hbigjBRlcWF4m/yOeTIB56sa1q2L0zaUe5ExJzg92+SPGmbwgrGR4OM7Q +lBtyJSYMabSGiBnVmC23pT/TbIMUUJJVDG+vNs3/jHsmvrQGdryyoiTE3A/Gm5VS +LRyoN6leC1TxwFGKTS6WoeFyF2TOTSSu05FRwDobUh69o4R/hyLKu8Q8augMT1E1 +dVT35or3ATe97WOpkOVVz22QzGl4LTtrjw2TaNH9CkJzBIkCNgQYAQoAIBYhBBxy +4XjOel1OH+iNs0f1okoPj2xBBQJpXn6HAhsMAAoJEEf1okoPj2xB6jUP/2OfZzzS +yJIrn84y7UC5qGYJRbxnVMnwbl2Mf8rrF2jkHsSQr3eL8Hk7mR8mxLlV7HuVF9RY +8ggh7liZs1cYVLYMIvoYWiLAE5KncB4F7R3EGFDrRpDP2yV+6KX/lbcYRvcPIcdC +le7LrWodG5MwMHO6c6fvJ307oLh0AUB6UV33UPxiJVyvWo01vVHmJfro+oMICSwe +VoRwzAFQHZM1H4pvC+MYLIkX9o5GAHhKtMiSklgSqRa9vECqXggaqj4Di0Y09ps3 +ltKWcTx83G5He+1B3Cz9IIMiloCygCE1+aOEkI6mtY3syafn+hypQzXiozjcFaBe +KkHXfaVzUmBgAwu5906IR20c18ESUkJYkyEvbVAv7C2k72EZY0VHbasi4XQdHoI2 +d1qswG8DPXpETW109np/81d4yhx5Zs9eM21Dqw/S6ZpRiNe7myjkNrHWdnz3YCvO +EOVfbQQJLhI05+yC/DAgiYZiW3g+ppFqsF8zOR+DIOSs4G8GRxq4oqrJIfEbJcO9 +z4ml95H+W+b+CbMoIT/EqYi/JstmGpf6H3RzBByRFO+HP6YWo8CT4kZzU8yAoI9/ +uGbsxORCbBXsFUWUKNzpoJKbZXndUf66OKcoGnUFXonZOE02DSDSTZ7eeORpej0n +TNkpqaN9Bduv8xozbFUitHNTPTplns4uPF9Q +=SAT8 +-----END PGP PRIVATE KEY BLOCK----- diff --git a/src/mongo/db/extension/test_examples/test_extensions_signing_keys/test_extensions_signing_public_key.asc b/src/mongo/db/extension/test_examples/test_extensions_signing_keys/test_extensions_signing_public_key.asc new file mode 100644 index 00000000000..39fff8223ad --- /dev/null +++ b/src/mongo/db/extension/test_examples/test_extensions_signing_keys/test_extensions_signing_public_key.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=Fjw3 +-----END PGP PUBLIC KEY BLOCK-----