diff --git a/all-packages.nix b/all-packages.nix index bcef5352..7f6d724b 100644 --- a/all-packages.nix +++ b/all-packages.nix @@ -27,6 +27,8 @@ withRedis = true; withTest = true; }; + rosenpass = callPackage ./pkgs/rosenpass {}; + rosenpass-tools = callPackage ./pkgs/rosenpass-tools {}; }; nixpkgs-candidates = { diff --git a/modules/all-modules.nix b/modules/all-modules.nix index add3da33..3bc110e0 100644 --- a/modules/all-modules.nix +++ b/modules/all-modules.nix @@ -2,6 +2,7 @@ # LiberaForms is intentionally disabled. # Refer to . #liberaforms = import ./liberaforms.nix; - pretalx = import ./pretalx.nix; flarum = import ./flarum.nix; + pretalx = import ./pretalx.nix; + rosenpass = import ./rosenpass.nix; } diff --git a/modules/rosenpass.nix b/modules/rosenpass.nix new file mode 100644 index 00000000..711c6e50 --- /dev/null +++ b/modules/rosenpass.nix @@ -0,0 +1,178 @@ +{ + config, + lib, + options, + pkgs, + ... +}: +with builtins; +with lib; let + cfg = config.services.rosenpass; + opt = options.services.rosenpass; +in { + options.services.rosenpass = with types; { + enable = mkEnableOption "Whether to enable the Rosenpass service to provide post-quantum secure key exchange for WireGuard."; + + package = mkPackageOption pkgs "rosenpass" {}; + + user = mkOption { + type = str; + default = "rosenpass"; + description = "User to run Rosenpass as."; + }; + + group = mkOption { + type = str; + default = "rosenpass"; + description = "Primary group of the user running Rosenpass."; + }; + + publicKeyFile = mkOption { + type = path; + description = "Path to a file containing the public key of the local Rosenpass peer. Generate this by running `rosenpass gen-keys`."; + }; + + secretKeyFile = mkOption { + type = path; + description = "Path to a file containing the secret key of the local Rosenpass peer. Generate this by running `rosenpass gen-keys`."; + }; + + defaultDevice = mkOption { + type = nullOr str; + description = "Name of the network interface to use for all peers by default."; + example = "wg0"; + }; + + listen = mkOption { + type = listOf str; + description = "List of local endpoints to listen for connections."; + default = []; + example = literalExpression "[ \"0.0.0.0:10000\" ]"; + }; + + verbosity = mkOption { + type = enum ["Verbose" "Quiet"]; + default = "Quiet"; + description = "Verbosity of output produced by the service."; + }; + + peers = let + peer = submodule { + options = { + publicKeyFile = mkOption { + type = path; + description = "Path to a file containing the public key of the remote Rosenpass peer."; + }; + + endpoint = mkOption { + type = nullOr str; + default = null; + description = "Endpoint of the remote Rosenpass peer."; + }; + + device = mkOption { + type = str; + default = cfg.defaultDevice; + defaultText = literalExpression "config.${opt.defaultDevice}"; + description = "Name of the local WireGuard interface to use for this peer."; + }; + + wireguard = mkOption { + type = submodule { + options = { + publicKey = mkOption { + type = str; + description = "WireGuard public key corresponding to the remote Rosenpass peer."; + }; + }; + }; + description = "WireGuard configuration for this peer."; + }; + }; + }; + in + mkOption { + type = listOf peer; + description = "List of peers to exchange keys with."; + default = []; + }; + + extraConfig = mkOption { + type = attrs; + description = '' + Extra configuration to be merged with the generated Rosenpass configuration file. + ''; + default = {}; + }; + }; + + config = mkIf cfg.enable { + warnings = let + netdevsList = attrValues config.systemd.network.netdevs; + publicKeyInNetdevs = peer: any (netdev: any (publicKeyInWireguardPeers peer) netdev.wireguardPeers) netdevsList; + publicKeyInWireguardPeers = peer: x: x.wireguardPeerConfig ? PublicKey && x.wireguardPeerConfig.PublicKey == peer.wireguard.publicKey; + + # NOTE: In the message below, we tried to refer to + # options.systemd.network.netdevs."".wireguardPeers.*.PublicKey + # directly, but don't know how to traverse "" and * in this path. + warningMsg = peer: "It appears that you have configured a Rosenpass peer with the Wireguard public key '${peer.wireguard.publicKey}' but there is no corresponding Wireguard peer configuration in any of `${options.systemd.network.netdevs}.\"\".wireguardPeers.*.PublicKey`. While this may work as expected, such a scenario is unusual. Please double-check your configuration."; + in + concatMap (peer: optional (!publicKeyInNetdevs peer) (warningMsg peer)) cfg.peers; + + environment.systemPackages = [cfg.package pkgs.wireguard-tools]; + + users.users."${cfg.user}" = { + isSystemUser = true; + createHome = false; + group = cfg.group; + }; + + users.groups."${cfg.group}" = {}; + + # NOTE: It would be possible to use systemd credentials for pqsk. + # + systemd.services.rosenpass = let + generatePeerConfig = { + publicKeyFile, + endpoint, + device, + wireguard, + }: + { + inherit device; + public_key = publicKeyFile; + peer = wireguard.publicKey; + extra_params = []; + } + // (optionalAttrs (endpoint != null) {inherit endpoint;}); + + generateConfig = { + publicKeyFile, + secretKeyFile, + listen, + verbosity, + peers, + ... + }: { + inherit listen verbosity; + public_key = publicKeyFile; + secret_key = secretKeyFile; + peers = map generatePeerConfig peers; + }; + toml = pkgs.formats.toml {}; + configFile = toml.generate "config.toml" (recursiveUpdate (generateConfig cfg) cfg.extraConfig); + in { + wantedBy = ["multi-user.target"]; + after = ["network-online.target"]; + path = [pkgs.wireguard-tools]; + + script = "${cfg.package}/bin/rosenpass exchange-config ${configFile}"; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + AmbientCapabilities = ["CAP_NET_ADMIN"]; + }; + }; + }; +} diff --git a/pkgs/rosenpass-tools/default.nix b/pkgs/rosenpass-tools/default.nix new file mode 100644 index 00000000..2ecc50ff --- /dev/null +++ b/pkgs/rosenpass-tools/default.nix @@ -0,0 +1,35 @@ +{ + lib, + makeWrapper, + stdenv, + coreutils, + findutils, + gawk, + rosenpass, + wireguard-tools, +}: +stdenv.mkDerivation { + pname = "rosenpass-tools"; + inherit (rosenpass) version src; + + nativeBuildInputs = [makeWrapper]; + + postInstall = let + rpDependencies = [ + coreutils + findutils + gawk + rosenpass + wireguard-tools + ]; + in '' + install -D $src/rp $out/bin/rp + install -D $src/doc/rp.1 $out/share/man/man1/rp.1 + wrapProgram $out/bin/rp --prefix PATH : ${lib.makeBinPath rpDependencies} + ''; + + meta = { + inherit (rosenpass.meta) homepage license maintainers; + description = rosenpass.meta.description + " This package contains `rp`, which is a script that wraps the `rosenpass` binary."; + }; +} diff --git a/pkgs/rosenpass/default.nix b/pkgs/rosenpass/default.nix new file mode 100644 index 00000000..77db7b59 --- /dev/null +++ b/pkgs/rosenpass/default.nix @@ -0,0 +1,69 @@ +{ + lib, + fetchFromGitHub, + nixosTests, + rustPlatform, + targetPlatform, + cmake, + libsodium, + pkg-config, +}: +rustPlatform.buildRustPackage rec { + pname = "rosenpass"; + version = "0.2.0"; + src = fetchFromGitHub { + owner = pname; + repo = pname; + rev = "v${version}"; + hash = "sha256-r7/3C5DzXP+9w4rp9XwbP+/NK1axIP6s3Iiio1xRMbk="; + }; + + cargoHash = "sha256-g2w3lZXQ3Kg3ydKdFs8P2lOPfIkfTbAF0MhxsJoX/E4="; + + nativeBuildInputs = [ + cmake # for oqs build in the oqs-sys crate + pkg-config # let libsodium-sys-stable find libsodium + rustPlatform.bindgenHook # for C-bindings in the crypto libs + ]; + + buildInputs = [libsodium]; + + # liboqs requires quite a lot of stack memory, thus we adjust + # Increase the default stack size picked for new threads (which is used + # by `cargo test`) to be _big enough_. + # Only set this value for the check phase (not as an environment variable for the derivation), + # because it is only required in this phase. + preCheck = "export RUST_MIN_STACK=${builtins.toString (8 * 1024 * 1024)}"; # 8 MiB + + # nix defaults to building for aarch64 _without_ the armv8-a + # crypto extensions, but liboqs depends on these + preBuild = + lib.optionalString targetPlatform.isAarch + ''NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto"''; + + preInstall = "install -D doc/rosenpass.1 $out/share/man/man1/rosenpass.1"; + + meta = with lib; { + description = "Build post-quantum-secure VPNs with WireGuard!"; + homepage = "https://rosenpass.eu/"; + license = with licenses; [ + mit + /* + or + */ + asl20 + ]; + platforms = platforms.all; + maintainers = with maintainers; + [ + andresnav + imincik + lorenzleutgeb + ] + ++ (with (import ../../maintainers/maintainers-list.nix); [augustebaum kubaneko]); + }; + + passthru.tests = { + inherit (nixosTests) rosenpass; + }; +} diff --git a/tests/all-tests.nix b/tests/all-tests.nix index 4275d6b3..c4ec759a 100644 --- a/tests/all-tests.nix +++ b/tests/all-tests.nix @@ -12,4 +12,13 @@ ]; }; }; + + rosenpass = import ./rosenpass { + configurations.shared = {...}: { + imports = [ + modules.rosenpass + modules.sops-nix + ]; + }; + }; } diff --git a/tests/rosenpass/.sops.yaml b/tests/rosenpass/.sops.yaml new file mode 100644 index 00000000..12fe4f93 --- /dev/null +++ b/tests/rosenpass/.sops.yaml @@ -0,0 +1,15 @@ +keys: + - &andres-nav age12qdlu87t3sh0m02eh5n3kx75d98h2evgme4uue2ucl4e4acg8ffszzlkss + - &augustebaum age16xvvc22xm35xzgc2yx6cpcz6wnww8tf6rwfmrag4vnem7nq6h9pqr33epg + - &imincik age1przhvgd5gy3kvcmlmsu47qmauhdwzzez7z89xyv623em72e9mfzskefwcl + - &lorenzleutgeb age1c0g6s6daxy79dlm9uqczwlkh0hvjpghw5h8zzljc3vs275rvvqus30hv9l + - &test age1fdlfm8xh97fwpf8fls9245wre9aktg6dzhhrr02s028kz4g38ajss2guwx +creation_rules: + - path_regex: ^(client|server)\/.*\.(yaml|bin)$ + key_groups: + - age: + - *andres-nav + - *augustebaum + - *imincik + - *lorenzleutgeb + - *test diff --git a/tests/rosenpass/client/pqpk.bin b/tests/rosenpass/client/pqpk.bin new file mode 100644 index 00000000..75338bd5 Binary files /dev/null and b/tests/rosenpass/client/pqpk.bin differ diff --git a/tests/rosenpass/client/pqsk.yaml b/tests/rosenpass/client/pqsk.yaml new file mode 100644 index 00000000..58514f91 --- /dev/null +++ b/tests/rosenpass/client/pqsk.yaml @@ -0,0 +1,36 @@ +{ + "data": "ENC[AES256_GCM,data:1fr0V215eWZKeotic8QQ/MpnXBVtevuA2SJxuklcJvrBORw7lJCefyduTuN6SKdy8ZENzfKQuEnWhbkkHLTcw7Oh9RiKQ8qVFxY/CKOjHX6OnDuxCFv7Svu9wddHS/xou2Wb/vhlUoBb90C/xYGPXqes756UsIUr1Ywj9Ny2OpZt/bJXQfYfnzj7LySBKzodRnaOvJZ+dRLs3tqHRGki5uvgR0pqRft7LxRud/ekPuaJYZ4l1pxVUY4RpicAph4HT8kKMSopcw++swbJievMIFoXQIfa7Cl7UVbfe8+W8H0vfkbDpomhmYd1NJplLOPXicjatOD7gLShbuMPtBRe3+35IVbelbfJN0rhCgzy2pVKyVz0Ev8OF59/OXDp5RIdT/X5tqDrmYEjesGqDSlBzisi04Vxnky4buX7bIJ54pK79pwKC/nQjKMO8/niVC9rJUn/XrUNwqcAnBwMXUj3Z+LxIfuHYErfJU1JGk62l0cKHdjwxRDhQAFqZe96eCZCpvPSRMCDIEoZE9zBGDw1fKXyIXCJ9fK6jknxxSz8aTEtNzuukEPF7qmlND+XHuqPSWaA0TUbFAJnPRdd6OcWhmqfijlVky98/D01rHEmB3do3UB/6ahoq/Kqu86OMskeY7RU2VG1k9Bq4KqFJvOUV0f356/mzh4eR7vzsCqYiULpeS8cr/xdg1hWy4MPC+qwz0qPtDLhLkgh6X21Wqs4ytRGeMtT8VmxIBPhtXEEwFSVUtiePE7gnv6W062CjUilrvqAxYD+qDSZwUDEy7E+KfbKZdURq/rsdUzLCKGL2VZnXZNekdnBphrZDkcWTVN393sX3Q4tjw2MtIjH1hoQr34audV2lRt0VPPDZ3CusyGfoi672MyAknT/OYn8hEZdrLVjBP1jFY5pkJ1qQqo+jSPgvgf6r6+YXqMUZr+7SpArNg1XAYw2+SkhcHc8XWeQlaFJVoyG+nr8e5RSQuUiw3BqFFOZWA2bzn+yzZHIdrdsVdC39gSFUS0Q4dEf2dVevt0USydv/5FIBAGx+jQSnhUCaMv+EiiUMa5jFbuSjs6jCzHhM/ftOqCpzRA6eeUbVZ0WBp+6gPQlX79bUeNNeeskaQIlx9IY0kY9xoh86u/RHIMPMI9suZ49RA/vCHL5LhG3b9A6HKi94BR2E1tcB7YYq8tlVXPTUrnfk5d/hZgvetPSeHG3NX6mrOsDOTazWsc/RKnuWbNOvhVgwHpeOirgHpyUMeYL2ys7mubsA27KiaZQtkukuBtKzk0thHTJqJuzDVkJfLOT/7Zlj7JP+HcnU8pKasHcvCAmgqMvKmaeYjDv0rfIpw1YaulUbrGxttUbZwA4bSd8wixIpaSPpcz8oMHwKVxy+JcTcZoFJHbT3kQdcXX9ctnk/+vqSSaNkH/iBhVG8dKD90AX4gT+4QKr8KoqpK2ZQvjbGpD4qc2/yLuUUagA73GXiECUp9nDHtWV/g5ECKj/EoGyswEnxchyMMtoRBoY1NknIf3KQh4gNLF4ue6+NlHb0IgqbEM7bHh7iyXwL13LyY90rP2m/V+Bz2WckQW2xt/bGPtQa7n9y1UB7Y+Ga8b3tHFiJmOuvCyjcAWshXVCfPaRwrCotDztgWNtny+6M5V/72pVP44G9xLLTc6KY0TZV0j+KYtgQQZ6EbDFN9jsfeoCBB0Y1ZeUpfr0lumeqKhF7isQExuKENG/jKg7N5gPSI8J4aaTSTNmEQ1jaRHZXejZs25RBrIkVyZfRpcbLoOoyZum66o5NUxCG1QhbicE+4ZdvgYdoPf0AyHXQl5uBSHQA3m6UdAdVgPFV+x4L3Hm09MrjtWXj+3NLmRmX+KF+6tbYfqWh5AZJBWH/n6uwAcgHoi1aVfbZTrSy8L+LVG4MVUld1KYvJmws5sT3a3ybiCCKtGMAxq9rtC8Y+f4Jr+WvmxXT5s2vFnmRtg0drISWKY74yGf4+N1BDgAd97cLU7L7vVHluhNduTNYFSqlLrINQ6QAudMTEPEyQ9SzpSA4bYSd2Kq1+d5+oZ6MahaFai7jWSXRt5i/GKExxMcNQduFGxep571Cczag4nCxbYom9L6X96vxqjpNGuIc/7m/YdytMu5yEW5XHMkpgmTtwogjrvYSZbNc63kymEVIaNM+p8e9gTXqPDzdQDqRK97bnOgAw5zjU2Etab0hfPfkyCEUggWPHLJ9auC3tXJqCtms02adryNxMnbE/YVIkYHsBU+WT6cRwBOzeh8GgK4j0Ndwuxg2CGfaQKkd+psvXGLQaEgT0n2i9t1lx+6kwwKOcIl+VF53T7uAVT3VGfoZqI/OXBP/TE64b50TwDzsYvjAyBEsSEDI4S0DmgTa+pqzulQ28/g5gB0WJl9+9qkVQc8MdQ2Tb04whTFTyu2ui0khsRmScND51Z/mEzuso1pFN8QJgVEh6hZ9wXdKsUyjRw0m0a3cDa9iPhb9BHfIPAe4HpxayExhQesGoUvghbn+rb02FpjdmLdajI8/A+U9eAEMbDq+42k5tBcIPDNYUXniUDlgnAlMI76i+8XVvQiVgnmFacBT69NCtm/CYaYWGzbUNcrzL4utiX7Jd5kQdRx91K8Q1jYGhnh2SPdCm5T84bICw+rVerbGR8Y6T9TY4Z13WoYuljOqUzGrt7kUId9QXmk6TKlY0vlEwXsnJyZ93dPwN4OchCK1ZA0ZL6gU9B6u6AhfhswLy8uwdqjI6Ol9vM1uw5TYsJ36QQPODFpKXGzhgevEJXL7i/aryM4cDeGP/5ry1G4SMy/PxcUZ4vEvGsQ4VeUKe0KAg0g/5VsbE3B3qNGRfFKe0tE3mzB5JishnLm2qtHI2YUPn840TgrrTzozwhmoppBNfrpeUhvG28L5GVx1qpqWv5jVrUXrAlJyvujhKQ+ojy/AzIEvMepIQSeBmnZQ6j2AJoihzLJo9JaG/WZnxCa6W/qgUdV4JXpr6Udx5j5TQtDUAQKHa4CmF9pDQp9+tO9bdHWnQm2bnlOaw27awlKs2I5K9v5voxmQduzzaYW4gfdRzgA+5SOilS9ZovlbYG1UwCyd/3l8iqUmQSC+ZdRz4LUr2tbZmHy9somVufIG21/3THxrBBjtQvGOvR7JUbuNvkGSIgSxzQLTJqsiPpJOeZxlKuK5StWzJVE9RKuutsUNbDl/Mh8lMT57agICizA2U40Gypv2/OrkwTOPJl+2qcxiAbgaHvMB/pWepx3HG8G47hBhnOJcRYxSn/MgAHiDYXjGpdPYvno1h3Yie58WZvlfhUNPd9ihJ6xF/+UCiJG37m6FlntoHoLbjb37T0B9NZivc2wMgO+CN1R2a40eeR1uZPt25kolvhuB5IEZrWoQYYa5O8zo22oGNLyguoCrUlHtr7K5JyDPOhjLYH99BofZ5moQAY0cMMHE5T42UvaNMOWIJrrArI+sMPOjDkJSrzNL5+S8mVmZdffiMkaVJg3iPyRJ611ecvCCOq/03313zjdy2dissz+l2ahOXnv2nhHOdYCT+q5BKIOEqRTygoIrraBN3yiV+q/btcvohjL0EGiGaBZSrk12uNtIA4HTxH5jajwlufFmG0KlxOCeGsPHzMtVdvgQBfABc/lva0qAOmkoBJv+tjjvzwXFPNSEIta89BVCCw+LiJGyWSRKTc8qi+y4QuaLU+QJbYz5Ulrp8kvsJdEDvhG39kBl7t8XanX+gRRhZirKDx1yMex6XJhFUbAGnUO/WAj7yhrJHXZpTkZZv3kNLzFfokpoNqNmppmQoNTpayXHDSfbyU2+LDd25i47nPFY0VkEN6pH0/QtASJjf5PiVx7rOxSUIigOUtmCPRKXTUw2PdYcaU4QgxnDwXtH6W8/MW5NrR+mIWNs8iG6EZY3R+ZM0vSk2vg2ngDzAftvxcdvIKfZRsA5BzTi3VXeaRQm/b3P8HAZbVY3TAfwkwmOEO7VmSn5DwwaZe1usLsdVRNSwSQLuUzhW3inLulrp0/pWsyEVBR8iUfs03JERSNiASOkyDOtjIj+vM8OXf91DvmUKqXrS+AXxyvqDs3tCmVTGe8lqrcZwj+zf6xQx7eJchuNLHVqWih54guddfs2FpRO1I3n6QGtELbzPtpx+RMsy8F9oQuRj9teVntzV2m5CyDKbN3qGSMly4bQg/40bvCAh1L44pOzB2v9yXLNGkpb4DvUDBYemtF2+inlba8hSJCV6/4bL95GZgFQVhUmHus9ZG/llklf0Lf/v7SYgkWPq0knHcBMQI+FsLQnK+AktayVAqiK3jMwPPDaKypT5l02tFgkS/CTatovIGITXrPu/qDk0k+oSF5G7/4YlXgxMGklwVzcAOhCWZ7Y6fYn5sTdmti+IL9BuwoOLdoULZgU5TzsMJkuPzepi1oMDbY1yvaa4BwEMkYRBa1R0dWgHhOlbJ/R1y7OwEW9M7GFnkOeZGg7pRFoux0eWOWt8kNpq31Sl7QPzhKg9+zxpbl2key8ruQKO8ihOWqDKr53M0Vw+iCsWNLj7+PbqHQ2ahKOnRpo/2PCWtB0FC8PNFbLliSWok8GMOjxXWeeckmuv0+tXACOWy/YQ1XZ5r1idVf6isEUOJ5hbIpp1ypbchpXU5g1QVBu/ddSQ7c9K5eKDuowXEbqeiG9dvZrshZyfEuOTdV3a22lipKGdHeASWATp9ymNNXjjRM7L3m3eF6flv3DEA7v1EOldzO7cgOFECishuf0r0VQwcbJON0Br0Bl1nqRkxAr+UbWebIBEJrFhnRqt8tEjdLolE+qx9Ptknd5+PFTalgfhdos62vl9m/OGJxrNO3g9BK7iqBn/44CasWJ3UHDDxVKazcvYQ3JbxfCCfzkaBVOgZTyINocwnXPdzMzcOziYY8/sYZNoKD+UpxAWLnYBmzaYPjswjFzaZfIDIXYpt5ywus0rs3W6K2Axc/EGjk2+Blp+3G8HbftiQSmizp5cy8pAA1GMA4KCSQg5zE72kG6B6fPmcEGiOvdp31PTbkdNrn8dA25KV5OXZjzzWlSeEW5TG3/Yp73w6tS3nxBApk0k0tcy+F7lshwu6ybc/TYG9prYoywcxGuUsafZesjckW0ACnj3pwpewyNtnFuvQK2LQ+hJL45fQFAZ4MmBucBP7n8/E9e8rgvQd6nI5+4QDgoJXTrNpMAkphIrK32by+J3ulbr8wKY0nuMPLSu+i3L2NzIjLmgN8iZBeTld/S1NwHvT7AlPrfMJlKBtXBdFWFDnJijacPCWJWRt7a/MK6MYZThiyWrGJOLaWyTqnwy3Up1KEfnIXoXz9HMnxlF3Fr5ws4W20vRTAEyo9xM1tb+QIGSBKOtnBFPfZ7LiSOY4TyIS3g3413FfZdsHNFHkFQavy4vyi1AwV857IFweyrIqf3G4uDCEiBkF/xsDqKtLrD42Ev0pIwWlZNZaGCZalOjVnP5Ra9Y5AGhXGDvwcHJD6GU5s9/0zR8NkhtaL+2mlcTrLEUP3UZj3wvllfWxqr67caXLkkS/88LVhN4gLyEOPH0jCvB49r8POkOK4riSak5PHlW488uNy2LuP+cnVvRPQt4yIujN2bUnl3x64F2/CmCAFFGOo1W7UR+/gpEddrJncv2x0fZ+1n9OfqpKktrkw7krX+78bE1irnOmXyE3CGV5ySzVvz60W4HMd8WQ91zl0n9XRGB062ULmiifpRp6R4egZmCoOP+h6PiTqOpYKf32Sla2y9U+Q+25cSasYEsh+i06QkJvyGwMwc9rAFRin8gkPChKn4CXbUJZElXICqF279JXYmePguIgzyc0cFTaZK7D8hwxbqbn/o83YYc7yugS/AS5Cectg81xzX+w76PRu4p1MXRrRarUvpy4PdqMeWdY2x698y//01MaWTKz7uQYIQXOMKPJsOH8gogQQr+6vXReNuwP0kBs/vmXaqpC5POL6VRJDWWYN9WUWw1lgCfx9ugCFp24Tbf7Z+Kpc7eNMARHRu3f7+bLu+gAFnZoGctkboMjikbEH/IfqRC3Z5xAPtRLtmBnNjEdZUfPhyfFwSAa+JpTvC6Y2Hntt0WdRhRvI+bWWC0C7KA4S/Ua5Vcj9GgsEaUiBObfi6Rn74NBBg6inFcuczjMkoT5elLSjW3McFNsLscOZ60A15mQzQgy/ZJFANLqJjdBm/zCznaTrDV0sh35AUMJWPiByRb58rqQioGAa/l39Q43N1zAMeHgOLmrQQQJVmOCy5TmRNBoHjRyZ1C3sVBYlzT8M20S7d/hGsPRcAbm2UsX4hbvZjtMSOKwsARg6J68Wn9CtrKdKFdqpnRxkEvv6Ga1yGr1stjBb7yfy7QBtBYVH7NfyKzUzfmwOMoBffoJQ5OGmd39Skv0iKzqXDxPlSUlOYMtANJxlph/3LfMB8R/9akWoxMUjtH2BHyhvj98RyUcCH8zvgo6SmlYIlEBTXC07Sm98lj29GX5t29GnwcKzj2350m0odEqQ771sRZZ9f0W9iTyXyFZz9YrcHy87XLBIoe8eB3G+HQQHtyPeinIuNHrCiKYqbGNgon5V7qNScEnbhBdf7QHcc4BfUMH46ABiblo/kV4TZsr8Ldaw6OOEXf+NffOFJuym918/OxZx6BQnX6nbGV//80WKTvbEZ6vPcNe2XJXJuPYvrmSRcraDWo8+Z6V52P/6NJ6in++9qtyZnzFodldhx4Llld5dsMczEmq+0MLdUIGGGPaZyEGS0SdY65UchksrpZ0WAycYChmYS6HNo3Jn1CWdFYFMVF0Em3NFQIKQU0IzICTj03VrpIbzHrJqtQABTnR4/YK5Ld2UlfmmBot5jZxcCJaxMOW+BmIKP8TXF5Y3jVt9zihN5P8GcqB+yBF3M9ZSah56gceuypry7k/24xKsdcSCvqDuiWoAL8I0fQjioF6AAO9TC7Qu0O524XSJA0ODonXg92lzQFfa0gqLCofintE7MW49c8l6Qsn5XSpJrUUqqgPVgkvgh1/2xZJtstSQGZ4svnTvCmAvVrOETE3Jxhdi+t4heQHIpLg0pxhVuiZC2U+SGHRBRCB/uIH8mRcp1BMudcVKhT5uojhKoBSqMtNWkDIIVzw/08zerK8Abcttk6GSQjr3o/IJ9NwwHx+Aty1Fm/Dm7u6evA741hSTeCMaGu1OUgkBgpP17dcfZfWSZ+KC/uxoz4Tp++ML6U1R67PEO2pqgIGyEmf9SFCeh8xvYXohGSLKJqJHMrtCRilE2c+a28RDvTXyl1/7swwypCDnSY9ZNiPzh51GdnaGOhcuvKybNeS3brwTY8SgbTmoLyxeADLK6MsPVrNs8BNBgI4ALrRz8iklM7yPi0jDds2baW8ygPnrNvXEj9iGGXNBhj/HiGvlPQxMK1icF2XhmuLQOOl0KZl0d2F6t8OolhKdKdUYcWKz+ao2VmwE906eroGxjaIf2Lt2OsmDiQZPazqc7GXes8KWOhtEC7Xt/sEjd/onSDSKjCk+9bElvIQN9NW4HpvpWKvybHNd7LnaGhh1KA3/0/NAi/oa5bljVWO3/TnDNB7cywtWVtcnGwlvhCV6DGwvwNLBcEClwX3mZAAjZ50OyWoVvvU1D3gsAQ2yrzylI6WGSXXGx2Z/2QLtPqRVhhBmMCMC88Z1xBZI44LzpFtFXKEf0qM900UOr8fyM+MhvyMoE/rc0PtYZKtrGN+NsoZl1ASQ5whg18ht2NpIT80moE6D8qUhNhyFo7k8oOpd8C+0HLSlzQe//BZK6ByDa8rrXGyogcAZxDpYzWBW2RHgZ4biMFu4cX9CnA6HMKK/TExOYXAEg4ce2c7QEX3ugavdtfkse+2mRysTUNQRGetQl2dUUSJVxqSc3AjyhHz1xLb18cyVcXmJWL/228t/sweICbpYxVguzKCvan7+b0cKM02d1RyGad05u6Ax+LeX4A7XmUFdBa05kSd2alvIMyo4sRxfen48F9aImr9CMUyrSm7OllXmSBOkb5q74nw2enlf3Oek7cCrHDgO9Gqidh4xg4a7tT6HQaZPbhCBU1oksUzAEWK4OsuYMjj+XkE0WXdySo0Cd3v6Fo+fAl6SLhxEC7SBGqHMWzWjcZp1hBqsdArSm+kExlAJLfypjUkE7AakPWH2jzuQojEGWjp/a1lceW3DLBx5suAFgR44WMFZWzXjOmHHntVXS8+Cg9+QnioUsP88GlLBhyUDLQZVveOcqXRtU7UufoQSawo7ZD1BUTKNXI5pMREEhCbooOfH6dzAMN2S6JE6Je+2iWDCBBbmG9biD3EbNwYKpbbYlez97puH+N3vvPZi5txZaVFZo7GUInooRaGr1p38D+uEOaCS7a6H2BUexpcsRTEKPS054t+xntkD44ZVGDO0fbhhac6Dw1uUNf3mwkeTQ07fmR60MOslCM1P2orFxoJ7/2ysi9yhaS86mulGUbXKn7E7fBxazwceHPdOAL+7zWa16L2RrsXMFIXAYJisGMFpPrJcKehH3K/Y4BklsHmMnJUCVlvWUsLmqJXbkRAjWmOn91o988VN7miFsPIgF9TrxQh73ks+jPBnIA7Nl5gw7bgxMBjNdrZmju1y3bhQ4B1yByGD8l51NovV+doYHArU5calKWJJVoMm/zJPm71NUA5npcWtV8N0wwGoLGE/PVM+AZPrASoafpmtgaamWOHy6d+jrtq3xZq7uBpULiNRLNEF+TUm24pBrOsGmgn/9fC/mW/UOfSQFplTRYsyI1PUK3MIpkCVxaFeb2Xqh1mnDxXUpULzw1l0bMY/VZsvhbqlGjmZ0nm9KUP2KXAFoxB/934XkjrjgRoy6/E4+vJp1LypCjNM6snIEXI3X6xKLIw2rTyy6M+GkHWPrc1UBwB+WY+369NFfRd81lXJqtWeD3vgp9lNvohpL6CrFhtjP6U5ak3cHO6AMtD+pupgMMkUx/lbSoJH9rC8S9wkmbtRyECUtgCfSormlQ7ozYzH1Ejcai2eZcFvRcYZVqbBvv6Lh926l8y2pB5KtwpLAKOSxhsiPKt3u30d+kbTOQAjEu8JvSce8Rj8K1ofa7K67oVbNirqzq/f1lwHPAwa81ZOWK+x2qCKVV3JS/AnRVXv0uLdRv7+BqrDaTZvvrFIgvDQJlmMwvetUdiYBq4Op3FaAyu8OFcwPMn511DzYUPJFN8VRvlgke6/0kizn3hDDZdIDPhSke/+32JofGkrSgksuOgCoUQtuUU9jX5vTQgkdlyideWZZIjcOcgEzuAzNtRn3C7USm02l4aBOXVzfczfqtwAR0K8isJowQP9H6/xJpMqvddJj7kD33HoO6OtrJzR+yWRSHWmVE1PCF65J0g8IiBijuuC536A/2k8MbcLlZJCY5mbploSCQ5mB9pGdSbwV0NSRdk2119eQS3D+zGedoJvwy61Rl56AsgIkgRGkghCD3F+ImDUmgb92uzSlzlspgfrwRxS2po0xFQl8+A2mlXpZAgrSbJR8Fxa9xy0wOmIL3hMSLa31FnSCmNLNIci9WAuF9ZtkbBN+XeNCOLHS5hHNvIx/5vzBg9SV9009Hgz+nhsC9+VU/nOzuSbAfofLQ6zsvVQr2hjFxrnG7E0dzucfh+mWAjejXqC/Ae3q4sOY+CMPKQ2MfkxK3FdVhOjX8OGZ20giuHpFgUBkbXqZzqZI3DFR41xwwyrVxKclagAgnEN9bS+EdXNVuafdOGpHnnRxOz60fQve9DeQL14Ntz1ticdtVHulxce4GFyhxDTymLfjHHJScwsE3NcIYyzl0/A0KlD5nsj20Lyj7ethbviwA9aVnagjjWDn2G37jpLOkrNq7sp2HOJuFLkxuQfpEtAgxOA3FmGbtPo0MEx9A83ETKLZg1HOnKuXIotFQXCjUpGJku6pxBOf0pO+yGJVQbk7J3eShMQv5V0X6BoYkZqW4Z6FKuwmS2iprmw6Zvfgoys2L9Ga0J8i1XI+17jouKg22NZQRe4WGZT+hDbyUlPGnwyLVGRI0ifd+/rq1nNWrOoJ09UM8+UnCA0u1xqnnrRFwVuYQrWAlFsSfhVCEFjBwCU2f2a27Le42Jf8wqRzoJ1Vt0yPkzrFs1S7Y+XXNNZ1zSxjM6gFzeA60KvQTwIsnS4mWI/jVk8++8bZGXFxo+yEvyxmXNndu+WttDLV1XANtJpZ36sxEmv5GPsahbskU0wRiA41BPRnTArznrtn5kQAH2opn4eYX9Bd+waLITH4D34b1X45r322cPXDtRNBzkLXGGqSUzGUHIaoz5RmnQH8uf3VgW5XZp2VH/NRxInHA9cERu65yp8hjQ2TeP3ZRr+wqomPOrgkU8WLu4ESncVATJLF2uOpcLcVbSFb0AdcrrRKJJz7R6nl9+jaDRm/KAySBqSKokQEkCJTYBJr7hWk2jTBUrSxykWrvJ80uU41FcXNC65oLPp+Ho8JpVSbsxw0UdaDO3/3r8K+etWJ06p+7gO9sCZnhAQ1/12xt0sya61UIawKRbba/3aQjRcIHMsm3ag9UByyLojLF2m/dIAgV7hSMfoPFF8cC2srA7/ZOJMZa9N1/jQIhjQBICkM502S1xetZ1HnxyehWr62ElnHSX92/zfEmlQO1zU6lewek/N9Svjj04RXzixGG3yHjT8sRhwYJenR7vYlQKWBN+Ku6xqFj4HShY7knTjIW5ujQub0H5FReThyBuOgM2opIW/FZIIt1oLLNOB8fySGizTkr62kRR9JlyU5q2oPOihp7IlOrSQLVdxKBZh5llCRKcjh1uxCGYXYO486HBKW1hgNWXWAzEqgk1AQ5iM/zxodQHEqZjuysSvh0+A+GtRHN0k6yHZllL/0AdJb9/JgzkWvcIV1u2XTfwqXuhI1M304qo5Ia25AC4rnGX/NLS1RKiLpfIv9wswmWDXJ8GFQN62Gy17FppmKW34+7aSMGVPW+QdfrjvvHPcfyyLRIOKmK63wqTCcExBMg75PcFI1JQOq21v1kxVdDzHXRpmfiJTl0KuU2XadHq/r2ibZDjyzp9Ak7iJY46+pBe1FzrkOA6t9FOhK44v35V2LggZy/Ypk4nOyTkS2sjfvXh0Wcbfr1jbyJYf00IYb+ROGgk2jkkyg8CS9jGyWsjnAcEdAdJhOuDeKh9fzbLDX97mbAaMJvwLW1MFKS5CnqHWiCNvfkuyyAuU1LQgFktbl1G7pThuyUy+DqWE0yEGWiGHCJCCUO2zQq+AOXDna0Wnngu2M5Uioe68xzeWJojidZ+1OqqbGwlJ9UvfqEcF/x0ezueCWBoUV9VRTycgIJX9RjC33501VjU/4XxDcmmtLB5mPmAYXoDx115CibTJM3etgStY3+61rL1eiBxGUfGqd6wwHvDl+WWg1CB0/IxJYEHpelK2s/D4LtyhbeXbM/5CJrJ0FHXxZysjDRayw2avsYQxf/PBcR8zlWTKtdsNgdfIIJYucNTNiWFg+YoaGHgpcJRbCDa3gdXpEVJEWGfmnyAU3bP0g94SGbc7jd75ZFTsqyrxHhWzBvKoQI1qBjCg7FELlkc1/eo58ZYk3Gsljn6pwIsH/hR5ys8dh99mDvC767J1OxafeT0/v3qrZ4WWGeTOTP1L5e9pWnwxxeZL6wMZyjOZdk0KJ7m9U0881fzUzoO0+0zCK7vLOKvokAwcExoRhNf5DAkI9AciS8JGstNg3gbIC8uNngCwrwHui7WUCtqM5BhZsw316lTJVHv4yLzDqZIaiZCmm2oxqUoV90Ea+YkL2TtrF5P+fC17IHmSK15m/I06Qs3oqc6n9PNTWlYIp2c8vdeUDyOZKjDQ3Q7LNrihDYGW1t7gdMcdeDgu9P24I9oHTipGTkDvzxxtvpUADXiFglzcEtyivIbDMOqvM8B+IUTsULXKl6KxkbHj1oMzbbVQZU/QNdTLqPeofv1PHTSAlu45uBf/VsHU/W/Gy9nWI+e94Jp1IXI+FUlAVOACTmzEy/9Jau1KnW6hio7rUKDQeQTgchK781Pott/PCM/N3iz3QZpdkhxelwJD6xsFu1rBEMAAkir/FRfPncqYeFPNc8aSwImmX0ZbDYNkLDp5JmFK8x8YFUvYZVsz1qfAw//hpJLtAZYfWzHUM6eGgvWvucKvuyRYf1s7ITPFzCKfQYBGi+FKiF1z8fM/3ODCDVwXGqLkAGqPIQzxKmBXEp83VD8CXcHhZKETzsqBKkSLanXlhnmhwM3Cl63w6cDUZH1ryAzY4Zjp3AB3IQap3a9ugj2XeEnXOhTsIWWcpZCFZrZFR2ps+khvZLg18QUfYiZY66cC5+HVb1tCt/nL1zJuJX1stHA8o7odz9pmGoWTEqTp9KzPRr4AbCiAVolaX5G4wDYRw/ijEkd8gvRJWxvIumiXEeHdw3K0wtSaFsQA4JBCtjlJViKp9c4ljxz55ZljUDWct8d3rUDM8wrlaF67WX2D4Q0zT6gMV3o+MK1kDvdTKixdOuNP/xktE3vBVLdjU7gdiUTyIqu/B/8HuvGLxRca2DNUkBlWFpSACrSdRV4pC2awUjM2rJGYW3YYIazLkbnSCj4eadirv+Ty4yROxDvAChhZ1zBTz22HWbUWPea58qyZHQ6CL2jGfZ9fEVxE41tC2vn/0v0B+0p5N0JrAuWgEAH7iwWUgvlC1r+3bRl/KWaCFX8WtyiwoDg/sLZMZjXppHAx23hVZ8GcywRvSJFfzROUM6VXP5/vovDM0+tjgciXIlJVgeGFiDJYOSzSSjYVX53hPp5X7yqk9pTCOhTI52ET/LxIBeamias4PwX16wb8IZKP0ugJk+IPTmVfP0k766fMTpFmDNeodnCdPzDjXcQ1L07wxIQiJL/2hb/Tne1rfdKFSFvYQymps/0kh5gaoj2ctH7goLNOfTBMSrXvMh773Nl+o3TTAJKLT5ObmOJd3gezelkng1m6+sjimmVoaKcc7lPs49SX94lpNkyPHx1mN6nwhBpt9BVxdA7Wk953XDcCGQ5hUBb8G9qsE8q2R+PSLFnHcqDIjMpHkgTATLkoOqtak6Uf5k5rZjaOAws4PLRcCq9cQ09meE1Bl7CUc05WROkkzbp6EdGNrmItCkpLHyRYlWTAzyAJPAIOF2ScbVxiF6nAr5uaJuvOPhLlQH3teUrro6RWczi8aRXoNH0eLt3AlIdyNAJQzPW9hGEd9kacBDngi7ZKcHdWOt67BSt4RpPaW5E8BfI9QPUFDHFHtU7lVoIHTlm482jYgWW6toxCz8gX5GuJfB4IXm3zwfxVlHCplqxjz8ATzCGsepHyHI/N+OF3xTZRQPIRuzGydsjrFNHr3gnGy5EKVjfpIg5wAX4p9QZJcB6J5okD2EZhQe4nxvj2BzLJkX46aIdpqeatYvURC7fzD6e4LvXpW71z2BAl6t0Z6SNKublxkPtNFJcqLcyw4wqV5ND/EdobGFC3X2i+5dBdSWQD7W1FJz5eLzQnuYP/VvuauyqgzILmPJxOYMLOiqj58yrnP98LG5MheGmDDboZXS6vbPGSwBie8hsX9VPnIY6uHdabrBGw2trNRykZIlSKITOHXbiA8CIdIK7ftjW9FyYkiTn0TevqzcwV2BjxWUKs05Kpc0opNl2Ywkp8VmElQmoMwtapYbGILG9J9O38jsuAI8/+uhp3XDES+hJQGjs5tATC7LR+r4uCytctMx25SlvIV8euJPNAugJJ7AwPtUG6mdwymbujb5uz/aHF9QKSGYRPfjKX9e7LSZbtA+0SR81eXDQUd//H5dcjP52oDORETtmtLxiBhpFLhr7uCnS0EqiDwLkcSRKgJLBdNrLMWXW10P6jxqKIIId6sigHoq6GZ/dXhlt+L7yIq4Tq1fSKQbbBk7OlQLIHhaEgehHYyrLXPJFIi/3QjCFhL/Z/ziaeRidGBh2D5tfcwkPtoYFn8pJLwdZzNJ8TxG/izY5LZGjUbuWvTtjJPyXIbyexBMaOUquOllKahBZjcryoTpm7Vo1REbAtRiGmsD2L2bXjzh2IXubgDHP5YeYlWfvu/01Z/l6tCJY3HwSMrXuavm1bRirPvqgJNqYPruNEGIi0XYitoP0vv6cSc9j95wVrCn1yGyWV2tWky91VttNxmf3DWII/KxYYpmWqjWxfmBoZ6qHFQm2nHBiHIT0fGitUT3GwPj2Z8QN12M/S3uH/UwCbYCzlr7O8Di4pxi6mWVX7nZXkbZI8BSEGr3Y6sUYVd60LiiCmmcwjmSsMRw+5ym2iP9VB9xnfGRzlqRsLAdQtMhiHxRT9G7EAzekjOT0iK6c/p6JN1uEBf3blt8bEX6UrfTxaUoEyNR9wC//yOn28fHdaexWUIhGTpeOZSfRhAvywnSD3yNKBJpD0KQt0MynxUku4TCrCekNThZnoPXPnR/pTRkrs1EKbIzlx1jdK5pNgzCbSLHoiUdT4Q5YOQM1GncyT8tgkkU57d+rWvyoqejhVg6O7NoHinjPuPp14S+PWWtNxrFWU58aWtoWsd9kbkZXf7v7b1SaoxLEmClI1S446S8heszJlQ3JlJc5hP1DRZ9kG1dAtGNcxEkinFIZRZStIbJfbSUGZA1cEEK9HGB93HLrKn/DpfO4uqhlV7mB/FiS56dh2FFa3DUbFU/5bBYdgpphtdMsEEw1+YhkZGTIU4CK/zm3blz9f4VVLSsaF16dn3sC1TsiSsfVdL7lmWwUAUZdOtdc4BxB73r0tkrcPXebaTo1PUiyRPyNpqtAKNaKavkLPpUPIFCXlKw/e1ZE3sVQXBVNdn7PNh0SitJhtDPzWTKGFkgAl1KWC4ZKlKWvZPS0ZwhO2bqm1dnOKLRVl/LoYq844kr3G/Yu3zneNcTYJik0F6c92+JDh2bhbb9qt82/u25ykf+cM5A1vRk0vwXgsIhoGphjvT4V4uHPjbj1sxAnutXQuMwheHStK1rEsMp9Zoa3sdpk8vvFPfGzy8tEhTV3qMf/UhzxeKiTEDPfSlpwMlYKIJfvyLfZXVda4DoZW6dF7pFbEFmJ7C9rqONSc8UQEQWVDrzhMKfurBfmLI8Icb6zAea18esnJk2Yjh/aU27iwxci3AHlkkeO0HTDAoK9JA8ew9NQ+9kXs6NZkNqjVw3pWpP+VKma7wc4keVr1pU8VlypK4GJxNCjBz8k0lWPS8SNV5pQc7yuXdLEeYyazoV+yf5lWmiYgXZ0Bl+e4vSu7goB9o1ZQSJePP+LxW0o2hxK55nq9wPQuh4SvRjOSQxSFtA83wvO77b0mCRShRAWdI7J5gLZCXutotDT/JiUlxdZ6ajYxUl5wH9+/0sIhNHbQEUX5X+132iKr2Zia9Ka8EC0MEMtZN1Pb23+IT7EKZ4xTotketmGE4KVt4jK/bPE5aUCXpW/Z8Q4JNdKq+xnqZ1HIX4Yqi8xsDuyz2bMylZNcT8hb01Pd3qDhBHLMXKuDzGtmtVrh/zi78MpEdjgtdrZ9CBXpgmCkN2Z3pUdKJDXao3M0GKZAKRNQxt1l2ylot0AuDw3+EXtI/RkASqdHglDOSHDRBYmRvTq3/4z52m04bbZEnLxrf2kScbDz3lRFWcDHfD3amZOi0OF7KjBKs+U9kh0uFEzzxTQmBoehOnFYj2etLxCay87Jwn+M4F3CJGx5iWC49ONW67arEw9xtF/il5UzqIisoWj/LKYzFoRLOZstL5Wh+eDgOmwdaw/9JyJrifs3XnQoM8I6b/PeJzwrWdGaIdG4inOgQWZsaxcOhI3Eh6tjguhwZN4hP6k3cQtjFD+3ojLyNQFAdkfmF4Dfm5zsi9NoXRfwPlq0fU2r+GAajpXQaz6mO83EQ/5/sEr6VSvdbOK+2V+UmVOkd5kVYVYayZEid5oEUMP1CUVGsq9Qo9yh/T7I+gfFaPWL8t1OjLQ/6C6XhdxoGdn1NSPNnQn4Ri84T+Und92zN4baKjjokWo0qoG3qdVuEioPB0Nx9riG3PL46m/sY88GzIq7NP1uq/fa2jV7V/3KRhxBQz2oqAQ2B8tbK8xBeyqWbWVnLrSZZ3ZKEffX+DNu/tfcmjOtibKWlO3NcpR0+8Su5VMuAo7nes63+sDVfsaJQiCR5IdcTYXCfXl4F4QwSb2DUE64GN9nJOoXaGhhhJ4bVuWw/wAQukXh1WwRxjpz1/dd7+w0YqG2/gT1Jnw1eD0tdwhNegK9QZq7lgCLdNMLunKeAxP2UOcrFTedFI1484D7VXUr0/NPYbmcsixW5mtpqfQC/B+LBl5U52pz1VbKUZvYv4eLg7Wr4cM6ptpXOB712WfUh1YKtCaAz9oyu3RZpoihqNJNU2LyBTN+7Jzo+u6HnbioIlVB9z0MHF9RFe6zx+5+1kXFHwtU1iHrIuiPOjl0I57/1iaE7iuWmKcvxFhSxXHS8aMYMXgbjuv3fJ6cmvDUAD1hp+cQVFloJDQUfZw05XO6r8dIZsPZhnBjWRYcHqNwHhM2sckQ1x1wLesxzwPp53XZo0eLig2FmIJWjjZ3G2osrwzLWcGW1Yi+CCtl/Z35bAM92ZOlNWtTvMBZQSp8b3AO1MVMj4Oq2/KCwtaV3dSO9SDcIjpwFHQi7Nkcy1Pg7YrDeA2M76f53FP/OnhFp8SD3wSdQr/m1qx3E7Cid1+0OLOHdtZuEBVEY8klEmePRuN0UBbDcsUJhanzkWTIbLLzOmZNU0I6OLraWBcZxpO8Be9XEJlCNoUzQ6nmG6XnQdcB9ixOEspPsLFySF1nprWw+rRQSNMR/WDfQUzUCPQk1b7F9+lNNHlG1Zf6BEkPzXmOsFNnbyocwEhSTTYJbtiH86mdOYULeKkD8fMS/k0zly7AeEwXcyugwtn0xuoCF6jwU1DLpQG2UDacDx9ZdmPo05I20dGIU45R1d2ZmVEzRABAg+0uiApfFt/GB4VazgWD7ALWjH2sjZRRPpRlodjEqJBdCHjriJc8NQfN44QMVyzWhrd2In3FdQdo2Jv2R6fY+vE9W30XRMKHslUBrjGLWg+CHyp8E15ZB299UZyc2vuduKSmZFv8Sjz2JTvLSdi5mP461MDTLgXpsgUOg1wKgaE3ubZtXEkiWiopgtWgp4gn2IMTXkbEQe89p2Do9nlhZMsA/5z0Qwvr/IdbBxqyOEoBOArrbpeUsFT00NL5uikAbngJvPGrNFiHsU6ImzF/JkYwdC/6Lrhs/C2kivEkt1MkUmv9+VGVSWQKVsZs9pGYG3Al+gX/+eFUNoFOuelkj+8xPeN58ULTMoDOfHoj1ftoSQx0lcutf9v1BPjN67uumQuYtQG3WQkIY3/kZUknvrhmb1xjIAL238geq976j/fsAPY5nu9KGZeu61vAQrgtcNyvghWfOI+iT99QpqBhbycGmNAfaADxFwhsFy2Yo3MubK0FP2bRkF7bdyHMozskD8JTPHHHlzHwssaEPi4nobjO+eyGLkmePSUSDeRoDmYye0esqBpqf4kZKVBbgqaxQnmhqDZKNnVPGisfhu5BV7YcqFfU40jwKIbBp1szPSaAWbjuCtEDggbh/SR8iNmurnqRGLmbn9YZQvO6HmNyJfFJOwUyDVhASy0eqbzX92SmL+8rlsRDioj+hmisDXC9ZC8wamrzJhlD46P5dhQA2iHA2IKjOEBSXEN7HJDiK1oZvyvuGp0QVLlUgdoG0hCuc6LHynBoICgfjZAzXIYZ8JQgJnNfN5rIWJPyiexQfeLVMkDILuxAVx8sYgi/AbfbElEbaFC6kVmT/5+g6KxpQgD9CRfk0kpyQEGBMUKH8idecZW38q9tP0LB9LUWwwlEabWkHb0YG8wz9jbYVCfaZo85Ls7Lf38itQ6k/AeLYzdvyiFFDcQpE+suttJ+jH9PG3JUrCFVAGwtHhVquYFMij7Liej3Sfzwbp5RSdjRL1JBNsz0cDme1R5oVi7Yic3co7cfd1pruBHJayEQZl6tku7+xLZnaU9umxzpMg4FnHkuWt80Q5TMGnEW3/2iqNSlu3BL2Ld75tFR56cwNiA4Kqp11GEIG2y93huf5OixgkwRpfSFbi6y/CYGjXZnSKtygu2/qkJo/otykPq8tesR/WR5LXu0XV5JQZdrebYC8p0yGSZWo3YWG8jVMnjZQ3SW4pl/qZxKxF30A1OK9wc6+MtIQdPB/Kz9kp8LZpBHH3gKeXiBSPJLiv8nWLsBYkfTAhBKan0=,iv:5y+De7i33X5RjD7GxxnDJ2InicPgfSVIOYevBA/mito=,tag:UtUXR3evvnfMeDYENtqA5w==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age12qdlu87t3sh0m02eh5n3kx75d98h2evgme4uue2ucl4e4acg8ffszzlkss", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWk83NjFqcjZwZjdZb2Rz\nUDJuMXFmZEN3elVtUUUzT1dYNFVBczRXUlV3CjIreG4zRnpuQS9ScFpJV3VXcTZ6\nN2llOUdvczRGT1FHU2RDeVVVT1NiRUEKLS0tIDFMK3doZm1pamlRNEYxOVlycGZY\nODdtZjhVMzcxaUZEREtqMXhQZW55RmsKdbBSAnJChkSrYxrf7U25CEUuqAbQKXGB\nzH42VNl/7hUuuHetg+mKKe2zv1BhjHxk3tEsBe5OZ8WFKanKDtnoaQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age16xvvc22xm35xzgc2yx6cpcz6wnww8tf6rwfmrag4vnem7nq6h9pqr33epg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWNktEaVo4eVhXU0JBb2pW\nNkJXZ1I1WUpIQStGaE9lTFUzZHhYcUpVSnowCisxOTVrVWVvN1dTcmxYUVF5UElE\nRmo3bWVleHlzOWtWQW1RZHhYay9sdjAKLS0tIFV5a1pnS05obmVxbUIyRGt3Z3dU\nTklRZ25NS1FDaW50YjVxOGtoVnZZaEkKK7K+d4mhrlHJmcmb6ksW3yN6GvxwrhlM\n7odVXDW4A8doEMbWFcx83P/a2UfApqsfvzAebrIL9GTK4gYnxXQlBQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1przhvgd5gy3kvcmlmsu47qmauhdwzzez7z89xyv623em72e9mfzskefwcl", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzRnRlS01JY2g2Y3lQZENJ\nK1RWOGlOSk9JTnN5NFBTZGFsWUxsN1pnSkJvCjBkNkIyZWlJYVEzRHNRSUJEVGxV\nOVpzanQxcmMzWDV2dXhRbHp0NkJIVk0KLS0tIGQ2QUNSbjFCUDBLUmllWXQ4bFlD\nVVZ0WEhnZytmS25QdHZ4bGVRbHh5UFkK5gLF59r1o/OI8tROjsxb08oMQgzUJu6w\n8OM3ZR3GbYK7k8blBuKsEGSyo7mlQwK/oe5LbM4Q9U/7trfrTiSD2w==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1c0g6s6daxy79dlm9uqczwlkh0hvjpghw5h8zzljc3vs275rvvqus30hv9l", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArT2U4U0RWekN1Z242dXJP\nMVgzbDlaNHNtWFJudFdCS1B0NVZKUi9qM2swCnRtVEg0U3pOS1JHd2xqa2dzOW9s\nUVUyUzNIcHpXTitZOUp2Y0FncXRwQkkKLS0tIFV2ZWlIcGhuLzkzT21ISTFxZ01D\nKzZtMVdwdmFON0I1cFk5ekF3NnhaVm8KObr8p8s2cNlmMJwnk9PV4ujoOQIyeUEp\nCCaD8ar+YiA/FhRvCa1dt926d2bV/DebSTAX7Bm3f8GeLv5XAkes1A==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1fdlfm8xh97fwpf8fls9245wre9aktg6dzhhrr02s028kz4g38ajss2guwx", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiVkwxSlBnOVpGcDV1Vm5W\nNUtHbkZMUmZlWEk0Q0IyQjhGVzUrandkUENVCkZlNnMxR3lsMWNOeWJ1VFlzNWJG\nVjdxRGNCdWRCUGF1VlpSQnl3c3grVmMKLS0tIDdITEJvUmFIM1NqNjY0NnJySDVv\ndkFWbzkyOVNQUTN2aWV1eU8rYjdrSjAKkGlVnMsM3KwO5CtYpSNi5J9Ol+lqvpFK\nZqOGH3i2uaytAZfMvTyFi5BXIkJkBFO8V2z+AOEFt3+yUToQDMB78w==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2023-09-05T18:40:10Z", + "mac": "ENC[AES256_GCM,data:87v+Y8LRuaevW+ZJZUmWSoVA1xY3DpaCwCU1+B8NY62rPKp4ih9YtJh8FFaybzfoVUR0C2mRDQ2bXVX+6E2oGYsPGAo51RcqjpGHZumE75tYwtdCNNkJ+kB/gA4AUlTXQKmh1M99A2ciFV1G8D15is5JjHG7skpD6/As5FUhE10=,iv:ClxGbiBNiC7R7F3KNqoNk6o6MFHodyxhO9Dtt0PggW8=,tag:qUWh3saA7Q2AA2cDNbB+Zw==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.7.3" + } +} \ No newline at end of file diff --git a/tests/rosenpass/client/sops.yaml b/tests/rosenpass/client/sops.yaml new file mode 100644 index 00000000..72f6d39f --- /dev/null +++ b/tests/rosenpass/client/sops.yaml @@ -0,0 +1,58 @@ +wireguard: + wgsk: ENC[AES256_GCM,data:k+45ywsKGgTelWa3tjFZyaRzKya/yLVPTM2CwwQNzJ9fx54olcfzLlwpxi8=,iv:YoLWrnVZSEFyGmC2k7KmAiWOrtjtBEhR5cwX6ehWnVc=,tag:SkJh7vGBwL2nmIwJx++b7g==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age12qdlu87t3sh0m02eh5n3kx75d98h2evgme4uue2ucl4e4acg8ffszzlkss + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBISXREQ2tlVUtVUHNkSCsz + b2NBOG00UmZjZkVCQ2pyK3lQblRCMlBHQUJZCmFEcVVZNDZYWGZrcVl6RDZYVnAw + aTlmWTNsbkVaNC9FMVBlQW9OYmNpcDAKLS0tIEw1SThDcEJmSnpQYVBueHRLZFRr + NlVmQ3JXUTd6dStCSHlITW04WllyUjgKKLk6KAZV2496O+LiZNSXDSm92VSyT22y + wsiHb9wzuKP5qUqPsbNezSsyRUbgPpn3HTO+v7JBuYqu5GLJj3RIfA== + -----END AGE ENCRYPTED FILE----- + - recipient: age16xvvc22xm35xzgc2yx6cpcz6wnww8tf6rwfmrag4vnem7nq6h9pqr33epg + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZZndSaWd0cktaL2dFbWxW + UWZHTk44V3Y1bzBSUnRhbFloVlpRWXJIU0c0Cng2ZmN3YnJWSitSWnNjUUhGeENS + SG1iQzkwaVUvUFZGVEF5VUhEaHpqNlUKLS0tIG5kV1Z3ODJmdEFNSm14N3IzblJq + eDltbkNNc0g5eVk4a1dMSTQ5VjRoRVUKs+Pxd0W6MRIjSsS2IFHdX4Q4m84v7K0H + JoY+r4I1NxAJWt6uoDhc9JIiagwPABjzN5nfe1+4o0nYmwmndG4XiQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1przhvgd5gy3kvcmlmsu47qmauhdwzzez7z89xyv623em72e9mfzskefwcl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2dGI4Mk9yc3RXL2FEdFBH + RjRmalliZ0ZVTUJuQkUrQ1BSdHQraFo4L2wwCkVNdjM4QVpEZGoyMEllWjRpOW5u + TjJHOVFXeGxYYVNyZjBRMGd1amFLOEUKLS0tIHNhU0QrYUwwYXBZZjFKT29vMVpy + NTRaSFdhR05qMitNcEZGRkMwd0g1d28KYInWBN/Qmp1y8A0gCk9LDXshkf27/xzj + 7Tdk57u52E7MqAcWUO8R8EbI79ePH2j4VXzhVNKsnjKODZ2MrcGvRg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1c0g6s6daxy79dlm9uqczwlkh0hvjpghw5h8zzljc3vs275rvvqus30hv9l + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxT1Z3MzlxMjgrY1VHR2xt + aFNreEszNFBUZGRoSEJ5QVRRMVc4Ty9FYnhzCkdzT2tWNXNKclQzVGJHMEtGR01E + ejlWbDAwTmYxNUgxL2dXbVg5ankwRTgKLS0tIHpvWUJ0UGhWMlgxMjk5Tko3Skdq + V05aR2JyU2hac2F1UWx6VnpxekF6UGsK9iBYVAkMCvmCIcxCkGU3Bq9t7kFs2gyz + uiUBUxgLTyfdmxZ4HDQFpMm66O6SHc5Zx0738/AClU89fhvtANJeyw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1fdlfm8xh97fwpf8fls9245wre9aktg6dzhhrr02s028kz4g38ajss2guwx + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJUTFQZzljQ3hCUHFESUlm + aGJOeXUvc0ZDTm1jOGlnMnM0QzFOOGRuODI0CjdlM2ZXWnJFUFFqVXFZRGFsZ2V2 + SmxHUGhtM2Y2d016V0ZYZkp1cXFMSFkKLS0tIGlvRjNHWDFEUEY1bXRqaWtjOXpi + RWhubmtWdVZwbml6QzlMcXVwL0RZa1EKcBXzTtmaB4Rg+qHVQilx8jPVjHbJ366r + OOYx12stTCvAcbrLCUhZRhsm9mLEmudFQcC36QxqxJfhYB3tKukLaQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-09-05T18:39:18Z" + mac: ENC[AES256_GCM,data:ZLevHXqYLBzz9F+UDHWGXCv9gjgoWRlhOyPB2hDXbmTptiDwoeJ1AAyXWCXCmgdR4zsNv9UuIpY++Q7zY1r2TEsQSfdCH1sELcBfn41QidLvrQDo5Ua1k08SiNyAeytsDAXRCr0YuOSA7gKydKt40RXCAo9FYNpr6iII7XWHLyI=,iv:fqt6TaPKgZyxn+NqXeH1i5kV2i6nprAlkvmRGkRU7V4=,tag:nZLc9jdY5kKeQ+JoX8eWeA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3 diff --git a/tests/rosenpass/default.nix b/tests/rosenpass/default.nix new file mode 100644 index 00000000..0f0d6d12 --- /dev/null +++ b/tests/rosenpass/default.nix @@ -0,0 +1,183 @@ +{configurations, ...}: let + deviceName = "rp0"; + + server = { + ip = "fe80::1"; + wg = { + public = "mQufmDFeQQuU/fIaB2hHgluhjjm1ypK4hJr1cW3WqAw="; + secret = { + sopsFile = ./server/sops.yaml; + key = "wireguard/wgsk"; + }; + listen = 10000; + }; + rp = { + secret = { + sopsFile = ./server/pqsk.yaml; + format = "binary"; + }; + public = ./server/pqpk.bin; + }; + }; + client = { + ip = "fe80::2"; + wg = { + public = "Mb3GOlT7oS+F3JntVKiaD7SpHxLxNdtEmWz/9FMnRFU="; + secret = { + sopsFile = ./client/sops.yaml; + key = "wireguard/wgsk"; + }; + }; + rp = { + secret = { + sopsFile = ./client/pqsk.yaml; + format = "binary"; + }; + public = ./client/pqpk.bin; + }; + }; +in { + name = "rosenpass"; + + nodes = let + sopsPath = config: name: config.sops.secrets.${name}.path; + etcPath = config: name: "/etc/" + config.environment.etc.${name}.target; + + shared = peer: { + config, + modulesPath, + ... + }: { + imports = [configurations.shared]; + + boot.kernelModules = ["wireguard"]; + + services.rosenpass = { + enable = true; + publicKeyFile = etcPath config "rosenpass/pqpk"; + secretKeyFile = sopsPath config "rosenpass/pqsk"; + defaultDevice = deviceName; + }; + + networking.firewall.allowedUDPPorts = [9999]; + + systemd = { + network = { + enable = true; + networks."rosenpass" = { + matchConfig.Name = deviceName; + networkConfig.IPForward = true; + address = ["${peer.ip}/64"]; + }; + + netdevs."10-rp0" = { + netdevConfig = { + Kind = "wireguard"; + Name = deviceName; + }; + wireguardConfig.PrivateKeyFile = sopsPath config "wireguard/wgsk"; + }; + }; + }; + + environment.etc."rosenpass/pqpk" = { + inherit (config.services.rosenpass) user group; + source = peer.rp.public; + }; + + sops = { + age.keyFile = ./keys.txt; + secrets = { + "wireguard/wgsk" = + peer.wg.secret + // { + owner = "systemd-network"; + group = "systemd-network"; + }; + "rosenpass/pqsk" = + peer.rp.secret + // { + inherit (config.services.rosenpass) group; + owner = config.services.rosenpass.user; + }; + }; + }; + }; + in { + server = {config, ...}: { + imports = [(shared server)]; + + networking.firewall.allowedUDPPorts = [server.wg.listen]; + + systemd.network.netdevs."10-${deviceName}" = { + wireguardConfig.ListenPort = server.wg.listen; + wireguardPeers = [ + { + wireguardPeerConfig = { + AllowedIPs = ["::/0"]; + PublicKey = client.wg.public; + }; + } + ]; + }; + + services.rosenpass = { + listen = ["0.0.0.0:9999"]; + peers = [ + { + publicKeyFile = etcPath config "rosenpass/peers/client/pqpk"; + wireguard.publicKey = client.wg.public; + } + ]; + }; + + environment.etc."rosenpass/peers/client/pqpk" = { + inherit (config.services.rosenpass) user group; + source = ./client/pqpk.bin; + }; + }; + client = {config, ...}: { + imports = [(shared client)]; + + systemd.network.netdevs."10-${deviceName}".wireguardPeers = [ + { + wireguardPeerConfig = { + AllowedIPs = ["::/0"]; + PublicKey = server.wg.public; + Endpoint = "server:${builtins.toString server.wg.listen}"; + }; + } + ]; + + services.rosenpass = { + peers = [ + { + publicKeyFile = etcPath config "rosenpass/peers/server/pqpk"; + endpoint = "server:9999"; + wireguard.publicKey = server.wg.public; + } + ]; + }; + + environment.etc."rosenpass/peers/server/pqpk" = { + inherit (config.services.rosenpass) user group; + source = ./server/pqpk.bin; + }; + }; + }; + + testScript = {nodes, ...}: '' + start_all() + + with subtest("rosenpass"): + server.wait_for_unit("rosenpass.service") + client.wait_for_unit("rosenpass.service") + + client.succeed("ping -c 2 -i 0.5 ${server.ip}%${deviceName}") + + # Rosenpass works by setting the WireGuard preshared key at regular intervals. + # Thus, if it is not active, then no key will be set, and the output of `wg show` will contain "none". + # Otherwise, if it is active, then the key will be set and "none" will not be found in the output of `wg show`. + server.wait_until_succeeds("wg show all preshared-keys | grep --invert-match none", timeout=5) + ''; +} diff --git a/tests/rosenpass/keys.txt b/tests/rosenpass/keys.txt new file mode 100644 index 00000000..22617a6f --- /dev/null +++ b/tests/rosenpass/keys.txt @@ -0,0 +1,2 @@ +# public key: age1fdlfm8xh97fwpf8fls9245wre9aktg6dzhhrr02s028kz4g38ajss2guwx +AGE-SECRET-KEY-1WFRN5AHQSE0XWPF82E2ZX3SJTLUXFWETX0XKY7PMLV36PYNQ6XUQ2AZ6M4 diff --git a/tests/rosenpass/server/pqpk.bin b/tests/rosenpass/server/pqpk.bin new file mode 100644 index 00000000..2a41ad57 Binary files /dev/null and b/tests/rosenpass/server/pqpk.bin differ diff --git a/tests/rosenpass/server/pqsk.yaml b/tests/rosenpass/server/pqsk.yaml new file mode 100644 index 00000000..02fba8ed --- /dev/null +++ b/tests/rosenpass/server/pqsk.yaml @@ -0,0 +1,36 @@ +{ + "data": "ENC[AES256_GCM,data:qeVzzUah2V3CjOfefxy9QVVgsFIpaFPIZvc0h1fZPDzc9DvTplotOzrR57K+tcngj8hhz0D6vilHgxjnY558tGAUkM+UKEAncxeqYImIUVj4A0/Y9xjUxoVHE6YEafEUlxUcR9MqZ5MwfDcGGxAbFzZCXK4UcpOHfZRKBl1ODFWnLEWgvr1tJzSLErasGakhgNM0QmhwFOFL+i9qkQwRs6to3nT4JwkpVkFiUgK98qCF195qSqlQLI/B7LaafkJvpEC/ieU4+4bpBB5rO1VpyOSDwJAxllCKB8EYgwSd4O81mm/IbPWJe7I1GA3dhjL1fdB8l4ZflQC+THMWXayChqailfPh4gvUoZyuRaX3mNP31Kz2SOg8S4h3BBX1wcGmeVnwvLAbPjufr6k/VmwtUlQsqiTUNtflPtEHDzDp4SRwXa/ZX7rUT+zYmRJXSZ03HEBW/8dbRAXX1cGv3OCM7L+PKfFSS3hoI2kwKhmbFhnzoUSQwh3YCfuqn4cjL27DDp76cD+xp0YYmZd6Pn+gb91NAXfa79JUKZA8/6Mrog+Cfnf3Dw0chgtpGN5wdIHrqPbdMyK5+f8DsyGs8TRh40ssYEjJQqUDdt1Ho6nmwgRZaL+srDsndyH3T1+mxmJLjLKmHLC1nr/BD0ciiuhoSQOQFlxQH/mIz258pm5nSmGL+o8JybUGXX06QL5NHd5efWpuFRuQxJBXBhp2DDC5vsVTS1PTs1HUq3bl//Z/HI/nHTC7pEaVAWwg4sIaKlXEE9oJ4bRdwIN63GDSybYwhTBYwQJzfyPJ96DFndW38VHjTyANZStG4oTYjyp+wWQN/oF498lqYDw6I8tGoUQlnuL9bsE1XGbYzD96Nt13pdE8XA83IDB8pNPbQxrb5W8FsALSJeKvZdAbFabbH30QLuk9t6o5maWN8fpT3iGdQVwKkT+vb/J9bvmPH5gpBQcJfgBik964ypwB7ALN4xTyHqxlnflt1YSpS57Rx7mrsMRq1ss50BzamiQwYcR80yzkL8+NLxuSbnbxiF9QkCXul+sDmn+RCV4Ug2yaBsgcsAvLJLhbTuzuhMfZo9AMxBoHd4eKgB9mk1gRGA3ylTZiNgHw7DXW1vgTxoldyZPWlnfURCTtAMG+SIQAPmMcfWtDP7B82QviqrR7rYWisZsBliK1ZtcOydya4zSYldguwW9vi+PzyraOvrESQRzTfdqqGZOoTwb0aypRmn01xIP59oawLFn36fHXIJfNjtkBr66CRA7dkIwyOxZXQUUKgyd3BlSUTILX+LJhzvnLTJ291o9mL2BJ77cl7E16K+AxsK47hgid+FUjErUtCo7S6sLaRUGEA/56koUQcn76yyrVwajfNVJBbsL96o0/wZWWkpGUQaz7rJxoNoh9KSgXUpDx1FlYkhRu7tTvLKAAsfeeZzHGsM5P8J85tLuqLxUI394m3l9qE902EIw9j+lWa57rk+CI3zFQjIq1hEKvknGpPWQz2vCXjmu8tuTkP5xbR5gWQNCBLFmp3P5XRnrkh0pr+WLKXYM45S6j247YGPT+z3FHf9DbrYPC2FMGgDn0FXaMi/JPMUclw9kGX/fpIZada5yCV0YSc13lGO9acEjOg/yIh39JWIiyuCF/UZICAZfu4rDbzZhrutuCsqC2bhAkRPwWjLgXtJnTm5BEktEbuNCYqqxnSsSefmOmHdXIVtNIiVgqVKV2NA6kUxs/iqlHdzjUYPlHpbrARXN6hj3j9Y06sw2Xcp7VF+fDj+eNK+KNfgz+Nu67GmOPacZZ+bJudhReSI7B/06ZknA1fKgZArm3smh5H3UXer2ids8/DGi8otqugWKNjMDED1QfFGvbaToBAWIWQtP743uvCycXaxPv0TOGANh+MA9ML9R8gUvK4TrEtTJFrkCi0SqwkSNSGkKCPTTF5CA32VXwJyNDWbtsOdsA8/WWWzP2JNxl/dxtEJgieUlUa+VEO1k34eEI2HpvsX+Nz8WD5oeEGAA3gpFLMcP7kPf+ZbAuuxfynOmsuCj8nFntDbACZ1IHA2ZfgNi+8fJj6tHDDVX/CJusE6Wq8UuvRNYpEgPolqu+XPgBZL8ZNh1ucGcFQ9I5rvV1jbxno3VahCh7tj++IVjg+llWr1CDjxuW4hcxrbRXIiPFqxYwUMw/UVwYimT1Nf/BjV9sqmRVX67b0phdEkdNhrSgvXeRF1LSMemxS7RtrSMLldkHuSlr53cSDMViohVC6JZPMiblcP/oAhE27F/cx7NgGA+RipK0TO/DKtls1KN7Asc6MGOhGih1uwhX28PTD9s6oQWPnj4xoGT6ru9CpBtX8wQXAzvbGxBYk8pqQDl66OUN9d382GwneQI+sK3usyl94rwyZK5ISjbMIKruWNxH63ta2RRVTo2l3nXige5NMMTlUMr4hKCCa4X8YOX9WQf/imInKAMveZUaWe+V2hpEvSs4O4bVvclzNwi6OU2ciOo1CmW/zHHGUV3XOgcmHMOOxCI4ETARIU1TUFTngi1MibuDlW0x7xVfLJEqDiGUpEKy55MnYPW1BwyZkodh3waswQjFsLXRh+InHIrfwDpyKMdK3XgvwGlrxCZ65xibeUxIhUv+p5wLDg1tXjAPd/yEKVyqW+V6yGAYM1p0i33Z+bTmioAWEzEFZrnGba598f9vlo390dMdtURX83tBGJeW/dHxKpqR6juylAh1FuxT5JnJQFks8XUcam4s5z2M18qOd7LG0R4v7F+gOMixumAvjqpJQZa/YZlF09pMfHiJhUaPKrAyEI4s/f00gAAOC1uHbMDVeVNtsQFIl9/U8H3d6GiZy4mKgfzW4vGLLEQoIhTnu60za2LZWOcox0Y9kATckVDoaL+CyOUL5Ubi+ojRGdE8pDWRz6WNznrCPa3VRMsrQrnTqd3IRTkL7LFm563iBLJmtZ0Fv3EdMIGztJwO7H2efJpZO6TV8/yYwtqTQn0NlJg0Ab1AjiTxgohs1mq4n49rotIkf75hezYM7uOi+Roie68GuuUKPomraVulvpgPqaKEVk1v9enJVKtdcVDP4+wNIj72/CEhSUBYdcttVb8juVODXOVDUVIkAnvTkL/7GbFm3Q9iVdfVp8s7Ut5b7gpf/jXChQHEcLB4jlFTrDt1JN4oMDu/37lp2XJ11PoSn4M18JDyOKe8T77hKoFMcIphK6vtkZFbK+9vYnjDuD/PkKJkB1K6zmyj/DbeXw1tWIa05+raWdxXIxeJ9FktkHhX/i0wI1vhMpTI+F0yUCE2SONsAkPF7m3KZknSBITNMWmQ/Hh+WVo8D+v4m7XwBeGlqozV6E7Jsk9n7NmMGDGULAnNmWC+IsVAIrbN1RIvWbOUMCe3WysOM1x0bTu0UdolwGpwMV/zKAvjxF6HTXmiEkxq3dARYRucJBwXmoiSuyIU5dIK8IjiTT3s3LbY/axoBT9LjjQg7AJKAtDBskiMs74wBZm1cvzM0m3947MCJl5Q6pTTtI/hsRlvOElJme8W9wGI2kTWk/XqBGKZvEVxe0y1HPIQJBwcu79HgT5gU9DKJtwNjr03vHPi5KZEXGPzSuaOyj3kIgejukerEtkr5rvGWIYBp1k6yP7aHOJ4JzlTiP7qLWXLJNQr/yRaujYPIPz/6Chukao4gXVSuWjTJsfMHnq/tBhraQIqvZsK880CXoPdP++JomAG1m4u0e7BBYAK5gGYFioa1uZE54QKDQsH4pWeKqaHABHzKdm0wON1CBz0EBWr8piw7NTf6oJq019+ufHd0CBZj6ePAohev4wDuA5fLUfN9yuFhrsPw8RYWggUoOCokT8zHy4LErjSeTSHbBECnZ86ZWonTIpN+s5JiKcob8HRugv+HelGRCDcTsGtKnDnQaIp7krvVebYq108rE2scMnPrerhw3PEh9MQC1Ei797G32mh73DgOR3B67pl1/l8aa06whWnm9ATEOWNlkVIhaQdbrpTv2R4lIWGiFYLd5SN1ERb+AMgv1vITglnfVlMzm04q4N3YN28saTKSUufFi6Z3y6jA7CvgQmlEC11OHCwc8LvZSGdBnJOmUQaZTMT6iURIxABIdH1g+ZFcSoUIJYnBbb7dW9ER2pq1pl4qVgoTkbGv6iyTX4SbH4syhrL1zx3AuC2kO+eVljSW5/o8IxICbFMacIinyDYREJZJ8MA14wnhpSrt6TRl10wxbkUhvyn9FG0eXlYyUJEqph1ISJS40sSr4YgWzHiQfTIxex3b+uZT61/cLtgKV2MrRpjCwyoPgGNegJmD0Pb5/XIcilLcjMzkwg2xFBASaxQonsAkNk6aa89AbiHKbRBTV9X5gdimna1ow6yFsvjdSSY7HX5dSVqZc99qkYcVpFDa75EhAPNMaTg0Wb9VeKL5ARQ6EvutGrShXEM1PWMfKf2lPr2uoau8JTC0x5SI3llRFJqMsQQJ8RLFvSpnMJM03JVP8vBeazpI9HlJxs2c44jIIiFLiLupX48onrdwE7QJaelRLElcvG0z34O47un4aHczUM2oxvASuVhuIZBUxdppb8WvFXs1YqzMXvCwPo3OxZ0rgfdbzpcTVYjqFVkJUVNLvdWCMfaiBCtFAFiL3GNKHdOYQXLOv6RsWWszlsC3sWIQXExgJLyfgy7CtG1u1S5Vs6wJVPhtIU4xptsdY8qithTsYVSKdUd2FV4KKY4XSbl5E9jQRLyKoBGSro0hEaDdUkN8o4gn07eR2usbFp5zIk3Ow18VawxzMsPI2oB3PUcPjXNHreoz0byu9/sFuPGXmF7ct1edcx5X3jAP2hTfiq394ZL3T8LWy+ltq1eHjVEFQEnO8FfhyDyhXFC39IN9jwi/NJWak98p5x2gva23m9L114VarQ7dvQrzYtPzDwIO8O6LfM8Pyhwifc7rc7zzNYx3SUxJGQfYr4vG6o9qV332TcdKo0ZK44wt4VjpVCZbTLYNKhBIj+/zMPwoEu/GpBFbyhKbV3C9MiuVRsjCvBS5Qp+xbmBG1rmhhFQhCsXnw78YtQfYrs39PMi05Zulix5mebVP+GQnp6RD2I0hThapGsiTnqPaSTcpVzJ+14XnH9HkzkKOZKl59LGVa+iAGb3LSNcXkpCko7pZyuJDizxyfZ9C1h2dMODwhoi662CoA88t03uqZ2kEAKRHWMJbQsMFOvvLE+/Mo2QRekbCth3exNkSfjw5Q6D6HwZMJfFb1cMbb2yGdrrTgbUjF2wq2fhwXRQOOe7SYNgrtMP/Kk+67smLlJJXTZD2zjENuJmpnsh6O4Y39IviPnAa53brs/PpMUrlAWmdrPUe6IU6cUhYe1KHcjTvv43u0fPnG9U506+gi1X+RGoS9gd9jjJ50+XEXbKWYw2zibqk4SVlZe8/lp2bHdJ5PcFTZPkDTFqEK8b/QE0f54It4+hjpTIobHLsfJVPeFR2YISflZyEpL75bgNTC5Lb+/ARBV3sFX0kjdh9iL858IYmHL+2Ly7tFushOLJpWX41DKjVZr9XHtmJOEYNTPapsZyPJOnT6Ycos6LQMyPoTd7CW+SJ+ejI6ODWQMytUOb3uSO3hL8zj3/uVrp/9kX2lwAxykxotv41vr6AE03EdvBMPQ4bzZu+BG4guAL+ZkCV4rBBdoTW2D20kh/si8P7B1hGaPb/GpMqnA7bvHX9rDbJJ6tMiiQL01Ho9dHG1SPdPB0ZSbAveah/xrEvsb60TIk6ym1qINI59ykVuvnp1Kns3mFErGjc8EOfxs3OacHYLtF7kte0iaWfCCm09t2g27xT2gTarLGrqh9DDbZHiPqNelOBwdUkqkei5VQPCVS3hVkDbm1A2xRLSTR7RjR4FyhBBwadZBmNku0oP+XY/pP1rZeHExOEIQ1MIvX33n8AxWdWra11AG7ViDGtqJAbONQSmrP73emm8sPYQQa5uz132gVkrzuBFmKXLytKAz3TJlLuQYloe+J5YXXiBNDCULIDSgtZlUbVohhO9o/6kF4CIknFR9bA1YwvF8aYEAHJgpiMgUHz5cWBYBO54bIYG5+z/VKQ7vfbxcRvFIX6SavX0SNDG94UO+Ye09bTM3lBKyuNNpD1tjjqcEA+PfCMGavcRc4SJFWyAjtxWwgA8tc5JAb5v51XOwRaqempUeaPux0L6gjM0F+X32KPAzoQ+y44wDljQSL95z7r/trb83miB610JlrhzpNf5FVVREZPUKxeFUV/8Gz6uSn41klqFaUAUvdGzozD6IzcDP6DcTt8syC8IouBR9fe810Zvaa0ZcvLLdnYonS4g+gCD7Y3eoth/aRIR6ksvLYwEzKkDC1+ekdSKep8ECjbTUiiAzJz129taCMY4092cJX+fNzoHsw2HFVKZ5UmX2rnBlGrATPHrPeJSOo7gdxFJYJyvMI8/108iFQXOM6uTeskhU71Ro1rXozPMESt6/6/tn75W/Txg0hRzxsRFq79DlvKuqTnHvaYZzd5oNm/OPK5HON1OGa6XwfJSQAYENdU+vIemAG8WYDqH3iQxWa0/ZhLXD7fQ+BPUHLechuFZ68j5RLoNYNjHX9FtMFqxFRf2Ws80sSPD8XXbhqLkqlCD6dLq9ICvRFxTvo0+wBtUvSX5xqXchc6S7ss2FeTgCIersCsNxBFZGTr2q0ECJSp3qD4fK+qhIMkO7VP99McSykzHUPJIOGsl/hUe4Uzm+kseVVe1r5bSSynXtrX+L9qfkkSDrzY7/578c1bUNTXFZuyXj2wa2zWqPWc95fRHB+HB8qAhxbkMxC2Eu5+Q/l+8iDWRRq91vtcr/wIJmjSva1HrUr5otWyIrKcovnkoVjLK/D0Zkqyob84YJTU1djFh3di8NoFNCB/C3ITL+zPiuG6lmwkl47l9aLyzLm787NARSxdxkun+r8ZqnuL95rgQrCBy1AvA4lSTQ9DjH1py5hmkMoe6cfCJr1xEmC9PrvVXDcCOfadvgky9jMdCmtLdGMGxKNzXlknY1wi9kJgVXWsHdfRGGzLw4qoC2HRm33Z6Dy0KbR4YosWfnG5YG43hDcd0KuvYM9bVkO19hBrP9I7XX97YstzUM1u9V1SRlIuDxnV9Q2eqef/6QsmC7rvpmSslW4Tt0KOEYQtii02/MUW8WfNJd/jQCIBpGOujmBc+2ym2lU0ZowofSeh895WhrZ5ZOMulN/Ki02P4S0GzWw7gvJxQxEbQemE6hhWjg8cgJuoTNZOZSFPtc6EATcge3BQlUB3+qY1ZQLA5sGwwrrhhCDqrsq2TB4D2YvRPBQ68c1JWGDBquJbQ765f0C+Mr7YRdxZJRhqYfTPOpq7ZLZe0D7px+YACNp+7y+6vIApFEPEhsTM5bqMqkIH67geoxQKAPzDGo2iMF86z8fHHjvtSiPufGDoWm3lPr10+0B4gKGOGzDSw3FddUNouTDws0jcRpsYhviLv9r6XJei5V5bHvJi6cstz1GAH07KQITn/WOvXBe5l+mpGwVaj3vrTbIFPRFmBzAi8+1IAFWl/YCpYxOlH33A2X+QrA0Inna0+qm5ZdCoYClrN+MkSjDmXlUhnZ2GxoK6t/DpaDCaFB6cUziUvp+nU17HLbFcYNWd/rinicqpvXfVeHx0aTtqNQrJr2CZ5BNOue1FidgB5GNzj3O3y2pyEm7y8N4JIBBGi/7wK4Wj7EWQKIVZ103EobaB81t0J6Ja9mOT1IC85NH2oSeDkERWzm5JJGFH2pjwoLYbaVs9oaR+M9xxa38V75DTQNnCLvIbPG6EzRK9PCRb2A63LGb+tP1ZpzoH9+pN6LZGcsJY1EuLfOejokbGED5ZszgZGrtD75G1zxObap/gAB/UfjcTRjhT3cg/54Jk+i8C/9hXq1Y18GS6qMkBt8Tgyu1zmHqrVlx1CXGn6yZ+fkN5SKUDeHw9AiB+A39wHAmuhAWkXCfMgIp9lNolIqxRAO09jtWOz9oDZ54+QmjZSsLEWLWm5XYtDbb/IIxEmvDDnLKZjVuZ4oldz6/4QuKwH3S5jdeTBWaS/cf2cbhb6fp3UJRSf4fIimEmd64xysFRNBg0JvuuUF6mmY+MqbddpCb5BWuICLLTQUZlm0Vv+sJMQAurdmYgf4IhvvE7DuC7ogaetj3O7pd7o5RmpALRA10hJbioygD4lqUaxvk3Y0oKpp8BpNE9bKSieLLq9skqnp9YP9XkUR2yzYf27jieBZzFHGu26J+ySscjs2lFHnm2+aH/bcCQyjRAchT29CiIT3Ffcem01Pluywoz30wO74G/nG/Qc/vilLe3AA6rkBn7Ck9PSsIaNsXVmeZSm1XzY6ceIxVUcnNK3sRDQ9vpQ+4Rn1bGoaDV7G/hLYMhjqM2QAHPQ3nsIz/L5PWqlBjioaOmfSYDdPBsOpzb1AXrCPfanwHVqU7ftAf1w415/QlZafW+95b6gHKu5yYdDuX4Jd4JmMxqaI/HaJAtaTjgFSo5vDETgeb0p2a7CMvejLDSIOL4xWuc1nlxjQimb4R7rmtluOcv+eTT2DGkZwJTZVb+Mzk/e9v8TUNPPrkyJ2WU4Jm5eCaRrGRhwVho1dccz4Q7kUFpP8EvaZoJjMYwiAG5Fy6rgY6Ny9dv3NtXx0StmKGtVecDSF9He5yFjgZg21oIkLVUUOQCnUbmeF5u7JG6PlI1rGPSWITvYOxGeB5ggUydREzzwUQQXjuA6oHUyuhxQxboDFcM6c7LRkKsV8j9Nj5eJbE0L0ViB39tNbu/AWajKat34rX593946mnFeSTaPbWVt4R8UN15onbD1yhrVhon/mxhT/tkxzn8DyW6v8dhis5YRrPkj08ZETdee0H0l9z3+0+aEYfUp8io1lQqsqSuu2/7pxUGQNrPkTTy3vOxV85AybCbaxxm1VLzRmx+yUI46jyRbNh/CGkPapuNi6XQ8xJdrbCoPpumSv1/3Oi5DRRfq2OjN8jgEXVjiRC8WV0Ca5xjuVCdFOdlawOcf9KHGZFb8RwReo3DaG41vDtNgw6KIF5aYQxlA1c/QQi9yZ7RIUu/PQmoCl4ffwmRtKBs0fIls757VZPmAeOAsmlaoHylY63wIiAh+wx1aaenY+ntjnT58lyog2uJnZR9drTTwPDS3yzA8lOtU7Oz/iz31VOwEAq8XDBjraDY8V6jE4WR7nVb4Mp9C+KeFMvdFFAd6BsIiOSyJuoNLhrpIkETRv/7JA9GzEtWNFx7irNZGqlpRSUWgd4wyzhgfhsT7Gv2df2ze3Drg4tSdQeAmpuDPku0JvgkcGC7cx4ljF0ZZamQvBRu8EkVDC/EreLf7YFo+zBcY9XZSX4cjFPc319to1cj12p8jJS+/m42VkLi45wohQttO3Cx8Vt4f5ha3imU114u4gsaS6CzsG1iIMTIPDJ8YzXZbin8ZQdE7KuuyaCDMmJmO4F8eYsjzY/8oaJe6hgrx26xmn26BzmXnxOGM4ewX0lc8zwnsi/wY060Em9ZlcwsWNFzaXKCrVMWh3zKb3hwjXjIbGVj9CbLr7gqg4smdlAsx7TP2OdpJLUe9nB2zkbp3q5cYdwba7RZ9YstUPDxFGP2aoMBvjUd3XcJ6t/oHdq1pv3dirJdhRs6XUK9PLRrFz3qml9VlNlZpw5qAutSSCJKB8gBKVbyJ+AZxUTacHgUTaMsnPQFOdjsw3RR1zWvqF2wHkmmRbEhLE+twgjKhF6xh+UlhVGhAnm32m+5UVmZmPS3Ay2b0rqsuROmn974IQ82XSQzSBEpcIvhjy/3sdpM6D4qhsKcC/SUvYfAVa+DeIztSt1c9arLQ8IHqYDKoXwqikunnBXV88xXmk5WFmalpr1Hq5fAsVUbCyD1KY8kPodqc2IZmWQGMB+f1yWkqyMJ+zv7lnIZgYfrYBDVCCrBLTYthbC3mU0VGvFy1sOEvFFeqJw8w/rjoZflwQ9TKDdrqgf5PMTFyKi6OTWFQB/qUsBFaEwbp1VR2F4ZRXxFt2MdFj2adXLsDBvQcv5Bh3hwZXnAyI91QRGhQndCCCbFed5PGLAiXuOOJq6ai6HRadQ0S9X5LhuTrFy/zvJVVuByehvN5gw/VKE4vBWSTNBQL0gwitgCmW0CO8CiAeF6BApxD6oDVuvMGkmEzOdAkUhRp+mtMNr4SDyvhxKrnw+F60O3F4BhtgjUubySZ2Wj46Jf5ZUZxHo4JZaHIeNoWM7AWo+cPQMw2mUCL9E3sGipbYy0d8CWrgDh8gxHuWxZl7wSUG0GJLzupW99yMsWu2OdgFO+0eKOEwgcPJXLGereGXN3jaJ95HrjirnuDc8xrHLN/yNDm1epoNOcUlmxhOAckVbMjHxsNj1aYv2ttBbtUGZ9B+prEzaTo5OOayDlfP0JcVb9/KYf6q1AQVasSHvpnFt0m0F4qNXkhYGRs8MNXNwXJ0LJVxAfcWItuBm8ENTmrDLSXAecIDWFEJSYQBAiHuh2dCg76dbYGgcZQ8pluj2rTwHlXzlxyHBrOajJMA0HGR3m3ZtRfIqlPGhb8EK6FAHsaOMocYrlat+GKY6gzb2qOCBIDKvlsoPeuJPMzGEjpeUeohgNnzFSvsM9wCmLevPMcUZ9tecPfSfiOa7HzhTnURvz76xC10WrVYKJOWyfNbVeDjXUJyoF+Ftg+z4XSbGlYg/hd+PfTQG+kBQ5+kxygKR4Jt4XG7qSFDpVuLkJyatUUBQAEYK3QsIusMhHyGtTTGRbkPGAC9r318MhCj1O3go+bZPDdurQQLoBfP4O7QYu8cedDTaAwPJZoUe6YQcQc7oB066QZvOC9xkLh4N68aPvoOBAQwrgIurqas8hIxjPeuxmbjSklWOOjVBVbaBqYnAAfshISgUselV1rbT5LU9T08tmjUbVJs//meedpkBPzshJadZbM85V5yAgOHQjMkemmJM5UffqkhKbZXtq/Pc2n6sRrJzizzI80GgOmcSU8GjKcfTGtQNMT5hh042LMy/nU+d7dkl34ZMKq2kWm5kge+6urrFmAcfSdOfnnff6bLG08eUqeHCfcNZ9YMrn7Z2MjH0tVmond/y3HGcXq7J2HBGasZhG9jMRW59PHJFkfHJlTlC7Y3golfJRYNIK31UaDJ3+4gWI4qe/aKwwONnpPkLMb+RAcSufXxkRZOobSMgUjEzK7NX26yKRbLToy29dMjydw7PeN/OBUVHWGcgsZyS++kjvqOOeDI28g3F3e6nRv+viqx7nbWa0aL4wxla62BJmOQGFsrGEcJE1huoYm8QNrVaZ8niqPwUIcUNu/3A40r7gtTwQ6vqncO1dp5gXvkmFov1a/QCpWpLhiT5eATdQCEO+idLVernvRUyNjltoRZc7PmmVnM+Pp7wN5uHPA6PvBSb721Tp68wils7tT52Do83qXXK9IkQFxKkPXRxoos4Plkaur8MFwplAH8e7FPgLTzl8tCXlyQpA4cu9/WbcvckdsY+w0Lh634DBcvZmLwgXcKpPQIcrY2Igz4DqIXwsPoa4CM8AbmvMIdcAXMPcLfI5L8R5Ws3K9BYFAMx7OI59VDQrD9ZeIkU1SI4u9A7dmXRJhugzWIZEPl9mMoS4EwAMB2VIk453p2SWgEAl3/A/7SBwJ11M/G1qoRbOeAkpTp5F+rDvMPOb0C0JgKR2M4uWaZB2B9aRrLwTWULA7moPBaES3ULh38QIGaweMzP3A/huV/TUhpbfdbSLdZrkJtp5ewjol0BBEpaeK0DIpbWVptljDowAM2XOdcJyq2/r5JwAOFhE1i1XPEN3708BzyU90/hB0XPRhT53+8/xUglgSxtq3SsEdFqxCoPPBvQ9RuZhLDxjOT1oe/v3cgrV5zwMZpimipUlL6MQczHF+hoYTR3SGb8oDWoe4KWbTXy0nKXauV6I6TOKX9QlW3hy9H+DA3jGEkSyDFlv7DSdlPqP88xGUlMwkQZNmwwyhwf9TjMLiiDU6GgNmJ/6cP81gBOv8cA6tQCLIB6CDc2p5X15fe43UbSIT0lqqDTgZq/gZV4k2zrP4rAd8Ltrqv/NYuDS54iKm7cYa5SrOYF6OogUqRKY0lf36eD9h2O7B8YpIeyhYuNUv+Tm9TvRgV2i7k604Sr1DLxHamzTbQaZpFGKaGsVSpucU0uIF7lzR+Jw7Xe+6FAnbNRbw88JO4fFDgfWIk3d5hmcsj997GL6Fzs7y3W1p+UnV59s/WwT1TsKpwXSy36EE+H4rGh4aTd5wSPlI5pxFclmpkwxxiRrN+TyQQNtgLnXHUNQhxcu/QRGnkiLX3C6JDMcfFYZQFmarRNv9nwAYSUX73RaTYyoO2MrYoGSIWCG0C8syPJlqMqB1A7ud7EpMeKw2t59ujSlxGkw5UY9IsDKH0n0CDWZAoui7jwxXuzcudtpy/f4dPV4pqjkBCCHWBf+PZeu8BUHIbJZ5v4Edpqbr5mbVln0pTkvDEhGgjE9jgySfIIDrNZsOh6FB5hCyqE0b08HAOMJ+h/4lWYvR3vX240lc1RaMickUW99qRAoKgeKJkRNaKKr/dpjeurDg0mf7bObbipKijAzLqA2uz8VRoi9pSRFcBc5OCbao3zVl2/Qy93BnCFObEVJaHvzYHjUYnEio9NnzZGYbEgfQiND6WabLabNjuLN5q3gBGEbdDgADMscJETcwNLYYJzAKukBufUwxMk6mI71seupxTkwf0ILFp8lNtrCIwBK8WAicTve7I+L1HPnBs2clBjZMOaRprrKK64MjnderX4Tlw8DufK2XohZs4OUvJAYwht02SKQnTVajqbG89W5q1wiqELkMy+2u27e5IkRUtKGLVae3thnciwEc+A+I3NOIGLu5ZGcxWwNhYLMyi4L+EQ6ImgME8xpiYJ6EpZoGJFpPAuRmgFWOV37qCwUjW32ppE6XGP93S7novUyjQ4whrBT/yETwIgBZakbh1CHRl7pD/pPA1/DPEKWhNq+H6HG4gmd8mx/WuODCJt48D0VUdcXhDTJLhLvY5eJfRuVd/ADeKt6dkYWkOSNbasLp+Q3fTGvgFnivts4Q2zkaVCC91QyitRZMjo59I8j2E0RiXlSj7rcM6s/Ey58aK8KHxG0yI7QsnShz0VqCl5q8tg6uqHhzAGUXz+wbQl0K2EV/jDxqN8V3Q/CaHaZoYgDAbUSQdLHwXFOw5H0WqzfvFkFUCmxG08thX1kgRcoysux1JDYO6rUbBzkgm4vRgiVgvyNaalCbviWvvCLiQVbK6lgGhf06bs81PKeaz+NzAx0PQd46TZwoFS4o1G16tTo6p0y+bkK5GiCIpZRfdkVv778zt4u7izUMNomW7kTGTd3JeXyFK8+oXmFXGlUP1ZCdd1QslC+fW0xcn9WXMNLnmlep96sd7nhd6CR/2evrRr/V3P/3rtY4x9XeY/P7q22Vkzc2CeuvGPU3bwMFLugb8BDhVgM1svBdgmEIzX+blFmpcoC9zdy/3bADSxrNMoPWCuYNvK86JNwKLMZuDIoQKv+2ne7B9yjAdT4n+G4egWpKrVzJYuYKwfwZYBjL+dsERyu4ho6sqds65njlEcfCUDtPECDIAQAEewGBlhq+O4f8CmuVUcohKu3SmR4OJ0SbzrEs5/3u665NLnOx2Q+I1cQseFA8jDTIpfS6HizRXEk/cLhPikjkf69mOAA+7hof2b0uo7LNFvtvf/cEuDUeNWvdMT3+VRKRHOnMFrJJRDmlmXXOG9I/cFiBJlENk1zNOsyHEc9d3hEXWczcBFyvPYtTd4rxUlngDxUETrxkyJ+FpgrE6DpdkUyc+nelLPQWCTAQ309JptLE+PHw+CGmReKZ2/OI285ya6bCqseGriI/OfDUFAnJxVgPu7ba4dPa3MtyCDIVaZ81fznY0xbDOCvx1GGekp8EkoGU5Q01umJpD1I2PY7C0DqdWUXhwIdpQNbHrCN13g+IvK+Wz/4CoVXAxF/ZKqwblRqrwSGmi039Nw1PVwk7743naMQw+b2vIL+L5TCSM7C9W9kyefzXLNQafZkWO2VUcAvg1Onb7qdE9XLxe14cKPupzsK7rCpTYw4INH09ic+T1Rgsa9olyv7IyW67rIx9lmtXbxQMYMPO9Wk0tfhlMjtcJcWmQaiFGco2UI9ETHm7qmEEdth3iaDv/wRCLeolcY/f7h8MvAcQAtaU5SU1/o23VEOK7H4mBXorbkuNTKJUWOYdhR0fX4yIS6TGlnvdrfIKRogeEhrx2fxeyAlP3/BZ2RH3WAjWTTwXcEVXnYbD2XG8uxA7GAohNFkCk0QcgUysXfaj8u/hjgg3AO+WJ7l59xo9YBgd9agsOikt+34clHi7vBC0eiLeKTX2ZqrYM98CXBq45WRM3LL6AHZ3mIyhdPYpkBkR0vYCOcaYlTNNl619lc5f6+bjQkH8AkApc6J78X2qGt8zaBZdy8dHfEW59g1wt75DqOM9j6BIbfM5S0tYTTd2PbFSJBTcHBOr4a/PbAmqXLmUZAo0VYRR47A8UErLfBl9BbHnQjhzjzs9g3ubhpbq9nNgj8X9lpz3jCxwUmV9YFS+x9aKr7YDqVnIL+XC6QR5A9rJh+nNtOfyHRS0zBM2f8Lg0Ebq3q3YW9PSDBTi5mIAcCLhnXYIrhoVD9a5634HjFKCjlLVz2QENTSKjLSKO0dNFelQk1ZGY1PuRnzDB91NBpR+kKbug6vE1nhcV4U46gqp3RKtGJid5wWgT1+Pr1t6O0BqKdWIjFsOTlR2Fk49cD8xg69jevqAFaOoY2fpoA+jiE+Rci/XM6IUP0xqTEi+HCPRKemDBCYA4huUmuReyF/lzr+v7qEKPSiWNq9MGY8XobD8rkhPQr/S0cyTVBpbfDaRhWnhoCocTbq/noZuJoRdDr9Fd45fSyV3NZOld1n+Ri5zjO0KDbfkuPTsMlKNJixV9iVkv+rvxPK38Z3dJV6ZgwNYneBq19uCmxIKETi2HKvDTAKeHCk3of8rds/b7exkPrcHRTML8NbipxtBd3ipswmyijYLBQjqRSfe1/w1DwnLV/Ts4v82d+VlDmHapcj1/z8ILI9fQyDZHDVtPAhIm6gtaadQbSVXErudf0yBVBB91VAHNnFeeau9RmkWNxD+YpkYt5aiQZAwSl03mK5k3wYI/H2K2ul3m3N+V0lFe7J/VD/6gn3b74NYBiWicMeYxCZDOSdINCVS0SiwFNFphQy85WVqm/j5rcnRWRd04CpD+idfmHN3zTaH0b0AdhuqKM78yWcbxs/OHSEw/gg+/tmLuTuCZLgrAIZs4RjfbgTmIVxqyjkBQZ+DTS1BLgxLOnFtRlM7GzD48D4DCV2ELJMoV17qRaXG50kHXe7/rAv/eORLupzl34g6MA1sSFXXp2wD7AFaBzO6UHiPgwQd1/JISNdL0B6xHLpfCjaPLLI/o8M8l8E9fBq5stFnmDx05joxfpXgOLT+4Cxe2yuWFLbthibkU6x2Ittkll8vmmH6q4BiktSi6kDq37KlqdQV5RFURJVg+ocLaQcURocTKoBPH0TOR97sEJntTgAr0rdcBeHvFytYgvB1QeZTeAnIBytcCDu/MTt2ZzHpcGd9oaCJM7kVplxeVjdv0VwTwgveSLBenWKbPBhpTbIbjLfExyr0fy/echETfSpdROmf2md/wpZsKYeDOKJkVcY7Z/PTWIxTCDSfIF+cNcrpV0Ckqy81xD+kjPdJiUASBBwGkTmSLsEjRJyDSZ4BPBHOyIz9B3HJJx3ZE8m4F1klrw2EJG+4QeuRMh80bOeKuQ7Li2Z5Y1FECsTVN2lZS2/wN/w/mnbM5fwiPYIaXhhQZsPaa5Zc4iz0X2maCe77qKna9tW2qZICvPQhV9O9JSDhZeHfdnWVZXhjW45Ak0D58Kc/GUywpv3d11+XZgmKfRKMARhwdpVDdRnFjWt86yFbjZgSJod3dst8yY6/vIb58dm1vxlINQkOBzoAhPcHJvzty0kF673eFTFtzW6ScvqWH9Kqc5ZFd4kHaAj6zqVXQyNJiQaJ4TyR4YjqgKz1ZgkjQjZshyy7dkdjyaVvyXIb4mreXSGkQN2wMHGk6e+YfJQWc9N4lA9XcK9ceGMjIYCSWA3BfPZxZPZ5qiMXwys8xzFdoOScFXTEYo6rQBUHDB59pyfQ90NJOYw7XA6Qsj6N/dNvzuqXll92UcnTm7kAYHdGRbbIg7wo8v3pN8t6iK7U6vF30yOyxsv3Oa7Amz7EOFKdwMCaR1ic7txqHWElIjyL6+SPOdrnUx4Ga60brDEo1o6u+eqIwbIJJy1Mg/jTxWUFbGOzteMa8UtMszNaR9xybycpNHhKh+ZyaFDia38JofrJSF2nwqjM3r1fJNkHlgNcespgP3scJsnNStpObtX7Yg0N+L7baK2L39mp3EEKUU750dL+wPpe9XY2wi5e3X0Sg5WASdMaKcRmb8WuCRrDas6OHqngHJovfFO6WaJCj/05UnnMBz+ctBxmZLspGnuNJyDB4vYKHp5GDoQr6UIZl6h0sDpbjL34UvASLRFkUywKSGqn8oaR22HRYmSlh94vPesqdiP1Sl4FFsC6nWT7h35ZZlIQsq2bQqt6cveAGA8jxX+OLv7cBNXkjU7BqC1eJh8mjlLRLDf3cs1W7W/zXfa+2CSYh0LURurIy0/WB02J+fPhtxnVGmktvmut8bfMTf9+QTmjBx7fW3pi8oOlMMqCVA/E1Fbi12kIQLF7iJVls6BUFbnFNwiit6uIJUVvF07TMMl/tubPfIgut0fbXChmj7BwlOyjiPhs+MtV2e+0wkbUHRfgMaHjocIADwv4H9lKNpezUaZdO0O55o4Gh0/jzr1GioCtzxBrXO3Lujm1HwzB70l4u/n+DWb+6MGNPO/fIXQugIOGxKw7EYTWvOk87w9WqYg8hSO0XnvhVW0+X24aPLtWQG5i0UKKZncVruJH0FtelwNwA7wqJMOQNZIU7NHZ8+FfWXoXIzyn8t84h4lx89+oWl83rY+rAl+LC22nyp2I7acXP1pJZPxK87ZW2Zf7Gb1j3FTDZ1Qc4lO28Z6ac/z2o0N0FxN0SJV3mcRi6Y+bXyJzQbeAOFh2zR1LYkH/yaCv79vP+F9Abdf4uwPA3yssQIKIKmpJ/qiejLfOHTwaaXk70dlCI2ZaNh57/CVJtAHKViZSQ37O7WHYgTW5vX8TkjGZ5DCtaWguJxnN1yMu218MXrP0o16CGdJ3Cwcr+UMjMxzvgvgwwQ/nur9UCPBTWFL5JCDXFMzE+Az9HCwgFdOvFCkk22aw39jy/gnmXaX1QOIpOHKlOXA/sc26LsB3WOwWKvlNgUUIKMeJgwNOf6HcT7atrOXm/KLu0+hJy3FRUoZiiIKOOXPK+h2HuMJy1yErowM1IsoWZyGl7WU6+I0bvaXOOIA4l0v5JgBOXSYwYWKixYwHavWe2nGmplSlJYNf6RA51WQTl49xng69dM9qJ9Y0evYpFXpA/gZwOByyZux+YHnM/8MRbkEC0A3/ymjGH78cvqp27DTgEgGZyq96nJw1KVAkX1zQYjR/A3QzFGF9PWy5wzuvq4hUM/oN1TRobc4bkN+nVEsMRvwhQXfAyWxtEaXZkN1GNU3JrqecON3nJVtPn88LO0iIfTv/PKTEPiT2jnzDknE20RWbddsQEhRfnbdBzRAclbIDcN90Npb6dU2Hvt3mjNtxbcQlqdRnzW/a3sY/s/QWbeqEiZX65poqubbHvZebO1+1ifihABUX/BYGtZJaswGjDzaw40ZKZMYSyscICmEZrCeAmRnzylf4uyRyVoOpFMt922VztKuRXHKq6ScVzyKGUlLjCtUu/7gjDQFP68nHZE00G/edZbNfmBsdGa93KayAvZe4vNcrOxA/byqW88dExmT0c4JYK9+7blblf6LuWZsDl79f/jo+P6jRgvIaT5G0lxVpivoB3yl//mujiP0QW2nWqCqi4ji3KWqcllL2nqTXlsU7TsGSUhYqtV8PqldgvhaeTqkHdb6QowlG9Ht0jaGmfU5EPTb/4ltBPBIIGgQ0VuRwT1oygK0Xf2baB7Vw7a7qzukWmXIbwwFn9xjb6Hm2EhYHt02zVXxGB1qrXpQ4mw3JvUtYntTBYw8F3JsRnus1wiSpri/nTGZzVZg000flv6+kiEFXwgyGT30W3d31S8JKvHcew=,iv:ACOr2a5gdwulDpVKqImXdn6X3LQX0kOrmPPZ265uilE=,tag:5yEzqEX+LSAh3T8KpiaG0A==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age12qdlu87t3sh0m02eh5n3kx75d98h2evgme4uue2ucl4e4acg8ffszzlkss", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxeU5QZ3BnZHJJRkw1d3hu\nNnpQQU1uMXdHaks3YWtLNUdGZDBDZzlGeGpVCnBCNTFkODFQVlJ5VkxGNzdBbkE4\nTUlmckF6MG5zN2FOcmxycTZ1MEJzeVUKLS0tIElUZzVrbDhJa3QzMDhTbmswYlpI\nQ3JuY0hUajNPYkVGTStMWDVWVU9FbUEK/GUAlX5L/OFEv0dcl8wIiMkxBI6HFL3L\nxHcWP6jFrB9apgc+BwLOyXQS/Taf6iR2v7cU0ANEki+Qlwf/AIbS3g==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age16xvvc22xm35xzgc2yx6cpcz6wnww8tf6rwfmrag4vnem7nq6h9pqr33epg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnN1Q0dEM2cHREZnhSWTNz\nZHZsNzNsTFdHbVNzdTlOZ0hoUUlHWWYyUFNNClRkTU9IZ1JVaklESmVmSjJTbU5a\nUVdySmx6Ry8yM3pxZmQ2bkhIVUdURk0KLS0tIGJtbDFMY2FkQVY0ME1VSGtaR081\naE1XU0didFZzTVRpeUNqU3JkaXhXOEEKYt8ThHmRvLIg4nGNA02kT1YPGAs12tJ0\nY3i7gjbbTqKDJVdMXSGH22qFZJZ7oNN0AGk0TbyS8y2s9bW3SSElHQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1przhvgd5gy3kvcmlmsu47qmauhdwzzez7z89xyv623em72e9mfzskefwcl", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4dkt4NDd1K1dkQS9aemVw\ndkZJMCtuR25QYUg3ZlBMdTNEV3dxZmwyMGljCm53OU1XcHZVYVliMDhudG16T0ZR\nNCtHNERJNVZqYWppT2pobDJRaGwxTHcKLS0tIFZwNm9Ua0VlbmRsaVV3NzJEcEpG\nUjlNWGFXM0l4MDBtRDFZUVFyVTl5QTAKHpVyZfnOMsd50A25TUYrLdXOztenTiU7\nNcJBkgWsRDQnUC0bZDvlDQGAxTf/FIr/jir9Dobpmgu+DpvwSO8TZA==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1c0g6s6daxy79dlm9uqczwlkh0hvjpghw5h8zzljc3vs275rvvqus30hv9l", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6SS9zdThienZSamt0aXBK\nMzV4czZ4OS9CNThpTE9lV2MrNEVyQVRKMEUwCjFBRVkwUVZ0NDJJZ0YwYURtYitN\nZFhpNXdGOEZsYmloYW42T2d4YjZBNDAKLS0tIHF4Y2s2UlcvZm10MHBQTW9sdmt1\ndzk2aVZxTXlhMjZ2OWlESE5UeE44Y1EKRNyZzY/xEUn5U2XDrNzHxZfiD9/YEPX/\nRA8QvFe6mrys5hDPF+MCFq6UtWHrKsQ1qn0bq1mlgZtaUbA7FMZ3hg==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1fdlfm8xh97fwpf8fls9245wre9aktg6dzhhrr02s028kz4g38ajss2guwx", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPZ0dyVXBkVXZkaXU2TUl0\nUUEyczgveklKL0tpYlZiYmthV25YRnpLcFNvCkN6NHU4SWxUcDdkZjI5dEhGZGxi\nSEt1TE1iSzJjdElnMnJ2SUwvZmZjUTgKLS0tIGVhREdHVk5kYkxyT2ZXWXhCc3l1\ncWhKY29SSHZpc0YvSEJ5YThmVGNHNWMKpJQxboVoWUnGaS2DlIPOWjPkmaUSD/RK\nJ/qsEQqf/LXmEhevsgt62/F+eoxxfyqkU13GiqRqDZPkfJXnJg6RWQ==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2023-09-05T18:31:18Z", + "mac": "ENC[AES256_GCM,data:conLVyrNV8zqe645UTGXPpg/15cWUrD1pNp+fPg20robx6gcGI1xnDRusYuLKAYcTP5YASj72Z9FVCzAj6mJj1guus5Ch4rrVCan3r/sklSGxBRWskZXJ8Fpe0kCfT94xTbvf0l/DjW29BSYAJyI6DNLgRd7mQBGRxICaYx8Zbs=,iv:Tm6FQ5X+NsIgb17TjwjxfsaeZHCJ/fuNsZv8znEg/jA=,tag:CGDPTTbht1u6Cuk9FHdbmQ==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.7.3" + } +} \ No newline at end of file diff --git a/tests/rosenpass/server/sops.yaml b/tests/rosenpass/server/sops.yaml new file mode 100644 index 00000000..0b703d40 --- /dev/null +++ b/tests/rosenpass/server/sops.yaml @@ -0,0 +1,58 @@ +wireguard: + wgsk: ENC[AES256_GCM,data:lv9G2+XPZx4XN6MHan1qaIFmGLNPu0mYBKwHSiHGJrKdiLImJ8TlbphBVe8=,iv:4aG6LJMFAhm3KjaIE1cSvNcz+YUQN0fOu4ZcfxZFWjc=,tag:8EubhheOwusyARzC/1sTFw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age12qdlu87t3sh0m02eh5n3kx75d98h2evgme4uue2ucl4e4acg8ffszzlkss + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6Z2hRT0RLY2czV0t6U1V5 + MXhXN1FvbmlJbG82R2RZVCs5R3Z1Z0gydnl3Cjh1QmNKYTNGL3A2a3lrS2VFNUM5 + TkNXMWVPMms4bUR2QkcvamRJVnFnblUKLS0tIGp1dTJ3Z1NRS3M3MVJjc0tVdGQx + WHE3WmROMW9PNm1yaUE5ZnpQOEdRNEUK8jMskqbhPTlqEyNCIzqTmnta2dH0tjE1 + arW+/CNg6reDB0Ag3mjjOpT1Jbcyk5db5tpK3IqYnkDpzq5ZXhJEfw== + -----END AGE ENCRYPTED FILE----- + - recipient: age16xvvc22xm35xzgc2yx6cpcz6wnww8tf6rwfmrag4vnem7nq6h9pqr33epg + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtMEM3VVVNRlpMcHEzQUo2 + bWtPMWxKREc1a21ZQkRiTFVWZ01hYmhSckZJCkoxdmdOWTg4VTIrcU94UDBHVVVm + TThBc1NWMUdpU0lxaGtENG5JcGNPRmMKLS0tIDRXUlAwSEhrOUZFTEhUN3BLc09x + cHlDTGtpUWo5b2Y1WG1ESWF6SzJxSDgKY6WcsxLnAQULgWlyPqUtrIqxKigmLYj+ + +6Cnxk7utcHG47zQ8qHg2laix3pUR9pRQtitniGTCEkhcLFL1ZwVGw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1przhvgd5gy3kvcmlmsu47qmauhdwzzez7z89xyv623em72e9mfzskefwcl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3UjRCelhRZm9nMVVCT2My + aGQ3K3ViclQ3UmQwYVNDUEtvK2dCdk5PSEEwClZicmoyZVBiRi91MUpOWUdoT0dx + VmxGMFRBdEJrQW9jU3hKVDUvN3VNWkUKLS0tIDNGd2pUS3Y2TWM5RGorNWJZVWdX + WEJ2cnFMUWRFekVVcktLYkg1STZORFkK2nZBBRpJyYVlkCP3yW23uuUYYXa2HGGF + I6o9cH3x7BW/JgT91swUToEyqGHOv0tY3rK2Rk+zcHHrun4Onu5kIg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1c0g6s6daxy79dlm9uqczwlkh0hvjpghw5h8zzljc3vs275rvvqus30hv9l + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVNjZWRTJBVXo3dFdYbHNS + L04yMVVmUXBuRTBxd3NwOEZ1azR5a2gvQVZVClRXdG4xKzZJRFllU2x0dnZpa1Mw + dW1lTUhFVkZMRTF3QkJUQ3RtZ0V0TE0KLS0tIDdkd0puRzVhTWlrSkt3YnNVTkdq + Smp1Y3VFcjJLWnBubER4R2dlS0MxUFkK+TUWiJ2GUWn+vI+wPl4yda5z2D83+aq/ + JPQbzLLDjH27RyTnWi4lknKUrPSEtXUJIsM1J5eEnzJRahYJiXv5bQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1fdlfm8xh97fwpf8fls9245wre9aktg6dzhhrr02s028kz4g38ajss2guwx + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRS3ZBeVdpVUFOWVlGdWRW + a3Jvc1h2c202RkJKSmZRWHdVZGR2VmNWNHpBCmw2K2ZFUmx4QmNOMXpNSHFLOUJ6 + V2dzQ1RJbU9QZFFPTHQxL3VQWWV0MnMKLS0tIExPVThoSWI4aVZ0WWl4bldLL2Zq + T3VNeG5SVUVnV3lTcWxLakNFTU1rSG8KqDE8j4l9toVbaDfEaFR12MqFKWlU2hgQ + jYVJEdIk88hvQGf2PpstD1T20P8CTz4hbJiALFS+WX1DnZbFEJDyVg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-09-05T18:30:04Z" + mac: ENC[AES256_GCM,data:eGrd2GEztw81Y3BiaKR9BnATyRJJbpJOWP5YVocPW1TIVkm7jnSQbEsb0QvPTxvuNvHsQDCiyEYv36wIWo48ZoqWKHkKVpCoeFY5L0AzaSelO/ya+KzeB8RmcNQL9YJzVH+496utFlZvB0I5mPRByO/GzaepAcVtWXqDkEYnZPQ=,iv:a8k3DGqK+6k5bh/S4Gp/dvwEwGH2hrZCVw6gH+VT1VE=,tag:3bhBlmhv5FGUbAaKeTdEdQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3