[Pkg-rust-maintainers] Bug#1028545: unblock: cargo/0.66.0+ds1-1

Fabian Grünbichler debian at fabian.gruenbichler.email
Thu Jan 12 15:07:05 GMT 2023


Package: release.debian.org
Severity: normal
User: release.debian.org at packages.debian.org
Usertags: unblock
X-Debbugs-Cc: cargo at packages.debian.org
Control: affects -1 + src:cargo

Please unblock package cargo, as discussed in #debian-release.

[ Reason ]
The update is the fix for CVE-2022-46176[0], including a repack of the
orig-vendor tarball for the required updated or added dependencies:

- libgit2-sys/git2/git2-curl: updated, only change between the versions
  is the added support for SSH host key verification needed for the CVE
  fix
- base64, sha1, hmac: added dependencies for known host support in cargo
- block-buffer, cpufeatures, crypto-common, digest, generic-array,
  subtle: added transitive dependencies

[ Impact ]
cargo in bookworm would remain affected by the linked CVE without this
update.

[ Tests ]
the built-in cargo testsuite passes, connecting to an unknown SSH host
was tested manually:

$ cargo init foo
$ cargo init bar --lib
$ cd foo
$ cargo add bar --git "ssh://localhost:${PWD}/../bar"

fails with the expected error message (if "localhost" is not a known
host either via SSH or cargo's configuration).

[ Risks ]
the package is a toolchain package, but the changes in cargo itself are
very limited in scope. there might be room to reduce the debdiff further
(for example, by dropping the patches adding support for hashed known
hosts), but that would entail a bigger delta from the upstream fix, as
well as reduced usability (by not being able to parse most/all entries
from .ssh/known_hosts).

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
A similar unblock request for debcargo+non-vendored dependencies
(rust-libgit2-sys, rust-git2, rust-git2-curl, rust-cargo) will be filed
once those have been uploaded. That set of packages will include an
update of rust-cargo (the library that is not part of the toolchain
packages set) from 0.63.1 to 0.66 with the CVE fix).

0: https://security-tracker.debian.org/tracker/CVE-2022-46176

unblock cargo/0.66.0+ds1-1
-------------- next part --------------
diff -Nru cargo-0.66.0/debian/changelog cargo-0.66.0+ds1/debian/changelog
--- cargo-0.66.0/debian/changelog	2023-01-08 16:38:30.000000000 +0100
+++ cargo-0.66.0+ds1/debian/changelog	2023-01-11 18:55:09.000000000 +0100
@@ -1,3 +1,12 @@
+cargo (0.66.0+ds1-1) unstable; urgency=medium
+
+  [ Fabian Gr?nbichler ]
+  * fix CVE-2022-46176 (Thanks Peter Green!)
+  * repack vendored sources with required libgit2-sys/git2/git2-curl versions
+  * update unsuspicious files
+
+ -- Fabian Gruenbichler <debian at fabian.gruenbichler.email>  Wed, 11 Jan 2023 18:55:09 +0100
+
 cargo (0.66.0-1) unstable; urgency=medium
 
   * new upstream version 0.66
diff -Nru cargo-0.66.0/debian/copyright cargo-0.66.0+ds1/debian/copyright
--- cargo-0.66.0/debian/copyright	2023-01-08 16:38:30.000000000 +0100
+++ cargo-0.66.0+ds1/debian/copyright	2023-01-11 18:55:09.000000000 +0100
@@ -120,11 +120,22 @@
  see https://github.com/bluss/either
  see https://github.com/rust-itertools/itertools
 
+Files: vendor/base64/*
+Copyright: 2015-2023 Alice Maz <alice at alicemaz.com>
+           2015-2023 Marshall Pierce <marshall at mpierce.org>
+License: MIT or Apache-2.0
+Comment: see https://github.com/marshallpierce/rust-base64
+
 Files: vendor/bitmaps/*
 Copyright: 2019-2020 Bodil Stokke <bodil at bodil.org>
 License: MPL-2.0+
 Comment: see https://github.com/bodil/bitmaps
 
+Files: vendor/block-buffer/*
+Copyright: 2016-2023 RustCrypto Developers
+License: MIT OR Apache-2.0
+Comment: see https://github.com/RustCrypto/utils
+
 Files: 
  vendor/bstr/*
  vendor/bstr-*/*
@@ -179,6 +190,11 @@
 License: MIT or Apache-2.0
 Comment: see https://github.com/servo/core-foundation-rs
 
+Files: vendor/cpufeatures/*
+Copyright: 2016-2023 RustCrypto Developers
+License: MIT OR Apache-2.0
+Comment: see https://github.com/RustCrypto/utils
+
 Files: vendor/crc32fast/*
 Copyright: 2018, Sam Rijs <srijs at airpost.net>
            2018, Alex Crichton <alex at alexcrichton.com>
@@ -189,6 +205,11 @@
 License: MIT or Apache-2.0
 Comment: see https://github.com/crossbeam-rs
 
+Files: vendor/crypto-common/*
+Copyright: 2017-2023 RustCrypto Developers
+License: MIT OR Apache-2.0
+Comment: see https://github.com/RustCrypto/traits
+
 Files: vendor/commoncrypto/*
        vendor/commoncrypto-sys/*
        vendor/crypto-hash/*
@@ -205,6 +226,11 @@
 License: MIT
 Comment: see https://github.com/alexcrichton/curl-rust
 
+Files: vendor/digest/*
+Copyright: 2017-2023 RustCrypto Developers
+License: MIT OR Apache-2.0
+Comment: see https://github.com/RustCrypto/traits
+
 Files: vendor/dunce/*
 Copyright: 2017-2021 Kornel <kornel at geekhood.net>
 License: CC0-1.0
@@ -215,6 +241,12 @@
 License: Apache-2.0 OR MIT
 Comment: see https://github.com/smol-rs/fastrand
 
+Files: vendor/generic-array/*
+Copyright: 2015-2022 Bart?omiej Kami?ski <fizyk20 at gmail.com>
+           2015-2022 Aaron Trent <novacrazy at gmail.com>
+License: MIT
+Comment: see https://github.com/fizyk20/generic-array.git
+
 Files: vendor/hashbrown/*
 Copyright: 2018-2022 Amanieu d'Antras <amanieu at gmail.com>
 License: MIT OR Apache-2.0
@@ -227,6 +259,11 @@
 License: MIT or Apache-2.0
 Comment: see https://github.com/KokaKiwi/rust-hex
 
+Files: vendor/hmac/*
+Copyright: 2017-2023 RustCrypto Developers
+License: MIT OR Apache-2.0
+Comment: see https://github.com/RustCrypto/MACs
+
 Files: vendor/home/*
 Copyright: Brian Anderson <andersb at gmail.com>
 License: MIT or Apache-2.0
@@ -402,6 +439,11 @@
 Comment: see https://github.com/serde-rs
          see https://github.com/dtolnay/serde-ignored
 
+Files: vendor/sha1/*
+Copyright: 2016-2022 RustCrypto Developers
+License: MIT OR Apache-2.0
+Comment: see https://github.com/RustCrypto/hashes
+
 Files: vendor/similar/*
 Copyright: 2021-2022 Armin Ronacher <armin.ronacher at active-4.com>
            2021-2022 Pierre-?tienne Meunier <pe at pijul.org>
@@ -430,6 +472,12 @@
 License: MIT
 Comment: see https://github.com/dguo/strsim-rs
 
+Files: vendor/subtle/*
+Copyright: 2017-2021 Isis Lovecruft <isis at patternsinthevoid.net>
+           2017-2021 Henry de Valence <hdevalence at hdevalence.ca>
+License: BSD-3-Clause
+Comment: see https://github.com/dalek-cryptography/subtle
+
 Files: vendor/syn/*
 Copyright: 2016-2017 David Tolnay <dtolnay at gmail.com>
 License: MIT or Apache-2.0
diff -Nru cargo-0.66.0/debian/make_orig_multi.sh cargo-0.66.0+ds1/debian/make_orig_multi.sh
--- cargo-0.66.0/debian/make_orig_multi.sh	2023-01-08 16:31:11.000000000 +0100
+++ cargo-0.66.0+ds1/debian/make_orig_multi.sh	2023-01-11 18:55:09.000000000 +0100
@@ -34,6 +34,14 @@
 tar -xaf "${TMPDIR}/cargo_${CARGO_VER}.orig.tar.gz" -C cargo --strip-components=1
 cd cargo
 
+# special patch for CVE fix - we want to vendor the updated/fixed dependencies!
+echo "Applying CVE-2022-46176 patches";
+for p in "${SRCDIR}/debian/patches/cve/"*.patch; do
+  echo "$(basename "$p")"
+  patch -p1 < "$p"
+  echo "$p" >> .cve-patches
+done
+
 # Download build-deps via cargo-vendor
 export GIT_AUTHOR_NAME="deb-build"
 export GIT_AUTHOR_EMAIL="<>"
@@ -55,6 +63,14 @@
 
 rm -rf vendor-scan
 
+# special patch for CVE fix - unapply to keep orig.tar.gz pristine
+echo "Unapplying CVE-2022-46176 patches";
+tac .cve-patches | while read p; do
+  echo "$(basename "$p")"
+  patch -Rp1 < "$p"
+done
+rm .cve-patches
+
 # Pack it up, reproducibly
 tar --sort=name \
     --use-compress-program='gzip -9n' \
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-01-validate-ssh-host.keys.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-01-validate-ssh-host.keys.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-01-validate-ssh-host.keys.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-01-validate-ssh-host.keys.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,586 @@
+This patch is based on the upstream commit described below, adapted for use
+in the Debian package by Peter Michael Green.
+
+commit 1387fd4105b242fa2d24ad99d10a5b1af23f293e
+Author: Eric Huss <eric at huss.org>
+Date:   Wed Dec 7 18:52:00 2022 -0800
+
+    Validate SSH host keys
+
+Index: cargo/src/cargo/sources/git/known_hosts.rs
+===================================================================
+--- /dev/null
++++ cargo/src/cargo/sources/git/known_hosts.rs
+@@ -0,0 +1,439 @@
++//! SSH host key validation support.
++//!
++//! A primary goal with this implementation is to provide user-friendly error
++//! messages, guiding them to understand the issue and how to resolve it.
++//!
++//! Note that there are a lot of limitations here. This reads OpenSSH
++//! known_hosts files from well-known locations, but it does not read OpenSSH
++//! config files. The config file can change the behavior of how OpenSSH
++//! handles known_hosts files. For example, some things we don't handle:
++//!
++//! - `GlobalKnownHostsFile` ? Changes the location of the global host file.
++//! - `UserKnownHostsFile` ? Changes the location of the user's host file.
++//! - `KnownHostsCommand` ? A command to fetch known hosts.
++//! - `CheckHostIP` ? DNS spoofing checks.
++//! - `VisualHostKey` ? Shows a visual ascii-art key.
++//! - `VerifyHostKeyDNS` ? Uses SSHFP DNS records to fetch a host key.
++//!
++//! There's also a number of things that aren't supported but could be easily
++//! added (it just adds a little complexity). For example, hashed hostnames,
++//! hostname patterns, and revoked markers. See "FIXME" comments littered in
++//! this file.
++
++use git2::cert::Cert;
++use git2::CertificateCheckStatus;
++use std::collections::HashSet;
++use std::fmt::Write;
++use std::path::{Path, PathBuf};
++
++/// These are host keys that are hard-coded in cargo to provide convenience.
++///
++/// If GitHub ever publishes new keys, the user can add them to their own
++/// configuration file to use those instead.
++///
++/// The GitHub keys are sourced from <https://api.github.com/meta> or
++/// <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints>.
++///
++/// These will be ignored if the user adds their own entries for `github.com`,
++/// which can be useful if GitHub ever revokes their old keys.
++static BUNDLED_KEYS: &[(&str, &str, &str)] = &[
++    ("github.com", "ssh-ed25519", "AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"),
++    ("github.com", "ecdsa-sha2-nistp256", "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg="),
++    ("github.com", "ssh-rsa", "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="),
++];
++
++enum KnownHostError {
++    /// Some general error happened while validating the known hosts.
++    CheckError(anyhow::Error),
++    /// The host key was not found.
++    HostKeyNotFound {
++        hostname: String,
++        key_type: git2::cert::SshHostKeyType,
++        remote_host_key: String,
++        remote_fingerprint: String,
++        other_hosts: Vec<KnownHost>,
++    },
++    /// The host key was found, but does not match the remote's key.
++    HostKeyHasChanged {
++        hostname: String,
++        key_type: git2::cert::SshHostKeyType,
++        old_known_host: KnownHost,
++        remote_host_key: String,
++        remote_fingerprint: String,
++    },
++}
++
++impl From<anyhow::Error> for KnownHostError {
++    fn from(err: anyhow::Error) -> KnownHostError {
++        KnownHostError::CheckError(err.into())
++    }
++}
++
++/// The location where a host key was located.
++#[derive(Clone)]
++enum KnownHostLocation {
++    /// Loaded from a file from disk.
++    File { path: PathBuf, lineno: u32 },
++    /// Part of the hard-coded bundled keys in Cargo.
++    Bundled,
++}
++
++/// The git2 callback used to validate a certificate (only ssh known hosts are validated).
++pub fn certificate_check(
++    cert: &Cert<'_>,
++    host: &str,
++    port: Option<u16>,
++) -> Result<CertificateCheckStatus, git2::Error> {
++    let Some(host_key) = cert.as_hostkey() else {
++        // Return passthrough for TLS X509 certificates to use whatever validation
++        // was done in git2.
++        return Ok(CertificateCheckStatus::CertificatePassthrough)
++    };
++    // If a nonstandard port is in use, check for that first.
++    // The fallback to check without a port is handled in the HostKeyNotFound handler.
++    let host_maybe_port = match port {
++        Some(port) if port != 22 => format!("[{host}]:{port}"),
++        _ => host.to_string(),
++    };
++    // The error message must be constructed as a string to pass through the libgit2 C API.
++    let err_msg = match check_ssh_known_hosts(host_key, &host_maybe_port) {
++        Ok(()) => {
++            return Ok(CertificateCheckStatus::CertificateOk);
++        }
++        Err(KnownHostError::CheckError(e)) => {
++            format!("error: failed to validate host key:\n{:#}", e)
++        }
++        Err(KnownHostError::HostKeyNotFound {
++            hostname,
++            key_type,
++            remote_host_key,
++            remote_fingerprint,
++            other_hosts,
++        }) => {
++            // Try checking without the port.
++            if port.is_some()
++                && !matches!(port, Some(22))
++                && check_ssh_known_hosts(host_key, host).is_ok()
++            {
++                return Ok(CertificateCheckStatus::CertificateOk);
++            }
++            let key_type_short_name = key_type.short_name();
++            let key_type_name = key_type.name();
++            let known_hosts_location = user_known_host_location_to_add();
++            let other_hosts_message = if other_hosts.is_empty() {
++                String::new()
++            } else {
++                let mut msg = String::from(
++                    "Note: This host key was found, \
++                    but is associated with a different host:\n",
++                );
++                for known_host in other_hosts {
++                    let loc = match known_host.location {
++                        KnownHostLocation::File { path, lineno } => {
++                            format!("{} line {lineno}", path.display())
++                        }
++                        KnownHostLocation::Bundled => format!("bundled with cargo"),
++                    };
++                    write!(msg, "    {loc}: {}\n", known_host.patterns).unwrap();
++                }
++                msg
++            };
++            format!("error: unknown SSH host key\n\
++                The SSH host key for `{hostname}` is not known and cannot be validated.\n\
++                \n\
++                To resolve this issue, add the host key to {known_hosts_location}\n\
++                \n\
++                The key to add is:\n\
++                \n\
++                {hostname} {key_type_name} {remote_host_key}\n\
++                \n\
++                The {key_type_short_name} key fingerprint is: SHA256:{remote_fingerprint}\n\
++                This fingerprint should be validated with the server administrator that it is correct.\n\
++                {other_hosts_message}\n\
++                See https://doc.rust-lang.org/nightly/cargo/appendix/git-authentication.html#ssh-known-hosts \
++                for more information.\n\
++                ")
++        }
++        Err(KnownHostError::HostKeyHasChanged {
++            hostname,
++            key_type,
++            old_known_host,
++            remote_host_key,
++            remote_fingerprint,
++        }) => {
++            let key_type_short_name = key_type.short_name();
++            let key_type_name = key_type.name();
++            let known_hosts_location = user_known_host_location_to_add();
++            let old_key_resolution = match old_known_host.location {
++                KnownHostLocation::File { path, lineno } => {
++                    let old_key_location = path.display();
++                    format!(
++                        "removing the old {key_type_name} key for `{hostname}` \
++                        located at {old_key_location} line {lineno}, \
++                        and adding the new key to {known_hosts_location}",
++                    )
++                }
++                KnownHostLocation::Bundled => {
++                    format!(
++                        "adding the new key to {known_hosts_location}\n\
++                        The current host key is bundled as part of Cargo."
++                    )
++                }
++            };
++            format!("error: SSH host key has changed for `{hostname}`\n\
++                *********************************\n\
++                * WARNING: HOST KEY HAS CHANGED *\n\
++                *********************************\n\
++                This may be caused by a man-in-the-middle attack, or the \
++                server may have changed its host key.\n\
++                \n\
++                The {key_type_short_name} fingerprint for the key from the remote host is:\n\
++                    SHA256:{remote_fingerprint}\n\
++                \n\
++                You are strongly encouraged to contact the server \
++                administrator for `{hostname}` to verify that this new key is \
++                correct.\n\
++                \n\
++                If you can verify that the server has a new key, you can \
++                resolve this error by {old_key_resolution}\n\
++                \n\
++                The key provided by the remote host is:\n\
++                \n\
++                {hostname} {key_type_name} {remote_host_key}\n\
++                \n\
++                See https://doc.rust-lang.org/nightly/cargo/appendix/git-authentication.html#ssh-known-hosts \
++                for more information.\n\
++                ")
++        }
++    };
++    Err(git2::Error::new(
++        git2::ErrorCode::GenericError,
++        git2::ErrorClass::Callback,
++        err_msg,
++    ))
++}
++
++/// Checks if the given host/host key pair is known.
++fn check_ssh_known_hosts(
++    cert_host_key: &git2::cert::CertHostkey<'_>,
++    host: &str,
++) -> Result<(), KnownHostError> {
++    let Some(remote_host_key) = cert_host_key.hostkey() else {
++        return Err(anyhow::format_err!("remote host key is not available").into());
++    };
++    let remote_key_type = cert_host_key.hostkey_type().unwrap();
++    // `changed_key` keeps track of any entries where the key has changed.
++    let mut changed_key = None;
++    // `other_hosts` keeps track of any entries that have an identical key,
++    // but a different hostname.
++    let mut other_hosts = Vec::new();
++
++    // Collect all the known host entries from disk.
++    let mut known_hosts = Vec::new();
++    for path in known_host_files() {
++        if !path.exists() {
++            continue;
++        }
++        let hosts = load_hostfile(&path)?;
++        known_hosts.extend(hosts);
++    }
++    // Load the bundled keys. Don't add keys for hosts that the user has
++    // configured, which gives them the option to override them. This could be
++    // useful if the keys are ever revoked.
++    let configured_hosts: HashSet<_> = known_hosts
++        .iter()
++        .flat_map(|known_host| {
++            known_host
++                .patterns
++                .split(',')
++                .map(|pattern| pattern.to_lowercase())
++        })
++        .collect();
++    for (patterns, key_type, key) in BUNDLED_KEYS {
++        if !configured_hosts.contains(*patterns) {
++            let key = base64::decode(key).unwrap();
++            known_hosts.push(KnownHost {
++                location: KnownHostLocation::Bundled,
++                patterns: patterns.to_string(),
++                key_type: key_type.to_string(),
++                key,
++            });
++        }
++    }
++
++    for known_host in known_hosts {
++        // The key type from libgit2 needs to match the key type from the host file.
++        if known_host.key_type != remote_key_type.name() {
++            continue;
++        }
++        let key_matches = known_host.key == remote_host_key;
++        if !known_host.host_matches(host) {
++            // `name` can be None for hashed hostnames (which libgit2 does not expose).
++            if key_matches {
++                other_hosts.push(known_host.clone());
++            }
++            continue;
++        }
++        if key_matches {
++            return Ok(());
++        }
++        // The host and key type matched, but the key itself did not.
++        // This indicates the key has changed.
++        // This is only reported as an error if no subsequent lines have a
++        // correct key.
++        changed_key = Some(known_host.clone());
++    }
++    // Older versions of OpenSSH (before 6.8, March 2015) showed MD5
++    // fingerprints (see FingerprintHash ssh config option). Here we only
++    // support SHA256.
++    let mut remote_fingerprint = cargo_util::Sha256::new();
++    remote_fingerprint.update(remote_host_key);
++    let remote_fingerprint =
++        base64::encode_config(remote_fingerprint.finish(), base64::STANDARD_NO_PAD);
++    let remote_host_key = base64::encode(remote_host_key);
++    // FIXME: Ideally the error message should include the IP address of the
++    // remote host (to help the user validate that they are connecting to the
++    // host they were expecting to). However, I don't see a way to obtain that
++    // information from libgit2.
++    match changed_key {
++        Some(old_known_host) => Err(KnownHostError::HostKeyHasChanged {
++            hostname: host.to_string(),
++            key_type: remote_key_type,
++            old_known_host,
++            remote_host_key,
++            remote_fingerprint,
++        }),
++        None => Err(KnownHostError::HostKeyNotFound {
++            hostname: host.to_string(),
++            key_type: remote_key_type,
++            remote_host_key,
++            remote_fingerprint,
++            other_hosts,
++        }),
++    }
++}
++
++/// Returns a list of files to try loading OpenSSH-formatted known hosts.
++fn known_host_files() -> Vec<PathBuf> {
++    let mut result = Vec::new();
++    if cfg!(unix) {
++        result.push(PathBuf::from("/etc/ssh/ssh_known_hosts"));
++    } else if cfg!(windows) {
++        // The msys/cygwin version of OpenSSH uses `/etc` from the posix root
++        // filesystem there (such as `C:\msys64\etc\ssh\ssh_known_hosts`).
++        // However, I do not know of a way to obtain that location from
++        // Windows-land. The ProgramData version here is what the PowerShell
++        // port of OpenSSH does.
++        if let Some(progdata) = std::env::var_os("ProgramData") {
++            let mut progdata = PathBuf::from(progdata);
++            progdata.push("ssh");
++            progdata.push("ssh_known_hosts");
++            result.push(progdata)
++        }
++    }
++    result.extend(user_known_host_location());
++    result
++}
++
++/// The location of the user's known_hosts file.
++fn user_known_host_location() -> Option<PathBuf> {
++    // NOTE: This is a potentially inaccurate prediction of what the user
++    // actually wants. The actual location depends on several factors:
++    //
++    // - Windows OpenSSH Powershell version: I believe this looks up the home
++    //   directory via ProfileImagePath in the registry, falling back to
++    //   `GetWindowsDirectoryW` if that fails.
++    // - OpenSSH Portable (under msys): This is very complicated. I got lost
++    //   after following it through some ldap/active directory stuff.
++    // - OpenSSH (most unix platforms): Uses `pw->pw_dir` from `getpwuid()`.
++    //
++    // This doesn't do anything close to that. home_dir's behavior is:
++    // - Windows: $USERPROFILE, or SHGetFolderPathW()
++    // - Unix: $HOME, or getpwuid_r()
++    //
++    // Since there is a mismatch here, the location returned here might be
++    // different than what the user's `ssh` CLI command uses. We may want to
++    // consider trying to align it better.
++    home::home_dir().map(|mut home| {
++        home.push(".ssh");
++        home.push("known_hosts");
++        home
++    })
++}
++
++/// The location to display in an error message instructing the user where to
++/// add the new key.
++fn user_known_host_location_to_add() -> String {
++    // Note that we don't bother with the legacy known_hosts2 files.
++    match user_known_host_location() {
++        Some(path) => path.to_str().expect("utf-8 home").to_string(),
++        None => "~/.ssh/known_hosts".to_string(),
++    }
++}
++
++/// A single known host entry.
++#[derive(Clone)]
++struct KnownHost {
++    location: KnownHostLocation,
++    /// The hostname. May be comma separated to match multiple hosts.
++    patterns: String,
++    key_type: String,
++    key: Vec<u8>,
++}
++
++impl KnownHost {
++    /// Returns whether or not the given host matches this known host entry.
++    fn host_matches(&self, host: &str) -> bool {
++        let mut match_found = false;
++        let host = host.to_lowercase();
++        // FIXME: support hashed hostnames
++        for pattern in self.patterns.split(',') {
++            let pattern = pattern.to_lowercase();
++            // FIXME: support * and ? wildcards
++            if let Some(pattern) = pattern.strip_prefix('!') {
++                if pattern == host {
++                    return false;
++                }
++            } else {
++                match_found = pattern == host;
++            }
++        }
++        match_found
++    }
++}
++
++/// Loads an OpenSSH known_hosts file.
++fn load_hostfile(path: &Path) -> Result<Vec<KnownHost>, anyhow::Error> {
++    let contents = cargo_util::paths::read(path)?;
++    let entries = contents
++        .lines()
++        .enumerate()
++        .filter_map(|(lineno, line)| {
++            let location = KnownHostLocation::File {
++                path: path.to_path_buf(),
++                lineno: lineno as u32 + 1,
++            };
++            parse_known_hosts_line(line, location)
++        })
++        .collect();
++    Ok(entries)
++}
++
++fn parse_known_hosts_line(line: &str, location: KnownHostLocation) -> Option<KnownHost> {
++    let line = line.trim();
++    // FIXME: @revoked and @cert-authority is currently not supported.
++    if line.is_empty() || line.starts_with('#') || line.starts_with('@') {
++        return None;
++    }
++    let mut parts = line.split([' ', '\t']).filter(|s| !s.is_empty());
++    let Some(patterns) = parts.next() else { return None };
++    let Some(key_type) = parts.next() else { return None };
++    let Some(key) = parts.next() else { return None };
++    let Ok(key) = base64::decode(key) else { return None };
++    Some(KnownHost {
++        location,
++        patterns: patterns.to_string(),
++        key_type: key_type.to_string(),
++        key,
++    })
++}
+Index: cargo/src/cargo/sources/git/mod.rs
+===================================================================
+--- cargo.orig/src/cargo/sources/git/mod.rs
++++ cargo/src/cargo/sources/git/mod.rs
+@@ -1,4 +1,5 @@
+ pub use self::source::GitSource;
+ pub use self::utils::{fetch, GitCheckout, GitDatabase, GitRemote};
++mod known_hosts;
+ mod source;
+ mod utils;
+Index: cargo/src/cargo/sources/git/utils.rs
+===================================================================
+--- cargo.orig/src/cargo/sources/git/utils.rs
++++ cargo/src/cargo/sources/git/utils.rs
+@@ -647,7 +647,6 @@ where
+             | ErrorClass::Submodule
+             | ErrorClass::FetchHead
+             | ErrorClass::Ssh
+-            | ErrorClass::Callback
+             | ErrorClass::Http => {
+                 let mut msg = "network failure seems to have happened\n".to_string();
+                 msg.push_str(
+@@ -658,6 +657,13 @@ where
+                 );
+                 err = err.context(msg);
+             }
++            ErrorClass::Callback => {
++                // This unwraps the git2 error. We're using the callback error
++                // specifically to convey errors from Rust land through the C
++                // callback interface. We don't need the `; class=Callback
++                // (26)` that gets tacked on to the git2 error message.
++                err = anyhow::format_err!("{}", e.message());
++            }
+             _ => {}
+         }
+     }
+@@ -686,12 +692,16 @@ pub fn with_fetch_options(
+     let mut progress = Progress::new("Fetch", config);
+     network::with_retry(config, || {
+         with_authentication(url, git_config, |f| {
++            let port = Url::parse(url).ok().and_then(|url| url.port());
+             let mut last_update = Instant::now();
+             let mut rcb = git2::RemoteCallbacks::new();
+             // We choose `N=10` here to make a `300ms * 10slots ~= 3000ms`
+             // sliding window for tracking the data transfer rate (in bytes/s).
+             let mut counter = MetricsCounter::<10>::new(0, last_update);
+             rcb.credentials(f);
++            rcb.certificate_check(|cert, host| {
++                super::known_hosts::certificate_check(cert, host, port)
++            });
+             rcb.transfer_progress(|stats| {
+                 let indexed_deltas = stats.indexed_deltas();
+                 let msg = if indexed_deltas > 0 {
+Index: cargo/src/doc/src/appendix/git-authentication.md
+===================================================================
+--- cargo.orig/src/doc/src/appendix/git-authentication.md
++++ cargo/src/doc/src/appendix/git-authentication.md
+@@ -58,9 +58,32 @@ on how to start `ssh-agent` and to add k
+ > used by Cargo's built-in SSH library. More advanced requirements should use
+ > [`net.git-fetch-with-cli`].
+ 
++### SSH Known Hosts
++
++When connecting to an SSH host, Cargo must verify the identity of the host
++using "known hosts", which are a list of host keys. Cargo can look for these
++known hosts in OpenSSH-style `known_hosts` files located in their standard
++locations (`.ssh/known_hosts` in your home directory, or
++`/etc/ssh/ssh_known_hosts` on Unix-like platforms or
++`%PROGRAMDATA%\ssh\ssh_known_hosts` on Windows). More information about these
++files can be found in the [sshd man page].
++
++When connecting to an SSH host before the known hosts has been configured,
++Cargo will display an error message instructing you how to add the host key.
++This also includes a "fingerprint", which is a smaller hash of the host key,
++which should be easier to visually verify. The server administrator can get
++the fingerprint by running `ssh-keygen` against the public key (for example,
++`ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub`). Well-known sites may
++publish their fingerprints on the web; for example GitHub posts theirs at
++<https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints>.
++
++Cargo comes with the host keys for [github.com](https://github.com) built-in.
++If those ever change, you can add the new keys to your known_hosts file.
++
+ [`credential.helper`]: https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage
+ [`net.git-fetch-with-cli`]: ../reference/config.md#netgit-fetch-with-cli
+ [GCM]: https://github.com/microsoft/Git-Credential-Manager-Core/
+ [PuTTY]: https://www.chiark.greenend.org.uk/~sgtatham/putty/
+ [Microsoft installation documentation]: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse
+ [key management]: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement
++[sshd man page]: https://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT
+--- rust-cargo-0.66.0.orig/Cargo.toml
++++ rust-cargo-0.66.0/Cargo.toml
+@@ -17,6 +17,7 @@ path = "src/cargo/lib.rs"
+
+ [dependencies]
+ atty = "0.2"
++base64 = "0.13"
+ bytesize = "1.0"
+ cargo-platform = { path = "crates/cargo-platform", version = "0.1.2" }
+ cargo-util = { path = "crates/cargo-util", version = "0.2.1" }
+@@ -28,8 +29,8 @@ pretty_env_logger = { version = "0.4", o
+ anyhow = "1.0"
+ filetime = "0.2.9"
+ flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] }
+-git2 = "0.15.0"
+-git2-curl = "0.16.0"
++git2 = "0.16.0"
++git2-curl = "0.17.0"
+ glob = "0.3.0"
+ hex = "0.4"
+ home = "0.5"
+@@ -41,7 +42,7 @@ jobserver = "0.1.24"
+ lazycell = "1.2.0"
+ libc = "0.2"
+ log = "0.4.6"
+-libgit2-sys = "0.14.0"
++libgit2-sys = "0.14.1"
+ memchr = "2.1.3"
+ opener = "0.5"
+ os_info = "3.5.0"
+
+--- cargo-0.66/crates/cargo-test-support/Cargo.toml.orig   2023-01-11 11:33:00.584077593 +0100
++++ cargo-0.66/crates/cargo-test-support/Cargo.toml        2023-01-11 11:33:12.564917363 +0100
+@@ -14,7 +14,7 @@ cargo-util = { path = "../cargo-util" }
+ snapbox = { version = "0.3.0", features = ["diff", "path"] }
+ filetime = "0.2"
+ flate2 = { version = "1.0", default-features = false, features = ["zlib"] }
+-git2 = "0.15.0"
++git2 = "0.16.0"
+ glob = "0.3"
+ itertools = "0.10.0"
+ lazy_static = "1.0"
+
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-02-add-support-for-deserializing-vec-value-string.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-02-add-support-for-deserializing-vec-value-string.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-02-add-support-for-deserializing-vec-value-string.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-02-add-support-for-deserializing-vec-value-string.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,157 @@
+commit 9f62f8440e9e542f27d60c75be38ac51186c6c32
+Author: Eric Huss <eric at huss.org>
+Date:   Fri Dec 9 20:03:27 2022 -0800
+
+    Add support for deserializing Vec<Value<String>> in config.
+    
+    This adds the ability to track the definition location of a string
+    in a TOML array.
+
+diff --git a/src/cargo/util/config/de.rs b/src/cargo/util/config/de.rs
+index 6fddc7e71f..1408f15b57 100644
+--- a/src/cargo/util/config/de.rs
++++ b/src/cargo/util/config/de.rs
+@@ -384,7 +384,12 @@ impl<'de> de::SeqAccess<'de> for ConfigSeqAccess {
+     {
+         match self.list_iter.next() {
+             // TODO: add `def` to error?
+-            Some((value, _def)) => seed.deserialize(value.into_deserializer()).map(Some),
++            Some((value, def)) => {
++                // This might be a String or a Value<String>.
++                // ValueDeserializer will handle figuring out which one it is.
++                let maybe_value_de = ValueDeserializer::new_with_string(value, def);
++                seed.deserialize(maybe_value_de).map(Some)
++            }
+             None => Ok(None),
+         }
+     }
+@@ -400,7 +405,17 @@ impl<'de> de::SeqAccess<'de> for ConfigSeqAccess {
+ struct ValueDeserializer<'config> {
+     hits: u32,
+     definition: Definition,
+-    de: Deserializer<'config>,
++    /// The deserializer, used to actually deserialize a Value struct.
++    /// This is `None` if deserializing a string.
++    de: Option<Deserializer<'config>>,
++    /// A string value to deserialize.
++    ///
++    /// This is used for situations where you can't address a string via a
++    /// TOML key, such as a string inside an array. The `ConfigSeqAccess`
++    /// doesn't know if the type it should deserialize to is a `String` or
++    /// `Value<String>`, so `ValueDeserializer` needs to be able to handle
++    /// both.
++    str_value: Option<String>,
+ }
+ 
+ impl<'config> ValueDeserializer<'config> {
+@@ -428,9 +443,19 @@ impl<'config> ValueDeserializer<'config> {
+         Ok(ValueDeserializer {
+             hits: 0,
+             definition,
+-            de,
++            de: Some(de),
++            str_value: None,
+         })
+     }
++
++    fn new_with_string(s: String, definition: Definition) -> ValueDeserializer<'config> {
++        ValueDeserializer {
++            hits: 0,
++            definition,
++            de: None,
++            str_value: Some(s),
++        }
++    }
+ }
+ 
+ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
+@@ -459,9 +484,14 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
+         // If this is the first time around we deserialize the `value` field
+         // which is the actual deserializer
+         if self.hits == 1 {
+-            return seed
+-                .deserialize(self.de.clone())
+-                .map_err(|e| e.with_key_context(&self.de.key, self.definition.clone()));
++            if let Some(de) = &self.de {
++                return seed
++                    .deserialize(de.clone())
++                    .map_err(|e| e.with_key_context(&de.key, self.definition.clone()));
++            } else {
++                return seed
++                    .deserialize(self.str_value.as_ref().unwrap().clone().into_deserializer());
++            }
+         }
+ 
+         // ... otherwise we're deserializing the `definition` field, so we need
+@@ -484,6 +514,71 @@ impl<'de, 'config> de::MapAccess<'de> for ValueDeserializer<'config> {
+     }
+ }
+ 
++// Deserializer is only implemented to handle deserializing a String inside a
++// sequence (like `Vec<String>` or `Vec<Value<String>>`). `Value<String>` is
++// handled by deserialize_struct, and the plain `String` is handled by all the
++// other functions here.
++impl<'de, 'config> de::Deserializer<'de> for ValueDeserializer<'config> {
++    type Error = ConfigError;
++
++    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
++    where
++        V: de::Visitor<'de>,
++    {
++        visitor.visit_str(&self.str_value.expect("string expected"))
++    }
++
++    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
++    where
++        V: de::Visitor<'de>,
++    {
++        visitor.visit_string(self.str_value.expect("string expected"))
++    }
++
++    fn deserialize_struct<V>(
++        self,
++        name: &'static str,
++        fields: &'static [&'static str],
++        visitor: V,
++    ) -> Result<V::Value, Self::Error>
++    where
++        V: de::Visitor<'de>,
++    {
++        // Match on the magical struct name/field names that are passed in to
++        // detect when we're deserializing `Value<T>`.
++        //
++        // See more comments in `value.rs` for the protocol used here.
++        if name == value::NAME && fields == value::FIELDS {
++            return visitor.visit_map(self);
++        }
++        unimplemented!("only strings and Value can be deserialized from a sequence");
++    }
++
++    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
++    where
++        V: de::Visitor<'de>,
++    {
++        visitor.visit_string(self.str_value.expect("string expected"))
++    }
++
++    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
++    where
++        V: de::Visitor<'de>,
++    {
++        visitor.visit_unit()
++    }
++
++    serde::forward_to_deserialize_any! {
++        i8 i16 i32 i64
++        u8 u16 u32 u64
++        option
++        newtype_struct seq tuple tuple_struct map enum bool
++        f32 f64 char bytes
++        byte_buf unit unit_struct
++        identifier
++    }
++}
++
+ /// A deserializer which takes two values and deserializes into a tuple of those
+ /// two values. This is similar to types like `StrDeserializer` in upstream
+ /// serde itself.
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-03-support-configuring-ssh-known-hosts.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-03-support-configuring-ssh-known-hosts.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-03-support-configuring-ssh-known-hosts.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-03-support-configuring-ssh-known-hosts.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,299 @@
+commit 026bda3fb5eddac0df111ee150706f756558a7b3
+Author: Eric Huss <eric at huss.org>
+Date:   Fri Dec 9 20:38:12 2022 -0800
+
+    Support configuring ssh known-hosts via cargo config.
+
+diff --git a/src/cargo/sources/git/known_hosts.rs b/src/cargo/sources/git/known_hosts.rs
+index 875dcf63f3..7efea43c3b 100644
+--- a/src/cargo/sources/git/known_hosts.rs
++++ b/src/cargo/sources/git/known_hosts.rs
+@@ -20,6 +20,7 @@
+ //! hostname patterns, and revoked markers. See "FIXME" comments littered in
+ //! this file.
+ 
++use crate::util::config::{Definition, Value};
+ use git2::cert::Cert;
+ use git2::CertificateCheckStatus;
+ use std::collections::HashSet;
+@@ -74,6 +75,8 @@ impl From<anyhow::Error> for KnownHostError {
+ enum KnownHostLocation {
+     /// Loaded from a file from disk.
+     File { path: PathBuf, lineno: u32 },
++    /// Loaded from cargo's config system.
++    Config { definition: Definition },
+     /// Part of the hard-coded bundled keys in Cargo.
+     Bundled,
+ }
+@@ -83,6 +86,8 @@ pub fn certificate_check(
+     cert: &Cert<'_>,
+     host: &str,
+     port: Option<u16>,
++    config_known_hosts: Option<&Vec<Value<String>>>,
++    diagnostic_home_config: &str,
+ ) -> Result<CertificateCheckStatus, git2::Error> {
+     let Some(host_key) = cert.as_hostkey() else {
+         // Return passthrough for TLS X509 certificates to use whatever validation
+@@ -96,7 +101,7 @@ pub fn certificate_check(
+         _ => host.to_string(),
+     };
+     // The error message must be constructed as a string to pass through the libgit2 C API.
+-    let err_msg = match check_ssh_known_hosts(host_key, &host_maybe_port) {
++    let err_msg = match check_ssh_known_hosts(host_key, &host_maybe_port, config_known_hosts) {
+         Ok(()) => {
+             return Ok(CertificateCheckStatus::CertificateOk);
+         }
+@@ -113,13 +118,13 @@ pub fn certificate_check(
+             // Try checking without the port.
+             if port.is_some()
+                 && !matches!(port, Some(22))
+-                && check_ssh_known_hosts(host_key, host).is_ok()
++                && check_ssh_known_hosts(host_key, host, config_known_hosts).is_ok()
+             {
+                 return Ok(CertificateCheckStatus::CertificateOk);
+             }
+             let key_type_short_name = key_type.short_name();
+             let key_type_name = key_type.name();
+-            let known_hosts_location = user_known_host_location_to_add();
++            let known_hosts_location = user_known_host_location_to_add(diagnostic_home_config);
+             let other_hosts_message = if other_hosts.is_empty() {
+                 String::new()
+             } else {
+@@ -132,6 +137,9 @@ pub fn certificate_check(
+                         KnownHostLocation::File { path, lineno } => {
+                             format!("{} line {lineno}", path.display())
+                         }
++                        KnownHostLocation::Config { definition } => {
++                            format!("config value from {definition}")
++                        }
+                         KnownHostLocation::Bundled => format!("bundled with cargo"),
+                     };
+                     write!(msg, "    {loc}: {}\n", known_host.patterns).unwrap();
+@@ -163,7 +171,7 @@ pub fn certificate_check(
+         }) => {
+             let key_type_short_name = key_type.short_name();
+             let key_type_name = key_type.name();
+-            let known_hosts_location = user_known_host_location_to_add();
++            let known_hosts_location = user_known_host_location_to_add(diagnostic_home_config);
+             let old_key_resolution = match old_known_host.location {
+                 KnownHostLocation::File { path, lineno } => {
+                     let old_key_location = path.display();
+@@ -173,6 +181,13 @@ pub fn certificate_check(
+                         and adding the new key to {known_hosts_location}",
+                     )
+                 }
++                KnownHostLocation::Config { definition } => {
++                    format!(
++                        "removing the old {key_type_name} key for `{hostname}` \
++                        loaded from Cargo's config at {definition}, \
++                        and adding the new key to {known_hosts_location}"
++                    )
++                }
+                 KnownHostLocation::Bundled => {
+                     format!(
+                         "adding the new key to {known_hosts_location}\n\
+@@ -217,6 +232,7 @@ pub fn certificate_check(
+ fn check_ssh_known_hosts(
+     cert_host_key: &git2::cert::CertHostkey<'_>,
+     host: &str,
++    config_known_hosts: Option<&Vec<Value<String>>>,
+ ) -> Result<(), KnownHostError> {
+     let Some(remote_host_key) = cert_host_key.hostkey() else {
+         return Err(anyhow::format_err!("remote host key is not available").into());
+@@ -237,6 +253,23 @@ fn check_ssh_known_hosts(
+         let hosts = load_hostfile(&path)?;
+         known_hosts.extend(hosts);
+     }
++    if let Some(config_known_hosts) = config_known_hosts {
++        // Format errors aren't an error in case the format needs to change in
++        // the future, to retain forwards compatibility.
++        for line_value in config_known_hosts {
++            let location = KnownHostLocation::Config {
++                definition: line_value.definition.clone(),
++            };
++            match parse_known_hosts_line(&line_value.val, location) {
++                Some(known_host) => known_hosts.push(known_host),
++                None => log::warn!(
++                    "failed to parse known host {} from {}",
++                    line_value.val,
++                    line_value.definition
++                ),
++            }
++        }
++    }
+     // Load the bundled keys. Don't add keys for hosts that the user has
+     // configured, which gives them the option to override them. This could be
+     // useful if the keys are ever revoked.
+@@ -363,12 +396,18 @@ fn user_known_host_location() -> Option<PathBuf> {
+ 
+ /// The location to display in an error message instructing the user where to
+ /// add the new key.
+-fn user_known_host_location_to_add() -> String {
++fn user_known_host_location_to_add(diagnostic_home_config: &str) -> String {
+     // Note that we don't bother with the legacy known_hosts2 files.
+-    match user_known_host_location() {
+-        Some(path) => path.to_str().expect("utf-8 home").to_string(),
+-        None => "~/.ssh/known_hosts".to_string(),
+-    }
++    let user = user_known_host_location();
++    let openssh_loc = match &user {
++        Some(path) => path.to_str().expect("utf-8 home"),
++        None => "~/.ssh/known_hosts",
++    };
++    format!(
++        "the `net.ssh.known-hosts` array in your Cargo configuration \
++        (such as {diagnostic_home_config}) \
++        or in your OpenSSH known_hosts file at {openssh_loc}"
++    )
+ }
+ 
+ /// A single known host entry.
+diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs
+index 831c43be6b..457c97c5bb 100644
+--- a/src/cargo/sources/git/utils.rs
++++ b/src/cargo/sources/git/utils.rs
+@@ -726,6 +726,9 @@ pub fn with_fetch_options(
+     cb: &mut dyn FnMut(git2::FetchOptions<'_>) -> CargoResult<()>,
+ ) -> CargoResult<()> {
+     let mut progress = Progress::new("Fetch", config);
++    let ssh_config = config.net_config()?.ssh.as_ref();
++    let config_known_hosts = ssh_config.and_then(|ssh| ssh.known_hosts.as_ref());
++    let diagnostic_home_config = config.diagnostic_home_config();
+     network::with_retry(config, || {
+         with_authentication(url, git_config, |f| {
+             let port = Url::parse(url).ok().and_then(|url| url.port());
+@@ -736,7 +739,13 @@ pub fn with_fetch_options(
+             let mut counter = MetricsCounter::<10>::new(0, last_update);
+             rcb.credentials(f);
+             rcb.certificate_check(|cert, host| {
+-                super::known_hosts::certificate_check(cert, host, port)
++                super::known_hosts::certificate_check(
++                    cert,
++                    host,
++                    port,
++                    config_known_hosts,
++                    &diagnostic_home_config,
++                )
+             });
+             rcb.transfer_progress(|stats| {
+                 let indexed_deltas = stats.indexed_deltas();
+diff --git a/src/cargo/util/config/mod.rs b/src/cargo/util/config/mod.rs
+index d30e094413..d9ab142c4e 100644
+--- a/src/cargo/util/config/mod.rs
++++ b/src/cargo/util/config/mod.rs
+@@ -356,6 +356,18 @@ impl Config {
+         &self.home_path
+     }
+ 
++    /// Returns a path to display to the user with the location of their home
++    /// config file (to only be used for displaying a diagnostics suggestion,
++    /// such as recommending where to add a config value).
++    pub fn diagnostic_home_config(&self) -> String {
++        let home = self.home_path.as_path_unlocked();
++        let path = match self.get_file_path(home, "config", false) {
++            Ok(Some(existing_path)) => existing_path,
++            _ => home.join("config.toml"),
++        };
++        path.to_string_lossy().to_string()
++    }
++
+     /// Gets the Cargo Git directory (`<cargo_home>/git`).
+     pub fn git_path(&self) -> Filesystem {
+         self.home_path.join("git")
+@@ -2356,6 +2368,13 @@ pub struct CargoNetConfig {
+     pub retry: Option<u32>,
+     pub offline: Option<bool>,
+     pub git_fetch_with_cli: Option<bool>,
++    pub ssh: Option<CargoSshConfig>,
++}
++
++#[derive(Debug, Deserialize)]
++#[serde(rename_all = "kebab-case")]
++pub struct CargoSshConfig {
++    pub known_hosts: Option<Vec<Value<String>>>,
+ }
+ 
+ #[derive(Debug, Deserialize)]
+diff --git a/src/doc/src/appendix/git-authentication.md b/src/doc/src/appendix/git-authentication.md
+index a7db1ac7f1..f46a6535c6 100644
+--- a/src/doc/src/appendix/git-authentication.md
++++ b/src/doc/src/appendix/git-authentication.md
+@@ -66,7 +66,8 @@ known hosts in OpenSSH-style `known_hosts` files located in their standard
+ locations (`.ssh/known_hosts` in your home directory, or
+ `/etc/ssh/ssh_known_hosts` on Unix-like platforms or
+ `%PROGRAMDATA%\ssh\ssh_known_hosts` on Windows). More information about these
+-files can be found in the [sshd man page].
++files can be found in the [sshd man page]. Alternatively, keys may be
++configured in a Cargo configuration file with [`net.ssh.known-hosts`].
+ 
+ When connecting to an SSH host before the known hosts has been configured,
+ Cargo will display an error message instructing you how to add the host key.
+@@ -78,10 +79,11 @@ publish their fingerprints on the web; for example GitHub posts theirs at
+ <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints>.
+ 
+ Cargo comes with the host keys for [github.com](https://github.com) built-in.
+-If those ever change, you can add the new keys to your known_hosts file.
++If those ever change, you can add the new keys to the config or known_hosts file.
+ 
+ [`credential.helper`]: https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage
+ [`net.git-fetch-with-cli`]: ../reference/config.md#netgit-fetch-with-cli
++[`net.ssh.known-hosts`]: ../reference/config.md#netsshknown-hosts
+ [GCM]: https://github.com/microsoft/Git-Credential-Manager-Core/
+ [PuTTY]: https://www.chiark.greenend.org.uk/~sgtatham/putty/
+ [Microsoft installation documentation]: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse
+diff --git a/src/doc/src/reference/config.md b/src/doc/src/reference/config.md
+index 1e50648797..f804ceebea 100644
+--- a/src/doc/src/reference/config.md
++++ b/src/doc/src/reference/config.md
+@@ -114,6 +114,9 @@ retry = 2                   # network retries
+ git-fetch-with-cli = true   # use the `git` executable for git operations
+ offline = true              # do not access the network
+ 
++[net.ssh]
++known-hosts = ["..."]       # known SSH host keys
++
+ [patch.<registry>]
+ # Same keys as for [patch] in Cargo.toml
+ 
+@@ -750,6 +753,41 @@ needed, and generate an error if it encounters a network error.
+ 
+ Can be overridden with the `--offline` command-line option.
+ 
++##### `net.ssh`
++
++The `[net.ssh]` table contains settings for SSH connections.
++
++##### `net.ssh.known-hosts`
++* Type: array of strings
++* Default: see description
++* Environment: not supported
++
++The `known-hosts` array contains a list of SSH host keys that should be
++accepted as valid when connecting to an SSH server (such as for SSH git
++dependencies). Each entry should be a string in a format similar to OpenSSH
++`known_hosts` files. Each string should start with one or more hostnames
++separated by commas, a space, the key type name, a space, and the
++base64-encoded key. For example:
++
++```toml
++[net.ssh]
++known-hosts = [
++    "example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFO4Q5T0UV0SQevair9PFwoxY9dl4pQl3u5phoqJH3cF"
++]
++```
++
++Cargo will attempt to load known hosts keys from common locations supported in
++OpenSSH, and will join those with any listed in a Cargo configuration file.
++If any matching entry has the correct key, the connection will be allowed.
++
++Cargo comes with the host keys for [github.com][github-keys] built-in. If
++those ever change, you can add the new keys to the config or known_hosts file.
++
++See [Git Authentication](../appendix/git-authentication.md#ssh-known-hosts)
++for more details.
++
++[github-keys]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
++
+ #### `[patch]`
+ 
+ Just as you can override dependencies using [`[patch]` in
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-04-add-some-known-hosts-tests-and-fix-comma-bug.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-04-add-some-known-hosts-tests-and-fix-comma-bug.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-04-add-some-known-hosts-tests-and-fix-comma-bug.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-04-add-some-known-hosts-tests-and-fix-comma-bug.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,244 @@
+commit 302a543ddf3b7621c2f10623862029d35fae7e3c
+Author: Eric Huss <eric at huss.org>
+Date:   Mon Dec 12 20:14:23 2022 -0800
+
+    Add some known_hosts tests.
+    
+    This also fixes a bug with the host matching when there are comma-separated hosts.
+
+diff --git a/src/cargo/sources/git/known_hosts.rs b/src/cargo/sources/git/known_hosts.rs
+index 7efea43c3b..58e64e7913 100644
+--- a/src/cargo/sources/git/known_hosts.rs
++++ b/src/cargo/sources/git/known_hosts.rs
+@@ -21,7 +21,7 @@
+ //! this file.
+ 
+ use crate::util::config::{Definition, Value};
+-use git2::cert::Cert;
++use git2::cert::{Cert, SshHostKeyType};
+ use git2::CertificateCheckStatus;
+ use std::collections::HashSet;
+ use std::fmt::Write;
+@@ -49,7 +49,7 @@ enum KnownHostError {
+     /// The host key was not found.
+     HostKeyNotFound {
+         hostname: String,
+-        key_type: git2::cert::SshHostKeyType,
++        key_type: SshHostKeyType,
+         remote_host_key: String,
+         remote_fingerprint: String,
+         other_hosts: Vec<KnownHost>,
+@@ -57,7 +57,7 @@ enum KnownHostError {
+     /// The host key was found, but does not match the remote's key.
+     HostKeyHasChanged {
+         hostname: String,
+-        key_type: git2::cert::SshHostKeyType,
++        key_type: SshHostKeyType,
+         old_known_host: KnownHost,
+         remote_host_key: String,
+         remote_fingerprint: String,
+@@ -238,11 +238,6 @@ fn check_ssh_known_hosts(
+         return Err(anyhow::format_err!("remote host key is not available").into());
+     };
+     let remote_key_type = cert_host_key.hostkey_type().unwrap();
+-    // `changed_key` keeps track of any entries where the key has changed.
+-    let mut changed_key = None;
+-    // `other_hosts` keeps track of any entries that have an identical key,
+-    // but a different hostname.
+-    let mut other_hosts = Vec::new();
+ 
+     // Collect all the known host entries from disk.
+     let mut known_hosts = Vec::new();
+@@ -293,6 +288,21 @@ fn check_ssh_known_hosts(
+             });
+         }
+     }
++    check_ssh_known_hosts_loaded(&known_hosts, host, remote_key_type, remote_host_key)
++}
++
++/// Checks a host key against a loaded set of known hosts.
++fn check_ssh_known_hosts_loaded(
++    known_hosts: &[KnownHost],
++    host: &str,
++    remote_key_type: SshHostKeyType,
++    remote_host_key: &[u8],
++) -> Result<(), KnownHostError> {
++    // `changed_key` keeps track of any entries where the key has changed.
++    let mut changed_key = None;
++    // `other_hosts` keeps track of any entries that have an identical key,
++    // but a different hostname.
++    let mut other_hosts = Vec::new();
+ 
+     for known_host in known_hosts {
+         // The key type from libgit2 needs to match the key type from the host file.
+@@ -301,7 +311,6 @@ fn check_ssh_known_hosts(
+         }
+         let key_matches = known_host.key == remote_host_key;
+         if !known_host.host_matches(host) {
+-            // `name` can be None for hashed hostnames (which libgit2 does not expose).
+             if key_matches {
+                 other_hosts.push(known_host.clone());
+             }
+@@ -434,7 +443,7 @@ impl KnownHost {
+                     return false;
+                 }
+             } else {
+-                match_found = pattern == host;
++                match_found |= pattern == host;
+             }
+         }
+         match_found
+@@ -444,6 +453,10 @@ impl KnownHost {
+ /// Loads an OpenSSH known_hosts file.
+ fn load_hostfile(path: &Path) -> Result<Vec<KnownHost>, anyhow::Error> {
+     let contents = cargo_util::paths::read(path)?;
++    Ok(load_hostfile_contents(path, &contents))
++}
++
++fn load_hostfile_contents(path: &Path, contents: &str) -> Vec<KnownHost> {
+     let entries = contents
+         .lines()
+         .enumerate()
+@@ -455,13 +468,13 @@ fn load_hostfile(path: &Path) -> Result<Vec<KnownHost>, anyhow::Error> {
+             parse_known_hosts_line(line, location)
+         })
+         .collect();
+-    Ok(entries)
++    entries
+ }
+ 
+ fn parse_known_hosts_line(line: &str, location: KnownHostLocation) -> Option<KnownHost> {
+     let line = line.trim();
+     // FIXME: @revoked and @cert-authority is currently not supported.
+-    if line.is_empty() || line.starts_with('#') || line.starts_with('@') {
++    if line.is_empty() || line.starts_with(['#', '@', '|']) {
+         return None;
+     }
+     let mut parts = line.split([' ', '\t']).filter(|s| !s.is_empty());
+@@ -476,3 +489,126 @@ fn parse_known_hosts_line(line: &str, location: KnownHostLocation) -> Option<Kno
+         key,
+     })
+ }
++
++#[cfg(test)]
++mod tests {
++    use super::*;
++
++    static COMMON_CONTENTS: &str = r#"
++        # Comments allowed at start of line
++
++        example.com,rust-lang.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5MzWIpZwpkpDjyCNiTIEVFhSA9OUUQvjFo7CgZBGCAj/cqeUIgiLsgtfmtBsfWIkAECQpM7ePP7NLZFGJcHvoyg5jXJiIX5s0eKo9IlcuTLLrMkW5MkHXE7bNklVbW1WdCfF2+y7Ao25B4L8FFRokMh0yp/H6+8xZ7PdVwL3FRPEg8ftZ5R0kuups6xiMHPRX+f/07vfJzA47YDPmXfhkn+JK8kL0JYw8iy8BtNBfRQL99d9iXJzWXnNce5NHMuKD5rOonD3aQHLDlwK+KhrFRrdaxQEM8ZWxNti0ux8yT4Dl5jJY0CrIu3Xl6+qroVgTqJGNkTbhs5DGWdFh6BLPTTH15rN4buisg7uMyLyHqx06ckborqD33gWu+Jig7O+PV6KJmL5mp1O1HXvZqkpBdTiT6GiDKG3oECCIXkUk0BSU9VG9VQcrMxxvgiHlyoXUAfYQoXv/lnxkTnm+Sr36kutsVOs7n5B43ZKAeuaxyQ11huJZpxamc0RA1HM641s= eric at host
++        Example.net ssh-dss AAAAB3NzaC1kc3MAAACBAK2Ek3jVxisXmz5UcZ7W65BAj/nDJCCVvSe0Aytndn4PH6k7sVesut5OoY6PdksZ9tEfuFjjS9HR5SJb8j1GW0GxtaSHHbf+rNc36PeU75bffzyIWwpA8uZFONt5swUAXJXcsHOoapNbUFuhHsRhB2hXxz9QGNiiwIwRJeSHixKRAAAAFQChKfxO1z9H2/757697xP5nJ/Z5dwAAAIEAoc+HIWas+4WowtB/KtAp6XE0B9oHI+55wKtdcGwwb7zHKK9scWNXwxIcMhSvyB3Oe2I7dQQlvyIWxsdZlzOkX0wdsTHjIAnBAP68MyvMv4kq3+I5GAVcFsqoLZfZvh0dlcgUq1/YNYZwKlt89tnzk8Fp4KLWmuw8Bd8IShYVa78AAACAL3qd8kNTY7CthgsQ8iWdjbkGSF/1KCeFyt8UjurInp9wvPDjqagwakbyLOzN7y3/ItTPCaGuX+RjFP0zZTf8i9bsAVyjFJiJ7vzRXcWytuFWANrpzLTn1qzPfh63iK92Aw8AVBYvEA/4bxo+XReAvhNBB/m78G6OedTeu6ZoTsI= eric at host
++        [example.net]:2222 ssh-dss AAAAB3NzaC1kc3MAAACBAJJN5kLZEpOJpXWyMT4KwYvLAj+b9ErNtglxOi86C6Kw7oZeYdDMCfD3lc3PJyX64udQcWGfO4abSESMiYdY43yFAZH279QGH5Q/B5CklVvTqYpfAUR+1r9TQxy3OVQHk7FB2wOi4xNQ3myO0vaYlBOB9il+P223aERbXx4JTWdvAAAAFQCTHWTcXxLK5Z6ZVPmfdSDyHzkF2wAAAIEAhp41/mTnM0Y0EWSyCXuETMW1QSpKGF8sqoZKp6wdzyhLXu0i32gLdXj4p24em/jObYh93hr+MwgxqWq+FHgD+D80Qg5f6vj4yEl4Uu5hqtTpCBFWUQoyEckbUkPf8uZ4/XzAne+tUSjZm09xATCmK9U2IGqZE+D+90eBkf1Svc8AAACAeKhi4EtfwenFYqKz60ZoEEhIsE1yI2jH73akHnfHpcW84w+fk3YlwjcfDfyYso+D0jZBdJeK5qIdkbUWhAX8wDjJVO0WL6r/YPr4yu/CgEyW1H59tAbujGJ4NR0JDqioulzYqNHnxpiw1RJukZnPBfSFKzRElvPOCq/NkQM/Mwk= eric at host
++        nistp256.example.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ4iYGCcJrUIfrHfzlsv8e8kaF36qpcUpe3VNAKVCZX/BDptIdlEe8u8vKNRTPgUO9jqS0+tjTcPiQd8/8I9qng= eric at host
++        nistp384.example.org ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNuGT3TqMz2rcwOt2ZqkiNqq7dvWPE66W2qPCoZsh0pQhVU3BnhKIc6nEr6+Wts0Z3jdF3QWwxbbTjbVTVhdr8fMCFhDCWiQFm9xLerYPKnu9qHvx9K87/fjc5+0pu4hLA== eric at host
++        nistp521.example.org ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAD35HH6OsK4DN75BrKipVj/GvZaUzjPNa1F8wMjUdPB1JlVcUfgzJjWSxrhmaNN3u0soiZw8WNRFINsGPCw5E7DywF1689WcIj2Ye2rcy99je15FknScTzBBD04JgIyOI50mCUaPCBoF14vFlN6BmO00cFo+yzy5N8GuQ2sx9kr21xmFQ== eric at host
++        # Revoked not yet supported.
++        @revoked * ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKtQsi+KPYispwm2rkMidQf30fG1Niy8XNkvASfePoca eric at host
++        example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAWkjI6XT2SZh3xNk5NhisA3o3sGzWR+VAKMSqHtI0aY eric at host
++        192.168.42.12 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVYJpa0yUGaNk0NXQTPWa0tHjqRpx+7hl2diReH6DtR eric at host
++        # Hash not yet supported.
++        |1|7CMSYgzdwruFLRhwowMtKx0maIE=|Tlff1GFqc3Ao+fUWxMEVG8mJiyk= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHgN3O21U4LWtP5OzjTzPnUnSDmCNDvyvlaj6Hi65JC eric at host
++        # Negation isn't terribly useful without globs.
++        neg.example.com,!neg.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOXfUnaAHTlo1Qi//rNk26OcmHikmkns1Z6WW/UuuS3K eric at host
++    "#;
++
++    #[test]
++    fn known_hosts_parse() {
++        let kh_path = Path::new("/home/abc/.known_hosts");
++        let khs = load_hostfile_contents(kh_path, COMMON_CONTENTS);
++        assert_eq!(khs.len(), 9);
++        match &khs[0].location {
++            KnownHostLocation::File { path, lineno } => {
++                assert_eq!(path, kh_path);
++                assert_eq!(*lineno, 4);
++            }
++            _ => panic!("unexpected"),
++        }
++        assert_eq!(khs[0].patterns, "example.com,rust-lang.org");
++        assert_eq!(khs[0].key_type, "ssh-rsa");
++        assert_eq!(khs[0].key.len(), 407);
++        assert_eq!(&khs[0].key[..30], b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x03\x01\x00\x01\x00\x00\x01\x81\x00\xb935\x88\xa5\x9c)");
++        match &khs[1].location {
++            KnownHostLocation::File { path, lineno } => {
++                assert_eq!(path, kh_path);
++                assert_eq!(*lineno, 5);
++            }
++            _ => panic!("unexpected"),
++        }
++        assert_eq!(khs[2].patterns, "[example.net]:2222");
++        assert_eq!(khs[3].patterns, "nistp256.example.org");
++        assert_eq!(khs[7].patterns, "192.168.42.12");
++    }
++
++    #[test]
++    fn host_matches() {
++        let kh_path = Path::new("/home/abc/.known_hosts");
++        let khs = load_hostfile_contents(kh_path, COMMON_CONTENTS);
++        assert!(khs[0].host_matches("example.com"));
++        assert!(khs[0].host_matches("rust-lang.org"));
++        assert!(khs[0].host_matches("EXAMPLE.COM"));
++        assert!(khs[1].host_matches("example.net"));
++        assert!(!khs[0].host_matches("example.net"));
++        assert!(khs[2].host_matches("[example.net]:2222"));
++        assert!(!khs[2].host_matches("example.net"));
++        assert!(!khs[8].host_matches("neg.example.com"));
++    }
++
++    #[test]
++    fn check_match() {
++        let kh_path = Path::new("/home/abc/.known_hosts");
++        let khs = load_hostfile_contents(kh_path, COMMON_CONTENTS);
++
++        assert!(check_ssh_known_hosts_loaded(
++            &khs,
++            "example.com",
++            SshHostKeyType::Rsa,
++            &khs[0].key
++        )
++        .is_ok());
++
++        match check_ssh_known_hosts_loaded(&khs, "example.com", SshHostKeyType::Dss, &khs[0].key) {
++            Err(KnownHostError::HostKeyNotFound {
++                hostname,
++                remote_fingerprint,
++                other_hosts,
++                ..
++            }) => {
++                assert_eq!(
++                    remote_fingerprint,
++                    "yn+pONDn0EcgdOCVptgB4RZd/wqmsVKrPnQMLtrvhw8"
++                );
++                assert_eq!(hostname, "example.com");
++                assert_eq!(other_hosts.len(), 0);
++            }
++            _ => panic!("unexpected"),
++        }
++
++        match check_ssh_known_hosts_loaded(
++            &khs,
++            "foo.example.com",
++            SshHostKeyType::Rsa,
++            &khs[0].key,
++        ) {
++            Err(KnownHostError::HostKeyNotFound { other_hosts, .. }) => {
++                assert_eq!(other_hosts.len(), 1);
++                assert_eq!(other_hosts[0].patterns, "example.com,rust-lang.org");
++            }
++            _ => panic!("unexpected"),
++        }
++
++        let mut modified_key = khs[0].key.clone();
++        modified_key[0] = 1;
++        match check_ssh_known_hosts_loaded(&khs, "example.com", SshHostKeyType::Rsa, &modified_key)
++        {
++            Err(KnownHostError::HostKeyHasChanged { old_known_host, .. }) => {
++                assert!(matches!(
++                    old_known_host.location,
++                    KnownHostLocation::File { lineno: 4, .. }
++                ));
++            }
++            _ => panic!("unexpected"),
++        }
++    }
++}
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-05-remove-let-else.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-05-remove-let-else.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-05-remove-let-else.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-05-remove-let-else.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,26 @@
+commit cf716fc3c2b0785013b321f08d6cf9e277f89c84
+Author: Eric Huss <eric at huss.org>
+Date:   Tue Dec 13 08:14:59 2022 -0800
+
+    Remove let-else, just use ? propagation.
+    
+    Co-authored-by: Weihang Lo <weihanglo at users.noreply.github.com>
+
+diff --git a/src/cargo/sources/git/known_hosts.rs b/src/cargo/sources/git/known_hosts.rs
+index 58e64e7913..f272195306 100644
+--- a/src/cargo/sources/git/known_hosts.rs
++++ b/src/cargo/sources/git/known_hosts.rs
+@@ -478,10 +478,9 @@ fn parse_known_hosts_line(line: &str, location: KnownHostLocation) -> Option<Kno
+         return None;
+     }
+     let mut parts = line.split([' ', '\t']).filter(|s| !s.is_empty());
+-    let Some(patterns) = parts.next() else { return None };
+-    let Some(key_type) = parts.next() else { return None };
+-    let Some(key) = parts.next() else { return None };
+-    let Ok(key) = base64::decode(key) else { return None };
++    let patterns = parts.next()?;
++    let key_type = parts.next()?;
++    let key = parts.next().map(base64::decode)?.ok()?;
+     Some(KnownHost {
+         location,
+         patterns: patterns.to_string(),
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-06-add-test-for-config-value-in-toml-array.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-06-add-test-for-config-value-in-toml-array.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-06-add-test-for-config-value-in-toml-array.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-06-add-test-for-config-value-in-toml-array.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,79 @@
+commit 018403ceaf71e205dbec64698bb864f5e094aec8
+Author: Eric Huss <eric at huss.org>
+Date:   Wed Dec 14 19:01:40 2022 -0800
+
+    Add test for config Value in TOML array.
+
+diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs
+index b1d07bb405..d1487833f7 100644
+--- a/tests/testsuite/config.rs
++++ b/tests/testsuite/config.rs
+@@ -1,7 +1,7 @@
+ //! Tests for config settings.
+ 
+ use cargo::core::{PackageIdSpec, Shell};
+-use cargo::util::config::{self, Config, SslVersionConfig, StringList};
++use cargo::util::config::{self, Config, Definition, SslVersionConfig, StringList};
+ use cargo::util::interning::InternedString;
+ use cargo::util::toml::{self, VecStringOrBool as VSOB};
+ use cargo::CargoResult;
+@@ -1508,3 +1508,59 @@ fn all_profile_options() {
+     let roundtrip_toml = toml_edit::easy::to_string(&roundtrip).unwrap();
+     compare::assert_match_exact(&profile_toml, &roundtrip_toml);
+ }
++
++#[cargo_test]
++fn value_in_array() {
++    // Value<String> in an array should work
++    let root_path = paths::root().join(".cargo/config.toml");
++    write_config_at(
++        &root_path,
++        "\
++[net.ssh]
++known-hosts = [
++    \"example.com ...\",
++    \"example.net ...\",
++]
++",
++    );
++
++    let foo_path = paths::root().join("foo/.cargo/config.toml");
++    write_config_at(
++        &foo_path,
++        "\
++[net.ssh]
++known-hosts = [
++    \"example.org ...\",
++]
++",
++    );
++
++    let config = ConfigBuilder::new()
++        .cwd("foo")
++        // environment variables don't actually work for known-hosts due to
++        // space splitting, but this is included here just to validate that
++        // they work (particularly if other Vec<Value> config vars are added
++        // in the future).
++        .env("CARGO_NET_SSH_KNOWN_HOSTS", "env-example")
++        .build();
++    let net_config = config.net_config().unwrap();
++    let kh = net_config
++        .ssh
++        .as_ref()
++        .unwrap()
++        .known_hosts
++        .as_ref()
++        .unwrap();
++    assert_eq!(kh.len(), 4);
++    assert_eq!(kh[0].val, "example.org ...");
++    assert_eq!(kh[0].definition, Definition::Path(foo_path.clone()));
++    assert_eq!(kh[1].val, "example.com ...");
++    assert_eq!(kh[1].definition, Definition::Path(root_path.clone()));
++    assert_eq!(kh[2].val, "example.net ...");
++    assert_eq!(kh[2].definition, Definition::Path(root_path.clone()));
++    assert_eq!(kh[3].val, "env-example");
++    assert_eq!(
++        kh[3].definition,
++        Definition::Environment("CARGO_NET_SSH_KNOWN_HOSTS".to_string())
++    );
++}
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-07-support-hashed-hostnames.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-07-support-hashed-hostnames.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-07-support-hashed-hostnames.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-07-support-hashed-hostnames.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,125 @@
+This patch is based on the upstream commit described below, adapted for use
+in the Debian package by Peter Michael Green.
+
+commit 67ae2dcafea5955824b1f390568a5fa109424987
+Author: Eric Huss <eric at huss.org>
+Date:   Wed Dec 28 15:52:10 2022 -0800
+
+    ssh known_hosts: support hashed hostnames
+
+Index: cargo/src/cargo/sources/git/known_hosts.rs
+===================================================================
+--- cargo.orig/src/cargo/sources/git/known_hosts.rs
++++ cargo/src/cargo/sources/git/known_hosts.rs
+@@ -16,13 +16,13 @@
+ //! - `VerifyHostKeyDNS` ? Uses SSHFP DNS records to fetch a host key.
+ //!
+ //! There's also a number of things that aren't supported but could be easily
+-//! added (it just adds a little complexity). For example, hashed hostnames,
+-//! hostname patterns, and revoked markers. See "FIXME" comments littered in
+-//! this file.
++//! added (it just adds a little complexity). For example, hostname patterns,
++//! and revoked markers. See "FIXME" comments littered in this file.
+ 
+ use crate::util::config::{Definition, Value};
+ use git2::cert::{Cert, SshHostKeyType};
+ use git2::CertificateCheckStatus;
++use hmac::Mac;
+ use std::collections::HashSet;
+ use std::fmt::Write;
+ use std::path::{Path, PathBuf};
+@@ -419,6 +419,8 @@ fn user_known_host_location_to_add(diagn
+     )
+ }
+ 
++const HASH_HOSTNAME_PREFIX: &str = "|1|";
++
+ /// A single known host entry.
+ #[derive(Clone)]
+ struct KnownHost {
+@@ -434,7 +436,9 @@ impl KnownHost {
+     fn host_matches(&self, host: &str) -> bool {
+         let mut match_found = false;
+         let host = host.to_lowercase();
+-        // FIXME: support hashed hostnames
++        if let Some(hashed) = self.patterns.strip_prefix(HASH_HOSTNAME_PREFIX) {
++            return hashed_hostname_matches(&host, hashed);
++        }
+         for pattern in self.patterns.split(',') {
+             let pattern = pattern.to_lowercase();
+             // FIXME: support * and ? wildcards
+@@ -450,6 +454,16 @@ impl KnownHost {
+     }
+ }
+ 
++fn hashed_hostname_matches(host: &str, hashed: &str) -> bool {
++    let Some((b64_salt, b64_host)) = hashed.split_once('|') else { return false; };
++    let Ok(salt) = base64::decode(b64_salt) else { return false; };
++    let Ok(hashed_host) = base64::decode(b64_host) else { return false; };
++    let Ok(mut mac) = hmac::Hmac::<sha1::Sha1>::new_from_slice(&salt) else { return false; };
++    mac.update(host.as_bytes());
++    let result = mac.finalize().into_bytes();
++    hashed_host == &result[..]
++}
++
+ /// Loads an OpenSSH known_hosts file.
+ fn load_hostfile(path: &Path) -> Result<Vec<KnownHost>, anyhow::Error> {
+     let contents = cargo_util::paths::read(path)?;
+@@ -474,7 +488,7 @@ fn load_hostfile_contents(path: &Path, c
+ fn parse_known_hosts_line(line: &str, location: KnownHostLocation) -> Option<KnownHost> {
+     let line = line.trim();
+     // FIXME: @revoked and @cert-authority is currently not supported.
+-    if line.is_empty() || line.starts_with(['#', '@', '|']) {
++    if line.is_empty() || line.starts_with(['#', '@']) {
+         return None;
+     }
+     let mut parts = line.split([' ', '\t']).filter(|s| !s.is_empty());
+@@ -506,8 +520,7 @@ mod tests {
+         @revoked * ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKtQsi+KPYispwm2rkMidQf30fG1Niy8XNkvASfePoca eric at host
+         example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAWkjI6XT2SZh3xNk5NhisA3o3sGzWR+VAKMSqHtI0aY eric at host
+         192.168.42.12 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVYJpa0yUGaNk0NXQTPWa0tHjqRpx+7hl2diReH6DtR eric at host
+-        # Hash not yet supported.
+-        |1|7CMSYgzdwruFLRhwowMtKx0maIE=|Tlff1GFqc3Ao+fUWxMEVG8mJiyk= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHgN3O21U4LWtP5OzjTzPnUnSDmCNDvyvlaj6Hi65JC eric at host
++        |1|QxzZoTXIWLhUsuHAXjuDMIV3FjQ=|M6NCOIkjiWdCWqkh5+Q+/uFLGjs= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHgN3O21U4LWtP5OzjTzPnUnSDmCNDvyvlaj6Hi65JC eric at host
+         # Negation isn't terribly useful without globs.
+         neg.example.com,!neg.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOXfUnaAHTlo1Qi//rNk26OcmHikmkns1Z6WW/UuuS3K eric at host
+     "#;
+@@ -516,7 +529,7 @@ mod tests {
+     fn known_hosts_parse() {
+         let kh_path = Path::new("/home/abc/.known_hosts");
+         let khs = load_hostfile_contents(kh_path, COMMON_CONTENTS);
+-        assert_eq!(khs.len(), 9);
++        assert_eq!(khs.len(), 10);
+         match &khs[0].location {
+             KnownHostLocation::File { path, lineno } => {
+                 assert_eq!(path, kh_path);
+@@ -551,7 +564,9 @@ mod tests {
+         assert!(!khs[0].host_matches("example.net"));
+         assert!(khs[2].host_matches("[example.net]:2222"));
+         assert!(!khs[2].host_matches("example.net"));
+-        assert!(!khs[8].host_matches("neg.example.com"));
++        assert!(khs[8].host_matches("hashed.example.com"));
++        assert!(!khs[8].host_matches("example.com"));
++        assert!(!khs[9].host_matches("neg.example.com"));
+     }
+ 
+     #[test]
+--- rust-cargo-0.66.0.orig/Cargo.toml
++++ rust-cargo-0.66.0/Cargo.toml
+@@ -33,6 +33,7 @@ git2 = "0.16.0"
+ git2-curl = "0.17.0"
+ glob = "0.3.0"
+ hex = "0.4"
++hmac = "0.12.1"
+ home = "0.5"
+ humantime = "2.0.0"
+ indexmap = "1"
+@@ -53,6 +54,7 @@ semver = { version = "1.0.3", features =
+ serde = { version = "1.0.123", features = ["derive"] }
+ serde_ignored = "0.1.0"
+ serde_json = { version = "1.0.30", features = ["raw_value"] }
++sha1 = "0.10.1"
+ shell-escape = "0.1.4"
+ strip-ansi-escapes = "0.1.0"
+ tar = { version = "0.4.38", default-features = false }
+
diff -Nru cargo-0.66.0/debian/patches/cve/CVE-2022-46176-08-eliminate-let-else.patch cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-08-eliminate-let-else.patch
--- cargo-0.66.0/debian/patches/cve/CVE-2022-46176-08-eliminate-let-else.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/cve/CVE-2022-46176-08-eliminate-let-else.patch	2023-01-11 18:55:09.000000000 +0100
@@ -0,0 +1,61 @@
+This patch eliminates let-else usage in the code introduced
+to fix CVE-2022-46176 as that construct is not stabalised in
+the version of rustc currently in Debian.
+
+It was written specifical for Debian by Peter Michael Green.
+
+Index: cargo/src/cargo/sources/git/known_hosts.rs
+===================================================================
+--- cargo.orig/src/cargo/sources/git/known_hosts.rs
++++ cargo/src/cargo/sources/git/known_hosts.rs
+@@ -89,11 +89,13 @@ pub fn certificate_check(
+     config_known_hosts: Option<&Vec<Value<String>>>,
+     diagnostic_home_config: &str,
+ ) -> Result<CertificateCheckStatus, git2::Error> {
+-    let Some(host_key) = cert.as_hostkey() else {
++    let host_key = cert.as_hostkey();
++    if host_key.is_none() {
+         // Return passthrough for TLS X509 certificates to use whatever validation
+         // was done in git2.
+         return Ok(CertificateCheckStatus::CertificatePassthrough)
+     };
++    let host_key = host_key.unwrap();
+     // If a nonstandard port is in use, check for that first.
+     // The fallback to check without a port is handled in the HostKeyNotFound handler.
+     let host_maybe_port = match port {
+@@ -234,9 +236,11 @@ fn check_ssh_known_hosts(
+     host: &str,
+     config_known_hosts: Option<&Vec<Value<String>>>,
+ ) -> Result<(), KnownHostError> {
+-    let Some(remote_host_key) = cert_host_key.hostkey() else {
++    let remote_host_key = cert_host_key.hostkey();
++    if remote_host_key.is_none() {
+         return Err(anyhow::format_err!("remote host key is not available").into());
+     };
++    let remote_host_key = remote_host_key.unwrap();
+     let remote_key_type = cert_host_key.hostkey_type().unwrap();
+ 
+     // Collect all the known host entries from disk.
+@@ -455,10 +459,18 @@ impl KnownHost {
+ }
+ 
+ fn hashed_hostname_matches(host: &str, hashed: &str) -> bool {
+-    let Some((b64_salt, b64_host)) = hashed.split_once('|') else { return false; };
+-    let Ok(salt) = base64::decode(b64_salt) else { return false; };
+-    let Ok(hashed_host) = base64::decode(b64_host) else { return false; };
+-    let Ok(mut mac) = hmac::Hmac::<sha1::Sha1>::new_from_slice(&salt) else { return false; };
++    let hostandsalt = hashed.split_once('|');
++    if hostandsalt.is_none() { return false; };
++    let (b64_salt, b64_host) = hostandsalt.unwrap();
++    let salt = base64::decode(b64_salt);
++    if salt.is_err() { return false; };
++    let salt = salt.unwrap();
++    let hashed_host = base64::decode(b64_host);
++    if hashed_host.is_err() { return false; };
++    let hashed_host = hashed_host.unwrap();
++    let mac = hmac::Hmac::<sha1::Sha1>::new_from_slice(&salt);
++    if mac.is_err() { return false; };
++    let mut mac = mac.unwrap();
+     mac.update(host.as_bytes());
+     let result = mac.finalize().into_bytes();
+     hashed_host == &result[..]
diff -Nru cargo-0.66.0/debian/patches/series cargo-0.66.0+ds1/debian/patches/series
--- cargo-0.66.0/debian/patches/series	2023-01-08 16:37:31.000000000 +0100
+++ cargo-0.66.0+ds1/debian/patches/series	2023-01-11 18:55:09.000000000 +0100
@@ -4,3 +4,12 @@
 2200-workaround-x32-test.patch
 disable-fs-specific-test.patch
 0003-tests-add-missing-cross-disabled-checks.patch
+
+cve/CVE-2022-46176-01-validate-ssh-host.keys.patch
+cve/CVE-2022-46176-02-add-support-for-deserializing-vec-value-string.patch
+cve/CVE-2022-46176-03-support-configuring-ssh-known-hosts.patch
+cve/CVE-2022-46176-04-add-some-known-hosts-tests-and-fix-comma-bug.patch
+cve/CVE-2022-46176-05-remove-let-else.patch
+cve/CVE-2022-46176-06-add-test-for-config-value-in-toml-array.patch
+cve/CVE-2022-46176-07-support-hashed-hostnames.patch
+cve/CVE-2022-46176-08-eliminate-let-else.patch
diff -Nru cargo-0.66.0/debian/vendor-tarball-unsuspicious.txt cargo-0.66.0+ds1/debian/vendor-tarball-unsuspicious.txt
--- cargo-0.66.0/debian/vendor-tarball-unsuspicious.txt	2023-01-08 16:31:11.000000000 +0100
+++ cargo-0.66.0+ds1/debian/vendor-tarball-unsuspicious.txt	2023-01-11 18:55:09.000000000 +0100
@@ -7,6 +7,10 @@
 */LICENSE.md
 */README.md
 */Cargo.toml
+base64/RELEASE-NOTES.md
+
+# ignore
+base64/icon_CLion.svg
 
 # test data
 bstr/src/unicode/data/*Test.txt
@@ -14,6 +18,7 @@
 combine/benches/http-requests.txt
 content_inspector/testdata/*
 flate2/tests/
+hmac/tests/data/*.blb
 idna/tests/IdnaTestV2.txt
 idna/tests/punycode_tests.json
 im-rc/proptest-regressions/
@@ -30,6 +35,7 @@
 schannel/test/cert.der
 schannel/test/cert.pem
 schannel/test/key_wrong_header.pem
+sha1/tests/data/*.blb
 toml_edit/tests/fixtures/*
 unicode-ident/tests/fst/*.fst
 url/tests/*.json
@@ -66,6 +72,9 @@
 
 # false positive (Algol68)
 aho-corasick/src/nfa.rs
+base64/src/encode.rs
+base64/src/decode.rs
+block-buffer/tests/mod.rs
 clap/src/derive.rs
 combine/src/parser/choice.rs
 combine/src/parser/mod.rs
@@ -73,6 +82,9 @@
 combine/src/parser/token.rs
 combine/src/stream/mod.rs
 combine/src/stream/position.rs
+digest/src/dev.rs
+digest/src/core_api/wrapper.rs
+digest/src/core_api/rt_variable.rs
 env_logger-0.7.1/src/fmt/writer/mod.rs
 env_logger/src/fmt/writer/mod.rs
 flate2/src/mem.rs
diff -Nru cargo-0.66.0/vendor/base64/benches/benchmarks.rs cargo-0.66.0+ds1/vendor/base64/benches/benchmarks.rs
--- cargo-0.66.0/vendor/base64/benches/benchmarks.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/benches/benchmarks.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,210 @@
+extern crate base64;
+#[macro_use]
+extern crate criterion;
+extern crate rand;
+
+use base64::display;
+use base64::{
+    decode, decode_config_buf, decode_config_slice, encode, encode_config_buf, encode_config_slice,
+    write, Config,
+};
+
+use criterion::{black_box, Bencher, Criterion, ParameterizedBenchmark, Throughput};
+use rand::{FromEntropy, Rng};
+use std::io::{self, Read, Write};
+
+const TEST_CONFIG: Config = base64::STANDARD;
+
+fn do_decode_bench(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4);
+    fill(&mut v);
+    let encoded = encode(&v);
+
+    b.iter(|| {
+        let orig = decode(&encoded);
+        black_box(&orig);
+    });
+}
+
+fn do_decode_bench_reuse_buf(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4);
+    fill(&mut v);
+    let encoded = encode(&v);
+
+    let mut buf = Vec::new();
+    b.iter(|| {
+        decode_config_buf(&encoded, TEST_CONFIG, &mut buf).unwrap();
+        black_box(&buf);
+        buf.clear();
+    });
+}
+
+fn do_decode_bench_slice(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4);
+    fill(&mut v);
+    let encoded = encode(&v);
+
+    let mut buf = Vec::new();
+    buf.resize(size, 0);
+    b.iter(|| {
+        decode_config_slice(&encoded, TEST_CONFIG, &mut buf).unwrap();
+        black_box(&buf);
+    });
+}
+
+fn do_decode_bench_stream(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4);
+    fill(&mut v);
+    let encoded = encode(&v);
+
+    let mut buf = Vec::new();
+    buf.resize(size, 0);
+    buf.truncate(0);
+
+    b.iter(|| {
+        let mut cursor = io::Cursor::new(&encoded[..]);
+        let mut decoder = base64::read::DecoderReader::new(&mut cursor, TEST_CONFIG);
+        decoder.read_to_end(&mut buf).unwrap();
+        buf.clear();
+        black_box(&buf);
+    });
+}
+
+fn do_encode_bench(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+    b.iter(|| {
+        let e = encode(&v);
+        black_box(&e);
+    });
+}
+
+fn do_encode_bench_display(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+    b.iter(|| {
+        let e = format!("{}", display::Base64Display::with_config(&v, TEST_CONFIG));
+        black_box(&e);
+    });
+}
+
+fn do_encode_bench_reuse_buf(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+    let mut buf = String::new();
+    b.iter(|| {
+        encode_config_buf(&v, TEST_CONFIG, &mut buf);
+        buf.clear();
+    });
+}
+
+fn do_encode_bench_slice(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+    let mut buf = Vec::new();
+    // conservative estimate of encoded size
+    buf.resize(v.len() * 2, 0);
+    b.iter(|| {
+        encode_config_slice(&v, TEST_CONFIG, &mut buf);
+    });
+}
+
+fn do_encode_bench_stream(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+    let mut buf = Vec::new();
+
+    buf.reserve(size * 2);
+    b.iter(|| {
+        buf.clear();
+        let mut stream_enc = write::EncoderWriter::new(&mut buf, TEST_CONFIG);
+        stream_enc.write_all(&v).unwrap();
+        stream_enc.flush().unwrap();
+    });
+}
+
+fn do_encode_bench_string_stream(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+
+    b.iter(|| {
+        let mut stream_enc = write::EncoderStringWriter::new(TEST_CONFIG);
+        stream_enc.write_all(&v).unwrap();
+        stream_enc.flush().unwrap();
+        let _ = stream_enc.into_inner();
+    });
+}
+
+fn do_encode_bench_string_reuse_buf_stream(b: &mut Bencher, &size: &usize) {
+    let mut v: Vec<u8> = Vec::with_capacity(size);
+    fill(&mut v);
+
+    let mut buf = String::new();
+    b.iter(|| {
+        buf.clear();
+        let mut stream_enc = write::EncoderStringWriter::from(&mut buf, TEST_CONFIG);
+        stream_enc.write_all(&v).unwrap();
+        stream_enc.flush().unwrap();
+        let _ = stream_enc.into_inner();
+    });
+}
+
+fn fill(v: &mut Vec<u8>) {
+    let cap = v.capacity();
+    // weak randomness is plenty; we just want to not be completely friendly to the branch predictor
+    let mut r = rand::rngs::SmallRng::from_entropy();
+    while v.len() < cap {
+        v.push(r.gen::<u8>());
+    }
+}
+
+const BYTE_SIZES: [usize; 5] = [3, 50, 100, 500, 3 * 1024];
+
+// Benchmarks over these byte sizes take longer so we will run fewer samples to
+// keep the benchmark runtime reasonable.
+const LARGE_BYTE_SIZES: [usize; 3] = [3 * 1024 * 1024, 10 * 1024 * 1024, 30 * 1024 * 1024];
+
+fn encode_benchmarks(byte_sizes: &[usize]) -> ParameterizedBenchmark<usize> {
+    ParameterizedBenchmark::new("encode", do_encode_bench, byte_sizes.iter().cloned())
+        .warm_up_time(std::time::Duration::from_millis(500))
+        .measurement_time(std::time::Duration::from_secs(3))
+        .throughput(|s| Throughput::Bytes(*s as u64))
+        .with_function("encode_display", do_encode_bench_display)
+        .with_function("encode_reuse_buf", do_encode_bench_reuse_buf)
+        .with_function("encode_slice", do_encode_bench_slice)
+        .with_function("encode_reuse_buf_stream", do_encode_bench_stream)
+        .with_function("encode_string_stream", do_encode_bench_string_stream)
+        .with_function(
+            "encode_string_reuse_buf_stream",
+            do_encode_bench_string_reuse_buf_stream,
+        )
+}
+
+fn decode_benchmarks(byte_sizes: &[usize]) -> ParameterizedBenchmark<usize> {
+    ParameterizedBenchmark::new("decode", do_decode_bench, byte_sizes.iter().cloned())
+        .warm_up_time(std::time::Duration::from_millis(500))
+        .measurement_time(std::time::Duration::from_secs(3))
+        .throughput(|s| Throughput::Bytes(*s as u64))
+        .with_function("decode_reuse_buf", do_decode_bench_reuse_buf)
+        .with_function("decode_slice", do_decode_bench_slice)
+        .with_function("decode_stream", do_decode_bench_stream)
+}
+
+fn bench(c: &mut Criterion) {
+    c.bench("bench_small_input", encode_benchmarks(&BYTE_SIZES[..]));
+
+    c.bench(
+        "bench_large_input",
+        encode_benchmarks(&LARGE_BYTE_SIZES[..]).sample_size(10),
+    );
+
+    c.bench("bench_small_input", decode_benchmarks(&BYTE_SIZES[..]));
+
+    c.bench(
+        "bench_large_input",
+        decode_benchmarks(&LARGE_BYTE_SIZES[..]).sample_size(10),
+    );
+}
+
+criterion_group!(benches, bench);
+criterion_main!(benches);
diff -Nru cargo-0.66.0/vendor/base64/.cargo-checksum.json cargo-0.66.0+ds1/vendor/base64/.cargo-checksum.json
--- cargo-0.66.0/vendor/base64/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/base64/Cargo.lock cargo-0.66.0+ds1/vendor/base64/Cargo.lock
--- cargo-0.66.0/vendor/base64/Cargo.lock	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/Cargo.lock	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,826 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
+dependencies = [
+ "autocfg 1.1.0",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+dependencies = [
+ "criterion",
+ "rand",
+ "structopt",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bstr"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
+dependencies = [
+ "lazy_static",
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
+[[package]]
+name = "cast"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
+dependencies = [
+ "rustc_version",
+]
+
+[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "2.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
+dependencies = [
+ "ansi_term",
+ "atty",
+ "bitflags",
+ "strsim",
+ "textwrap",
+ "unicode-width",
+ "vec_map",
+]
+
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "criterion"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63f696897c88b57f4ffe3c69d8e1a0613c7d0e6c4833363c8560fbde9c47b966"
+dependencies = [
+ "atty",
+ "cast 0.2.7",
+ "clap",
+ "criterion-plot",
+ "csv",
+ "itertools 0.9.0",
+ "lazy_static",
+ "num-traits",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
+dependencies = [
+ "cast 0.3.0",
+ "itertools 0.10.5",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
+dependencies = [
+ "autocfg 1.1.0",
+ "cfg-if",
+ "crossbeam-utils",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "csv"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
+dependencies = [
+ "bstr",
+ "csv-core",
+ "itoa 0.4.8",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "either"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+
+[[package]]
+name = "fuchsia-cprng"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "itertools"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
+[[package]]
+name = "itoa"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.135"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg 1.1.0",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg 1.1.0",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
+
+[[package]]
+name = "oorandom"
+version = "11.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
+
+[[package]]
+name = "plotters"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d1685fbe7beba33de0330629da9d955ac75bd54f33d7b79f9a895590124f6bb"
+dependencies = [
+ "js-sys",
+ "num-traits",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+dependencies = [
+ "autocfg 0.1.8",
+ "libc",
+ "rand_chacha",
+ "rand_core 0.4.2",
+ "rand_hc",
+ "rand_isaac",
+ "rand_jitter",
+ "rand_os",
+ "rand_pcg",
+ "rand_xorshift",
+ "winapi",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+dependencies = [
+ "autocfg 0.1.8",
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
+dependencies = [
+ "rand_core 0.4.2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
+
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rand_jitter"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
+dependencies = [
+ "libc",
+ "rand_core 0.4.2",
+ "winapi",
+]
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+dependencies = [
+ "cloudabi",
+ "fuchsia-cprng",
+ "libc",
+ "rand_core 0.4.2",
+ "rdrand",
+ "winapi",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+dependencies = [
+ "autocfg 0.1.8",
+ "rand_core 0.4.2",
+]
+
+[[package]]
+name = "rand_xorshift"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rayon"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+dependencies = [
+ "autocfg 1.1.0",
+ "crossbeam-deque",
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "num_cpus",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "regex"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+dependencies = [
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "semver"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
+
+[[package]]
+name = "serde"
+version = "1.0.146"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6df50b7a60a0ad48e1b42eb38373eac8ff785d619fb14db917b4e63d5439361f"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.146"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a714fd32ba1d66047ce7d53dabd809e9922d538f9047de13cc4cffca47b36205"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
+dependencies = [
+ "itoa 1.0.4",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "strsim"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+
+[[package]]
+name = "structopt"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
+dependencies = [
+ "clap",
+ "lazy_static",
+ "structopt-derive",
+]
+
+[[package]]
+name = "structopt-derive"
+version = "0.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "web-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff -Nru cargo-0.66.0/vendor/base64/Cargo.toml cargo-0.66.0+ds1/vendor/base64/Cargo.toml
--- cargo-0.66.0/vendor/base64/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,53 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "base64"
+version = "0.13.1"
+authors = [
+    "Alice Maz <alice at alicemaz.com>",
+    "Marshall Pierce <marshall at mpierce.org>",
+]
+description = "encodes and decodes base64 as bytes or utf8"
+documentation = "https://docs.rs/base64"
+readme = "README.md"
+keywords = [
+    "base64",
+    "utf8",
+    "encode",
+    "decode",
+    "no_std",
+]
+categories = ["encoding"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/marshallpierce/rust-base64"
+
+[profile.bench]
+debug = true
+
+[[bench]]
+name = "benchmarks"
+harness = false
+
+[dev-dependencies.criterion]
+version = "=0.3.2"
+
+[dev-dependencies.rand]
+version = "0.6.1"
+
+[dev-dependencies.structopt]
+version = "0.3"
+
+[features]
+alloc = []
+default = ["std"]
+std = []
diff -Nru cargo-0.66.0/vendor/base64/examples/base64.rs cargo-0.66.0+ds1/vendor/base64/examples/base64.rs
--- cargo-0.66.0/vendor/base64/examples/base64.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/examples/base64.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,89 @@
+use std::fs::File;
+use std::io::{self, Read};
+use std::path::PathBuf;
+use std::process;
+use std::str::FromStr;
+
+use base64::{read, write};
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+enum CharacterSet {
+    Standard,
+    UrlSafe,
+}
+
+impl Default for CharacterSet {
+    fn default() -> Self {
+        CharacterSet::Standard
+    }
+}
+
+impl Into<base64::Config> for CharacterSet {
+    fn into(self) -> base64::Config {
+        match self {
+            CharacterSet::Standard => base64::STANDARD,
+            CharacterSet::UrlSafe => base64::URL_SAFE,
+        }
+    }
+}
+
+impl FromStr for CharacterSet {
+    type Err = String;
+    fn from_str(s: &str) -> Result<CharacterSet, String> {
+        match s {
+            "standard" => Ok(CharacterSet::Standard),
+            "urlsafe" => Ok(CharacterSet::UrlSafe),
+            _ => Err(format!("charset '{}' unrecognized", s)),
+        }
+    }
+}
+
+/// Base64 encode or decode FILE (or standard input), to standard output.
+#[derive(Debug, StructOpt)]
+struct Opt {
+    /// decode data
+    #[structopt(short = "d", long = "decode")]
+    decode: bool,
+    /// The character set to choose. Defaults to the standard base64 character set.
+    /// Supported character sets include "standard" and "urlsafe".
+    #[structopt(long = "charset")]
+    charset: Option<CharacterSet>,
+    /// The file to encode/decode.
+    #[structopt(parse(from_os_str))]
+    file: Option<PathBuf>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    let stdin;
+    let mut input: Box<dyn Read> = match opt.file {
+        None => {
+            stdin = io::stdin();
+            Box::new(stdin.lock())
+        }
+        Some(ref f) if f.as_os_str() == "-" => {
+            stdin = io::stdin();
+            Box::new(stdin.lock())
+        }
+        Some(f) => Box::new(File::open(f).unwrap()),
+    };
+    let config = opt.charset.unwrap_or_default().into();
+    let stdout = io::stdout();
+    let mut stdout = stdout.lock();
+    let r = if opt.decode {
+        let mut decoder = read::DecoderReader::new(&mut input, config);
+        io::copy(&mut decoder, &mut stdout)
+    } else {
+        let mut encoder = write::EncoderWriter::new(&mut stdout, config);
+        io::copy(&mut input, &mut encoder)
+    };
+    if let Err(e) = r {
+        eprintln!(
+            "Base64 {} failed with {}",
+            if opt.decode { "decode" } else { "encode" },
+            e
+        );
+        process::exit(1);
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/examples/make_tables.rs cargo-0.66.0+ds1/vendor/base64/examples/make_tables.rs
--- cargo-0.66.0/vendor/base64/examples/make_tables.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/examples/make_tables.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,179 @@
+use std::collections::{HashMap, HashSet};
+use std::iter::Iterator;
+
+fn main() {
+    println!("pub const INVALID_VALUE: u8 = 255;");
+
+    // A-Z
+    let standard_alphabet: Vec<u8> = (0x41..0x5B)
+        // a-z
+        .chain(0x61..0x7B)
+        // 0-9
+        .chain(0x30..0x3A)
+        // +
+        .chain(0x2B..0x2C)
+        // /
+        .chain(0x2F..0x30)
+        .collect();
+    print_encode_table(&standard_alphabet, "STANDARD_ENCODE", 0);
+    print_decode_table(&standard_alphabet, "STANDARD_DECODE", 0);
+
+    // A-Z
+    let url_alphabet: Vec<u8> = (0x41..0x5B)
+        // a-z
+        .chain(0x61..0x7B)
+        // 0-9
+        .chain(0x30..0x3A)
+        // -
+        .chain(0x2D..0x2E)
+        // _
+        .chain(0x5F..0x60)
+        .collect();
+    print_encode_table(&url_alphabet, "URL_SAFE_ENCODE", 0);
+    print_decode_table(&url_alphabet, "URL_SAFE_DECODE", 0);
+
+    // ./0123456789
+    let crypt_alphabet: Vec<u8> = (b'.'..(b'9' + 1))
+        // A-Z
+        .chain(b'A'..(b'Z' + 1))
+        // a-z
+        .chain(b'a'..(b'z' + 1))
+        .collect();
+    print_encode_table(&crypt_alphabet, "CRYPT_ENCODE", 0);
+    print_decode_table(&crypt_alphabet, "CRYPT_DECODE", 0);
+
+    // ./
+    let bcrypt_alphabet: Vec<u8> = (b'.'..(b'/' + 1))
+        // A-Z
+        .chain(b'A'..(b'Z' + 1))
+        // a-z
+        .chain(b'a'..(b'z' + 1))
+        // 0-9
+        .chain(b'0'..(b'9' + 1))
+        .collect();
+    print_encode_table(&bcrypt_alphabet, "BCRYPT_ENCODE", 0);
+    print_decode_table(&bcrypt_alphabet, "BCRYPT_DECODE", 0);
+
+    // A-Z
+    let imap_alphabet: Vec<u8> = (0x41..0x5B)
+        // a-z
+        .chain(0x61..0x7B)
+        // 0-9
+        .chain(0x30..0x3A)
+        // +
+        .chain(0x2B..0x2C)
+        // ,
+        .chain(0x2C..0x2D)
+        .collect();
+    print_encode_table(&imap_alphabet, "IMAP_MUTF7_ENCODE", 0);
+    print_decode_table(&imap_alphabet, "IMAP_MUTF7_DECODE", 0);
+
+    // '!' - '-'
+    let binhex_alphabet: Vec<u8> = (0x21..0x2E)
+        // 0-9
+        .chain(0x30..0x3A)
+        // @-N
+        .chain(0x40..0x4F)
+        // P-V
+        .chain(0x50..0x57)
+        // X-[
+        .chain(0x58..0x5C)
+        // `-f
+        .chain(0x60..0x66)
+        // h-m
+        .chain(0x68..0x6E)
+        // p-r
+        .chain(0x70..0x73)
+        .collect();
+    print_encode_table(&binhex_alphabet, "BINHEX_ENCODE", 0);
+    print_decode_table(&binhex_alphabet, "BINHEX_DECODE", 0);
+}
+
+fn print_encode_table(alphabet: &[u8], const_name: &str, indent_depth: usize) {
+    check_alphabet(alphabet);
+    println!("#[rustfmt::skip]");
+    println!(
+        "{:width$}pub const {}: &[u8; 64] = &[",
+        "",
+        const_name,
+        width = indent_depth
+    );
+
+    for (i, b) in alphabet.iter().enumerate() {
+        println!(
+            "{:width$}{}, // input {} (0x{:X}) => '{}' (0x{:X})",
+            "",
+            b,
+            i,
+            i,
+            String::from_utf8(vec![*b as u8]).unwrap(),
+            b,
+            width = indent_depth + 4
+        );
+    }
+
+    println!("{:width$}];", "", width = indent_depth);
+}
+
+fn print_decode_table(alphabet: &[u8], const_name: &str, indent_depth: usize) {
+    check_alphabet(alphabet);
+    // map of alphabet bytes to 6-bit morsels
+    let mut input_to_morsel = HashMap::<u8, u8>::new();
+
+    // standard base64 alphabet bytes, in order
+    for (morsel, ascii_byte) in alphabet.iter().enumerate() {
+        // truncation cast is fine here
+        let _ = input_to_morsel.insert(*ascii_byte, morsel as u8);
+    }
+
+    println!("#[rustfmt::skip]");
+    println!(
+        "{:width$}pub const {}: &[u8; 256] = &[",
+        "",
+        const_name,
+        width = indent_depth
+    );
+    for ascii_byte in 0..256 {
+        let (value, comment) = match input_to_morsel.get(&(ascii_byte as u8)) {
+            None => (
+                "INVALID_VALUE".to_string(),
+                format!("input {} (0x{:X})", ascii_byte, ascii_byte),
+            ),
+            Some(v) => (
+                format!("{}", *v),
+                format!(
+                    "input {} (0x{:X} char '{}') => {} (0x{:X})",
+                    ascii_byte,
+                    ascii_byte,
+                    String::from_utf8(vec![ascii_byte as u8]).unwrap(),
+                    *v,
+                    *v
+                ),
+            ),
+        };
+
+        println!(
+            "{:width$}{}, // {}",
+            "",
+            value,
+            comment,
+            width = indent_depth + 4
+        );
+    }
+    println!("{:width$}];", "", width = indent_depth);
+}
+
+fn check_alphabet(alphabet: &[u8]) {
+    // ensure all characters are distinct
+    assert_eq!(64, alphabet.len());
+    let mut set: HashSet<u8> = HashSet::new();
+    set.extend(alphabet);
+    assert_eq!(64, set.len());
+
+    // must be ASCII to be valid as single UTF-8 bytes
+    for &b in alphabet {
+        assert!(b <= 0x7F_u8);
+        // = is assumed to be padding, so cannot be used as a symbol
+        assert_ne!(b'=', b);
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/icon_CLion.svg cargo-0.66.0+ds1/vendor/base64/icon_CLion.svg
--- cargo-0.66.0/vendor/base64/icon_CLion.svg	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/icon_CLion.svg	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,34 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 128 128">
+  <defs>
+    <linearGradient id="linear-gradient" x1="40.69" y1="-676.56" x2="83.48" y2="-676.56" gradientTransform="matrix(1, 0, 0, -1, 0, -648.86)" gradientUnits="userSpaceOnUse">
+      <stop offset="0" stop-color="#ed358c"/>
+      <stop offset="0.16" stop-color="#e9388c"/>
+      <stop offset="0.3" stop-color="#de418c"/>
+      <stop offset="0.43" stop-color="#cc508c"/>
+      <stop offset="0.57" stop-color="#b2658d"/>
+      <stop offset="0.7" stop-color="#90808d"/>
+      <stop offset="0.83" stop-color="#67a18e"/>
+      <stop offset="0.95" stop-color="#37c78f"/>
+      <stop offset="1" stop-color="#22d88f"/>
+    </linearGradient>
+    <linearGradient id="linear-gradient-2" x1="32.58" y1="-665.27" x2="13.76" y2="-791.59" gradientTransform="matrix(1, 0, 0, -1, 0, -648.86)" gradientUnits="userSpaceOnUse">
+      <stop offset="0.09" stop-color="#22d88f"/>
+      <stop offset="0.9" stop-color="#029de0"/>
+    </linearGradient>
+    <linearGradient id="linear-gradient-3" x1="116.68" y1="-660.66" x2="-12.09" y2="-796.66" xlink:href="#linear-gradient-2"/>
+    <linearGradient id="linear-gradient-4" x1="73.35" y1="-739.1" x2="122.29" y2="-746.06" xlink:href="#linear-gradient-2"/>
+  </defs>
+  <title>icon_CLion</title>
+  <g>
+    <polygon points="49.2 51.8 40.6 55.4 48.4 0 77.8 16.2 49.2 51.8" fill="url(#linear-gradient)"/>
+    <polygon points="44.6 76.8 48.8 0 11.8 23.2 0 94 44.6 76.8" fill="url(#linear-gradient-2)"/>
+    <polygon points="125.4 38.4 109 4.8 77.8 16.2 55 41.4 0 94 41.6 124.4 93.6 77.2 125.4 38.4" fill="url(#linear-gradient-3)"/>
+    <polygon points="53.8 54.6 46.6 98.4 75.8 121 107.8 128 128 82.4 53.8 54.6" fill="url(#linear-gradient-4)"/>
+  </g>
+  <g>
+    <rect x="24" y="24" width="80" height="80"/>
+    <rect x="31.6" y="89" width="30" height="5" fill="#fff"/>
+    <path d="M31,51.2h0A16.83,16.83,0,0,1,48.2,34c6.2,0,10,2,13,5.2l-4.6,5.4c-2.6-2.4-5.2-3.8-8.4-3.8-5.6,0-9.6,4.6-9.6,10.4h0c0,5.6,4,10.4,9.6,10.4,3.8,0,6.2-1.6,8.8-3.8l4.6,4.6c-3.4,3.6-7.2,6-13.6,6A17,17,0,0,1,31,51.2" fill="#fff"/>
+    <path d="M66.6,34.4H74v27H88.4v6.2H66.6V34.4Z" fill="#fff"/>
+  </g>
+</svg>
diff -Nru cargo-0.66.0/vendor/base64/LICENSE-APACHE cargo-0.66.0+ds1/vendor/base64/LICENSE-APACHE
--- cargo-0.66.0/vendor/base64/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/base64/LICENSE-MIT cargo-0.66.0+ds1/vendor/base64/LICENSE-MIT
--- cargo-0.66.0/vendor/base64/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Alice Maz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/base64/README.md cargo-0.66.0+ds1/vendor/base64/README.md
--- cargo-0.66.0/vendor/base64/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,114 @@
+[base64](https://crates.io/crates/base64)
+===
+
+[![](https://img.shields.io/crates/v/base64.svg)](https://crates.io/crates/base64) [![Docs](https://docs.rs/base64/badge.svg)](https://docs.rs/base64) [![Build](https://travis-ci.org/marshallpierce/rust-base64.svg?branch=master)](https://travis-ci.org/marshallpierce/rust-base64) [![codecov](https://codecov.io/gh/marshallpierce/rust-base64/branch/master/graph/badge.svg)](https://codecov.io/gh/marshallpierce/rust-base64) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)
+
+<a href="https://www.jetbrains.com/?from=rust-base64"><img src="/icon_CLion.svg" height="40px"/></a>
+
+Made with CLion. Thanks to JetBrains for supporting open source!
+
+It's base64. What more could anyone want?
+
+This library's goals are to be *correct* and *fast*. It's thoroughly tested and widely used. It exposes functionality at multiple levels of abstraction so you can choose the level of convenience vs performance that you want, e.g. `decode_config_slice` decodes into an existing `&mut [u8]` and is pretty fast (2.6GiB/s for a 3 KiB input), whereas `decode_config` allocates a new `Vec<u8>` and returns it, which might be more convenient in some cases, but is slower (although still fast enough for almost any purpose) at 2.1 GiB/s.
+
+Example
+---
+
+```rust
+extern crate base64;
+
+use base64::{encode, decode};
+
+fn main() {
+    let a = b"hello world";
+    let b = "aGVsbG8gd29ybGQ=";
+
+    assert_eq!(encode(a), b);
+    assert_eq!(a, &decode(b).unwrap()[..]);
+}
+```
+
+See the [docs](https://docs.rs/base64) for all the details.
+
+Rust version compatibility
+---
+
+The minimum required Rust version is 1.34.0.
+
+Developing
+---
+
+Benchmarks are in `benches/`. Running them requires nightly rust, but `rustup` makes it easy:
+
+```bash
+rustup run nightly cargo bench
+```
+
+Decoding is aided by some pre-calculated tables, which are generated by:
+
+```bash
+cargo run --example make_tables > src/tables.rs.tmp && mv src/tables.rs.tmp src/tables.rs
+```
+
+no_std
+---
+
+This crate supports no_std. By default the crate targets std via the `std` feature. You can deactivate the `default-features` to target core instead. In that case you lose out on all the functionality revolving around `std::io`, `std::error::Error` and heap allocations. There is an additional `alloc` feature that you can activate to bring back the support for heap allocations.
+
+Profiling
+---
+
+On Linux, you can use [perf](https://perf.wiki.kernel.org/index.php/Main_Page) for profiling. Then compile the benchmarks with `rustup nightly run cargo bench --no-run`.
+
+Run the benchmark binary with `perf` (shown here filtering to one particular benchmark, which will make the results easier to read). `perf` is only available to the root user on most systems as it fiddles with event counters in your CPU, so use `sudo`. We need to run the actual benchmark binary, hence the path into `target`. You can see the actual full path with `rustup run nightly cargo bench -v`; it will print out the commands it runs. If you use the exact path that `bench` outputs, make sure you get the one that's for the benchmarks, not the tests. You may also want to `cargo clean` so you have only one `benchmarks-` binary (they tend to accumulate).
+
+```bash
+sudo perf record target/release/deps/benchmarks-* --bench decode_10mib_reuse
+```
+
+Then analyze the results, again with perf:
+
+```bash
+sudo perf annotate -l
+```
+
+You'll see a bunch of interleaved rust source and assembly like this. The section with `lib.rs:327` is telling us that 4.02% of samples saw the `movzbl` aka bit shift as the active instruction. However, this percentage is not as exact as it seems due to a phenomenon called *skid*. Basically, a consequence of how fancy modern CPUs are is that this sort of instruction profiling is inherently inaccurate, especially in branch-heavy code.
+
+```text
+ lib.rs:322    0.70 :     10698:       mov    %rdi,%rax
+    2.82 :        1069b:       shr    $0x38,%rax
+         :                  if morsel == decode_tables::INVALID_VALUE {
+         :                      bad_byte_index = input_index;
+         :                      break;
+         :                  };
+         :                  accum = (morsel as u64) << 58;
+ lib.rs:327    4.02 :     1069f:       movzbl (%r9,%rax,1),%r15d
+         :              // fast loop of 8 bytes at a time
+         :              while input_index < length_of_full_chunks {
+         :                  let mut accum: u64;
+         :
+         :                  let input_chunk = BigEndian::read_u64(&input_bytes[input_index..(input_index + 8)]);
+         :                  morsel = decode_table[(input_chunk >> 56) as usize];
+ lib.rs:322    3.68 :     106a4:       cmp    $0xff,%r15
+         :                  if morsel == decode_tables::INVALID_VALUE {
+    0.00 :        106ab:       je     1090e <base64::decode_config_buf::hbf68a45fefa299c1+0x46e>
+```
+
+
+Fuzzing
+---
+
+This uses [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz). See `fuzz/fuzzers` for the available fuzzing scripts. To run, use an invocation like these:
+
+```bash
+cargo +nightly fuzz run roundtrip
+cargo +nightly fuzz run roundtrip_no_pad
+cargo +nightly fuzz run roundtrip_random_config -- -max_len=10240
+cargo +nightly fuzz run decode_random
+```
+
+
+License
+---
+
+This project is dual-licensed under MIT and Apache 2.0.
diff -Nru cargo-0.66.0/vendor/base64/RELEASE-NOTES.md cargo-0.66.0+ds1/vendor/base64/RELEASE-NOTES.md
--- cargo-0.66.0/vendor/base64/RELEASE-NOTES.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/RELEASE-NOTES.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,109 @@
+# 0.13.1
+
+- More precise decode buffer sizing, avoiding unnecessary allocation in `decode_config`.
+
+# 0.13.0
+
+- Config methods are const
+- Added `EncoderStringWriter` to allow encoding directly to a String
+- `EncoderWriter` now owns its delegate writer rather than keeping a reference to it (though refs still work)
+    - As a consequence, it is now possible to extract the delegate writer from an `EncoderWriter` via `finish()`, which returns `Result<W>` instead of `Result<()>`. If you were calling `finish()` explicitly, you will now need to use `let _ = foo.finish()` instead of just `foo.finish()` to avoid a warning about the unused value.
+- When decoding input that has both an invalid length and an invalid symbol as the last byte, `InvalidByte` will be emitted instead of `InvalidLength` to make the problem more obvious.
+
+# 0.12.2
+
+- Add `BinHex` alphabet
+
+# 0.12.1
+
+- Add `Bcrypt` alphabet
+
+# 0.12.0
+
+- A `Read` implementation (`DecoderReader`) to let users transparently decoded data from a b64 input source
+- IMAP's modified b64 alphabet
+- Relaxed type restrictions to just `AsRef<[ut8]>` for main `encode*`/`decode*` functions
+- A minor performance improvement in encoding
+
+# 0.11.0
+- Minimum rust version 1.34.0
+- `no_std` is now supported via the two new features `alloc` and `std`.
+
+# 0.10.1
+
+- Minimum rust version 1.27.2
+- Fix bug in streaming encoding ([#90](https://github.com/marshallpierce/rust-base64/pull/90)): if the underlying writer didn't write all the bytes given to it, the remaining bytes would not be retried later. See the docs on `EncoderWriter::write`.
+- Make it configurable whether or not to return an error when decoding detects excess trailing bits.
+
+# 0.10.0
+
+- Remove line wrapping. Line wrapping was never a great conceptual fit in this library, and other features (streaming encoding, etc) either couldn't support it or could support only special cases of it with a great increase in complexity. Line wrapping has been pulled out into a [line-wrap](https://crates.io/crates/line-wrap) crate, so it's still available if you need it.
+  - `Base64Display` creation no longer uses a `Result` because it can't fail, which means its helper methods for common
+  configs that `unwrap()` for you are no longer needed
+- Add a streaming encoder `Write` impl to transparently base64 as you write.
+- Remove the remaining `unsafe` code.
+- Remove whitespace stripping to simplify `no_std` support. No out of the box configs use it, and it's trivial to do yourself if needed: `filter(|b| !b" \n\t\r\x0b\x0c".contains(b)`.
+- Detect invalid trailing symbols when decoding and return an error rather than silently ignoring them.
+
+# 0.9.3
+
+- Update safemem
+
+# 0.9.2
+
+- Derive `Clone` for `DecodeError`.
+
+# 0.9.1
+
+- Add support for `crypt(3)`'s base64 variant.
+
+# 0.9.0
+
+- `decode_config_slice` function for no-allocation decoding, analogous to `encode_config_slice`
+- Decode performance optimization
+
+# 0.8.0
+
+- `encode_config_slice` function for no-allocation encoding
+
+# 0.7.0
+
+- `STANDARD_NO_PAD` config
+- `Base64Display` heap-free wrapper for use in format strings, etc
+
+# 0.6.0
+
+- Decode performance improvements
+- Use `unsafe` in fewer places
+- Added fuzzers
+
+# 0.5.2
+
+- Avoid usize overflow when calculating length
+- Better line wrapping performance
+
+# 0.5.1
+
+- Temporarily disable line wrapping
+- Add Apache 2.0 license
+
+# 0.5.0
+
+- MIME support, including configurable line endings and line wrapping
+- Removed `decode_ws`
+- Renamed `Base64Error` to `DecodeError`
+
+# 0.4.1
+
+- Allow decoding a `AsRef<[u8]>` instead of just a `&str`
+
+# 0.4.0
+
+- Configurable padding
+- Encode performance improvements
+
+# 0.3.0
+
+- Added encode/decode functions that do not allocate their own storage
+- Decode performance improvements
+- Extraneous padding bytes are no longer ignored. Now, an error will be returned.
diff -Nru cargo-0.66.0/vendor/base64/src/chunked_encoder.rs cargo-0.66.0+ds1/vendor/base64/src/chunked_encoder.rs
--- cargo-0.66.0/vendor/base64/src/chunked_encoder.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/chunked_encoder.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,247 @@
+use crate::{
+    encode::{add_padding, encode_to_slice},
+    Config,
+};
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use alloc::string::String;
+use core::cmp;
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use core::str;
+
+/// The output mechanism for ChunkedEncoder's encoded bytes.
+pub trait Sink {
+    type Error;
+
+    /// Handle a chunk of encoded base64 data (as UTF-8 bytes)
+    fn write_encoded_bytes(&mut self, encoded: &[u8]) -> Result<(), Self::Error>;
+}
+
+const BUF_SIZE: usize = 1024;
+
+/// A base64 encoder that emits encoded bytes in chunks without heap allocation.
+pub struct ChunkedEncoder {
+    config: Config,
+    max_input_chunk_len: usize,
+}
+
+impl ChunkedEncoder {
+    pub fn new(config: Config) -> ChunkedEncoder {
+        ChunkedEncoder {
+            config,
+            max_input_chunk_len: max_input_length(BUF_SIZE, config),
+        }
+    }
+
+    pub fn encode<S: Sink>(&self, bytes: &[u8], sink: &mut S) -> Result<(), S::Error> {
+        let mut encode_buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
+        let encode_table = self.config.char_set.encode_table();
+
+        let mut input_index = 0;
+
+        while input_index < bytes.len() {
+            // either the full input chunk size, or it's the last iteration
+            let input_chunk_len = cmp::min(self.max_input_chunk_len, bytes.len() - input_index);
+
+            let chunk = &bytes[input_index..(input_index + input_chunk_len)];
+
+            let mut b64_bytes_written = encode_to_slice(chunk, &mut encode_buf, encode_table);
+
+            input_index += input_chunk_len;
+            let more_input_left = input_index < bytes.len();
+
+            if self.config.pad && !more_input_left {
+                // no more input, add padding if needed. Buffer will have room because
+                // max_input_length leaves room for it.
+                b64_bytes_written += add_padding(bytes.len(), &mut encode_buf[b64_bytes_written..]);
+            }
+
+            sink.write_encoded_bytes(&encode_buf[0..b64_bytes_written])?;
+        }
+
+        Ok(())
+    }
+}
+
+/// Calculate the longest input that can be encoded for the given output buffer size.
+///
+/// If the config requires padding, two bytes of buffer space will be set aside so that the last
+/// chunk of input can be encoded safely.
+///
+/// The input length will always be a multiple of 3 so that no encoding state has to be carried over
+/// between chunks.
+fn max_input_length(encoded_buf_len: usize, config: Config) -> usize {
+    let effective_buf_len = if config.pad {
+        // make room for padding
+        encoded_buf_len
+            .checked_sub(2)
+            .expect("Don't use a tiny buffer")
+    } else {
+        encoded_buf_len
+    };
+
+    // No padding, so just normal base64 expansion.
+    (effective_buf_len / 4) * 3
+}
+
+// A really simple sink that just appends to a string
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub(crate) struct StringSink<'a> {
+    string: &'a mut String,
+}
+
+#[cfg(any(feature = "alloc", feature = "std", test))]
+impl<'a> StringSink<'a> {
+    pub(crate) fn new(s: &mut String) -> StringSink {
+        StringSink { string: s }
+    }
+}
+
+#[cfg(any(feature = "alloc", feature = "std", test))]
+impl<'a> Sink for StringSink<'a> {
+    type Error = ();
+
+    fn write_encoded_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error> {
+        self.string.push_str(str::from_utf8(s).unwrap());
+
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+pub mod tests {
+    use super::*;
+    use crate::{encode_config_buf, tests::random_config, CharacterSet, STANDARD};
+
+    use rand::{
+        distributions::{Distribution, Uniform},
+        FromEntropy, Rng,
+    };
+
+    #[test]
+    fn chunked_encode_empty() {
+        assert_eq!("", chunked_encode_str(&[], STANDARD));
+    }
+
+    #[test]
+    fn chunked_encode_intermediate_fast_loop() {
+        // > 8 bytes input, will enter the pretty fast loop
+        assert_eq!(
+            "Zm9vYmFyYmF6cXV4",
+            chunked_encode_str(b"foobarbazqux", STANDARD)
+        );
+    }
+
+    #[test]
+    fn chunked_encode_fast_loop() {
+        // > 32 bytes input, will enter the uber fast loop
+        assert_eq!(
+            "Zm9vYmFyYmF6cXV4cXV1eGNvcmdlZ3JhdWx0Z2FycGx5eg==",
+            chunked_encode_str(b"foobarbazquxquuxcorgegraultgarplyz", STANDARD)
+        );
+    }
+
+    #[test]
+    fn chunked_encode_slow_loop_only() {
+        // < 8 bytes input, slow loop only
+        assert_eq!("Zm9vYmFy", chunked_encode_str(b"foobar", STANDARD));
+    }
+
+    #[test]
+    fn chunked_encode_matches_normal_encode_random_string_sink() {
+        let helper = StringSinkTestHelper;
+        chunked_encode_matches_normal_encode_random(&helper);
+    }
+
+    #[test]
+    fn max_input_length_no_pad() {
+        let config = config_with_pad(false);
+        assert_eq!(768, max_input_length(1024, config));
+    }
+
+    #[test]
+    fn max_input_length_with_pad_decrements_one_triple() {
+        let config = config_with_pad(true);
+        assert_eq!(765, max_input_length(1024, config));
+    }
+
+    #[test]
+    fn max_input_length_with_pad_one_byte_short() {
+        let config = config_with_pad(true);
+        assert_eq!(765, max_input_length(1025, config));
+    }
+
+    #[test]
+    fn max_input_length_with_pad_fits_exactly() {
+        let config = config_with_pad(true);
+        assert_eq!(768, max_input_length(1026, config));
+    }
+
+    #[test]
+    fn max_input_length_cant_use_extra_single_encoded_byte() {
+        let config = Config::new(crate::CharacterSet::Standard, false);
+        assert_eq!(300, max_input_length(401, config));
+    }
+
+    pub fn chunked_encode_matches_normal_encode_random<S: SinkTestHelper>(sink_test_helper: &S) {
+        let mut input_buf: Vec<u8> = Vec::new();
+        let mut output_buf = String::new();
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+        let input_len_range = Uniform::new(1, 10_000);
+
+        for _ in 0..5_000 {
+            input_buf.clear();
+            output_buf.clear();
+
+            let buf_len = input_len_range.sample(&mut rng);
+            for _ in 0..buf_len {
+                input_buf.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+
+            let chunk_encoded_string = sink_test_helper.encode_to_string(config, &input_buf);
+            encode_config_buf(&input_buf, config, &mut output_buf);
+
+            assert_eq!(
+                output_buf, chunk_encoded_string,
+                "input len={}, config: pad={}",
+                buf_len, config.pad
+            );
+        }
+    }
+
+    fn chunked_encode_str(bytes: &[u8], config: Config) -> String {
+        let mut s = String::new();
+        {
+            let mut sink = StringSink::new(&mut s);
+            let encoder = ChunkedEncoder::new(config);
+            encoder.encode(bytes, &mut sink).unwrap();
+        }
+
+        return s;
+    }
+
+    fn config_with_pad(pad: bool) -> Config {
+        Config::new(CharacterSet::Standard, pad)
+    }
+
+    // An abstraction around sinks so that we can have tests that easily to any sink implementation
+    pub trait SinkTestHelper {
+        fn encode_to_string(&self, config: Config, bytes: &[u8]) -> String;
+    }
+
+    struct StringSinkTestHelper;
+
+    impl SinkTestHelper for StringSinkTestHelper {
+        fn encode_to_string(&self, config: Config, bytes: &[u8]) -> String {
+            let encoder = ChunkedEncoder::new(config);
+            let mut s = String::new();
+            {
+                let mut sink = StringSink::new(&mut s);
+                encoder.encode(bytes, &mut sink).unwrap();
+            }
+
+            s
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/decode.rs cargo-0.66.0+ds1/vendor/base64/src/decode.rs
--- cargo-0.66.0/vendor/base64/src/decode.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/decode.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,893 @@
+use crate::{tables, Config, PAD_BYTE};
+
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use crate::STANDARD;
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use alloc::vec::Vec;
+use core::fmt;
+#[cfg(any(feature = "std", test))]
+use std::error;
+
+// decode logic operates on chunks of 8 input bytes without padding
+const INPUT_CHUNK_LEN: usize = 8;
+const DECODED_CHUNK_LEN: usize = 6;
+// we read a u64 and write a u64, but a u64 of input only yields 6 bytes of output, so the last
+// 2 bytes of any output u64 should not be counted as written to (but must be available in a
+// slice).
+const DECODED_CHUNK_SUFFIX: usize = 2;
+
+// how many u64's of input to handle at a time
+const CHUNKS_PER_FAST_LOOP_BLOCK: usize = 4;
+const INPUT_BLOCK_LEN: usize = CHUNKS_PER_FAST_LOOP_BLOCK * INPUT_CHUNK_LEN;
+// includes the trailing 2 bytes for the final u64 write
+const DECODED_BLOCK_LEN: usize =
+    CHUNKS_PER_FAST_LOOP_BLOCK * DECODED_CHUNK_LEN + DECODED_CHUNK_SUFFIX;
+
+/// Errors that can occur while decoding.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum DecodeError {
+    /// An invalid byte was found in the input. The offset and offending byte are provided.
+    InvalidByte(usize, u8),
+    /// The length of the input is invalid.
+    /// A typical cause of this is stray trailing whitespace or other separator bytes.
+    /// In the case where excess trailing bytes have produced an invalid length *and* the last byte
+    /// is also an invalid base64 symbol (as would be the case for whitespace, etc), `InvalidByte`
+    /// will be emitted instead of `InvalidLength` to make the issue easier to debug.
+    InvalidLength,
+    /// The last non-padding input symbol's encoded 6 bits have nonzero bits that will be discarded.
+    /// This is indicative of corrupted or truncated Base64.
+    /// Unlike InvalidByte, which reports symbols that aren't in the alphabet, this error is for
+    /// symbols that are in the alphabet but represent nonsensical encodings.
+    InvalidLastSymbol(usize, u8),
+}
+
+impl fmt::Display for DecodeError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            DecodeError::InvalidByte(index, byte) => {
+                write!(f, "Invalid byte {}, offset {}.", byte, index)
+            }
+            DecodeError::InvalidLength => write!(f, "Encoded text cannot have a 6-bit remainder."),
+            DecodeError::InvalidLastSymbol(index, byte) => {
+                write!(f, "Invalid last symbol {}, offset {}.", byte, index)
+            }
+        }
+    }
+}
+
+#[cfg(any(feature = "std", test))]
+impl error::Error for DecodeError {
+    fn description(&self) -> &str {
+        match *self {
+            DecodeError::InvalidByte(_, _) => "invalid byte",
+            DecodeError::InvalidLength => "invalid length",
+            DecodeError::InvalidLastSymbol(_, _) => "invalid last symbol",
+        }
+    }
+
+    fn cause(&self) -> Option<&dyn error::Error> {
+        None
+    }
+}
+
+///Decode from string reference as octets.
+///Returns a Result containing a Vec<u8>.
+///Convenience `decode_config(input, base64::STANDARD);`.
+///
+///# Example
+///
+///```rust
+///extern crate base64;
+///
+///fn main() {
+///    let bytes = base64::decode("aGVsbG8gd29ybGQ=").unwrap();
+///    println!("{:?}", bytes);
+///}
+///```
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub fn decode<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, DecodeError> {
+    decode_config(input, STANDARD)
+}
+
+///Decode from string reference as octets.
+///Returns a Result containing a Vec<u8>.
+///
+///# Example
+///
+///```rust
+///extern crate base64;
+///
+///fn main() {
+///    let bytes = base64::decode_config("aGVsbG8gd29ybGR+Cg==", base64::STANDARD).unwrap();
+///    println!("{:?}", bytes);
+///
+///    let bytes_url = base64::decode_config("aGVsbG8gaW50ZXJuZXR-Cg==", base64::URL_SAFE).unwrap();
+///    println!("{:?}", bytes_url);
+///}
+///```
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub fn decode_config<T: AsRef<[u8]>>(input: T, config: Config) -> Result<Vec<u8>, DecodeError> {
+    let decoded_length_estimate = (input
+        .as_ref()
+        .len()
+        .checked_add(3)
+        .expect("decoded length calculation overflow"))
+        / 4
+        * 3;
+    let mut buffer = Vec::<u8>::with_capacity(decoded_length_estimate);
+
+    decode_config_buf(input, config, &mut buffer).map(|_| buffer)
+}
+
+///Decode from string reference as octets.
+///Writes into the supplied buffer to avoid allocation.
+///Returns a Result containing an empty tuple, aka ().
+///
+///# Example
+///
+///```rust
+///extern crate base64;
+///
+///fn main() {
+///    let mut buffer = Vec::<u8>::new();
+///    base64::decode_config_buf("aGVsbG8gd29ybGR+Cg==", base64::STANDARD, &mut buffer).unwrap();
+///    println!("{:?}", buffer);
+///
+///    buffer.clear();
+///
+///    base64::decode_config_buf("aGVsbG8gaW50ZXJuZXR-Cg==", base64::URL_SAFE, &mut buffer)
+///        .unwrap();
+///    println!("{:?}", buffer);
+///}
+///```
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub fn decode_config_buf<T: AsRef<[u8]>>(
+    input: T,
+    config: Config,
+    buffer: &mut Vec<u8>,
+) -> Result<(), DecodeError> {
+    let input_bytes = input.as_ref();
+
+    let starting_output_len = buffer.len();
+
+    let num_chunks = num_chunks(input_bytes);
+    let decoded_len_estimate = num_chunks
+        .checked_mul(DECODED_CHUNK_LEN)
+        .and_then(|p| p.checked_add(starting_output_len))
+        .expect("Overflow when calculating output buffer length");
+    buffer.resize(decoded_len_estimate, 0);
+
+    let bytes_written;
+    {
+        let buffer_slice = &mut buffer.as_mut_slice()[starting_output_len..];
+        bytes_written = decode_helper(input_bytes, num_chunks, config, buffer_slice)?;
+    }
+
+    buffer.truncate(starting_output_len + bytes_written);
+
+    Ok(())
+}
+
+/// Decode the input into the provided output slice.
+///
+/// This will not write any bytes past exactly what is decoded (no stray garbage bytes at the end).
+///
+/// If you don't know ahead of time what the decoded length should be, size your buffer with a
+/// conservative estimate for the decoded length of an input: 3 bytes of output for every 4 bytes of
+/// input, rounded up, or in other words `(input_len + 3) / 4 * 3`.
+///
+/// If the slice is not large enough, this will panic.
+pub fn decode_config_slice<T: AsRef<[u8]>>(
+    input: T,
+    config: Config,
+    output: &mut [u8],
+) -> Result<usize, DecodeError> {
+    let input_bytes = input.as_ref();
+
+    decode_helper(input_bytes, num_chunks(input_bytes), config, output)
+}
+
+/// Return the number of input chunks (including a possibly partial final chunk) in the input
+fn num_chunks(input: &[u8]) -> usize {
+    input
+        .len()
+        .checked_add(INPUT_CHUNK_LEN - 1)
+        .expect("Overflow when calculating number of chunks in input")
+        / INPUT_CHUNK_LEN
+}
+
+/// Helper to avoid duplicating num_chunks calculation, which is costly on short inputs.
+/// Returns the number of bytes written, or an error.
+// We're on the fragile edge of compiler heuristics here. If this is not inlined, slow. If this is
+// inlined(always), a different slow. plain ol' inline makes the benchmarks happiest at the moment,
+// but this is fragile and the best setting changes with only minor code modifications.
+#[inline]
+fn decode_helper(
+    input: &[u8],
+    num_chunks: usize,
+    config: Config,
+    output: &mut [u8],
+) -> Result<usize, DecodeError> {
+    let char_set = config.char_set;
+    let decode_table = char_set.decode_table();
+
+    let remainder_len = input.len() % INPUT_CHUNK_LEN;
+
+    // Because the fast decode loop writes in groups of 8 bytes (unrolled to
+    // CHUNKS_PER_FAST_LOOP_BLOCK times 8 bytes, where possible) and outputs 8 bytes at a time (of
+    // which only 6 are valid data), we need to be sure that we stop using the fast decode loop
+    // soon enough that there will always be 2 more bytes of valid data written after that loop.
+    let trailing_bytes_to_skip = match remainder_len {
+        // if input is a multiple of the chunk size, ignore the last chunk as it may have padding,
+        // and the fast decode logic cannot handle padding
+        0 => INPUT_CHUNK_LEN,
+        // 1 and 5 trailing bytes are illegal: can't decode 6 bits of input into a byte
+        1 | 5 => {
+            // trailing whitespace is so common that it's worth it to check the last byte to
+            // possibly return a better error message
+            if let Some(b) = input.last() {
+                if *b != PAD_BYTE && decode_table[*b as usize] == tables::INVALID_VALUE {
+                    return Err(DecodeError::InvalidByte(input.len() - 1, *b));
+                }
+            }
+
+            return Err(DecodeError::InvalidLength);
+        }
+        // This will decode to one output byte, which isn't enough to overwrite the 2 extra bytes
+        // written by the fast decode loop. So, we have to ignore both these 2 bytes and the
+        // previous chunk.
+        2 => INPUT_CHUNK_LEN + 2,
+        // If this is 3 unpadded chars, then it would actually decode to 2 bytes. However, if this
+        // is an erroneous 2 chars + 1 pad char that would decode to 1 byte, then it should fail
+        // with an error, not panic from going past the bounds of the output slice, so we let it
+        // use stage 3 + 4.
+        3 => INPUT_CHUNK_LEN + 3,
+        // This can also decode to one output byte because it may be 2 input chars + 2 padding
+        // chars, which would decode to 1 byte.
+        4 => INPUT_CHUNK_LEN + 4,
+        // Everything else is a legal decode len (given that we don't require padding), and will
+        // decode to at least 2 bytes of output.
+        _ => remainder_len,
+    };
+
+    // rounded up to include partial chunks
+    let mut remaining_chunks = num_chunks;
+
+    let mut input_index = 0;
+    let mut output_index = 0;
+
+    {
+        let length_of_fast_decode_chunks = input.len().saturating_sub(trailing_bytes_to_skip);
+
+        // Fast loop, stage 1
+        // manual unroll to CHUNKS_PER_FAST_LOOP_BLOCK of u64s to amortize slice bounds checks
+        if let Some(max_start_index) = length_of_fast_decode_chunks.checked_sub(INPUT_BLOCK_LEN) {
+            while input_index <= max_start_index {
+                let input_slice = &input[input_index..(input_index + INPUT_BLOCK_LEN)];
+                let output_slice = &mut output[output_index..(output_index + DECODED_BLOCK_LEN)];
+
+                decode_chunk(
+                    &input_slice[0..],
+                    input_index,
+                    decode_table,
+                    &mut output_slice[0..],
+                )?;
+                decode_chunk(
+                    &input_slice[8..],
+                    input_index + 8,
+                    decode_table,
+                    &mut output_slice[6..],
+                )?;
+                decode_chunk(
+                    &input_slice[16..],
+                    input_index + 16,
+                    decode_table,
+                    &mut output_slice[12..],
+                )?;
+                decode_chunk(
+                    &input_slice[24..],
+                    input_index + 24,
+                    decode_table,
+                    &mut output_slice[18..],
+                )?;
+
+                input_index += INPUT_BLOCK_LEN;
+                output_index += DECODED_BLOCK_LEN - DECODED_CHUNK_SUFFIX;
+                remaining_chunks -= CHUNKS_PER_FAST_LOOP_BLOCK;
+            }
+        }
+
+        // Fast loop, stage 2 (aka still pretty fast loop)
+        // 8 bytes at a time for whatever we didn't do in stage 1.
+        if let Some(max_start_index) = length_of_fast_decode_chunks.checked_sub(INPUT_CHUNK_LEN) {
+            while input_index < max_start_index {
+                decode_chunk(
+                    &input[input_index..(input_index + INPUT_CHUNK_LEN)],
+                    input_index,
+                    decode_table,
+                    &mut output
+                        [output_index..(output_index + DECODED_CHUNK_LEN + DECODED_CHUNK_SUFFIX)],
+                )?;
+
+                output_index += DECODED_CHUNK_LEN;
+                input_index += INPUT_CHUNK_LEN;
+                remaining_chunks -= 1;
+            }
+        }
+    }
+
+    // Stage 3
+    // If input length was such that a chunk had to be deferred until after the fast loop
+    // because decoding it would have produced 2 trailing bytes that wouldn't then be
+    // overwritten, we decode that chunk here. This way is slower but doesn't write the 2
+    // trailing bytes.
+    // However, we still need to avoid the last chunk (partial or complete) because it could
+    // have padding, so we always do 1 fewer to avoid the last chunk.
+    for _ in 1..remaining_chunks {
+        decode_chunk_precise(
+            &input[input_index..],
+            input_index,
+            decode_table,
+            &mut output[output_index..(output_index + DECODED_CHUNK_LEN)],
+        )?;
+
+        input_index += INPUT_CHUNK_LEN;
+        output_index += DECODED_CHUNK_LEN;
+    }
+
+    // always have one more (possibly partial) block of 8 input
+    debug_assert!(input.len() - input_index > 1 || input.is_empty());
+    debug_assert!(input.len() - input_index <= 8);
+
+    // Stage 4
+    // Finally, decode any leftovers that aren't a complete input block of 8 bytes.
+    // Use a u64 as a stack-resident 8 byte buffer.
+    let mut leftover_bits: u64 = 0;
+    let mut morsels_in_leftover = 0;
+    let mut padding_bytes = 0;
+    let mut first_padding_index: usize = 0;
+    let mut last_symbol = 0_u8;
+    let start_of_leftovers = input_index;
+    for (i, b) in input[start_of_leftovers..].iter().enumerate() {
+        // '=' padding
+        if *b == PAD_BYTE {
+            // There can be bad padding in a few ways:
+            // 1 - Padding with non-padding characters after it
+            // 2 - Padding after zero or one non-padding characters before it
+            //     in the current quad.
+            // 3 - More than two characters of padding. If 3 or 4 padding chars
+            //     are in the same quad, that implies it will be caught by #2.
+            //     If it spreads from one quad to another, it will be caught by
+            //     #2 in the second quad.
+
+            if i % 4 < 2 {
+                // Check for case #2.
+                let bad_padding_index = start_of_leftovers
+                    + if padding_bytes > 0 {
+                        // If we've already seen padding, report the first padding index.
+                        // This is to be consistent with the faster logic above: it will report an
+                        // error on the first padding character (since it doesn't expect to see
+                        // anything but actual encoded data).
+                        first_padding_index
+                    } else {
+                        // haven't seen padding before, just use where we are now
+                        i
+                    };
+                return Err(DecodeError::InvalidByte(bad_padding_index, *b));
+            }
+
+            if padding_bytes == 0 {
+                first_padding_index = i;
+            }
+
+            padding_bytes += 1;
+            continue;
+        }
+
+        // Check for case #1.
+        // To make '=' handling consistent with the main loop, don't allow
+        // non-suffix '=' in trailing chunk either. Report error as first
+        // erroneous padding.
+        if padding_bytes > 0 {
+            return Err(DecodeError::InvalidByte(
+                start_of_leftovers + first_padding_index,
+                PAD_BYTE,
+            ));
+        }
+        last_symbol = *b;
+
+        // can use up to 8 * 6 = 48 bits of the u64, if last chunk has no padding.
+        // To minimize shifts, pack the leftovers from left to right.
+        let shift = 64 - (morsels_in_leftover + 1) * 6;
+        // tables are all 256 elements, lookup with a u8 index always succeeds
+        let morsel = decode_table[*b as usize];
+        if morsel == tables::INVALID_VALUE {
+            return Err(DecodeError::InvalidByte(start_of_leftovers + i, *b));
+        }
+
+        leftover_bits |= (morsel as u64) << shift;
+        morsels_in_leftover += 1;
+    }
+
+    let leftover_bits_ready_to_append = match morsels_in_leftover {
+        0 => 0,
+        2 => 8,
+        3 => 16,
+        4 => 24,
+        6 => 32,
+        7 => 40,
+        8 => 48,
+        _ => unreachable!(
+            "Impossible: must only have 0 to 8 input bytes in last chunk, with no invalid lengths"
+        ),
+    };
+
+    // if there are bits set outside the bits we care about, last symbol encodes trailing bits that
+    // will not be included in the output
+    let mask = !0 >> leftover_bits_ready_to_append;
+    if !config.decode_allow_trailing_bits && (leftover_bits & mask) != 0 {
+        // last morsel is at `morsels_in_leftover` - 1
+        return Err(DecodeError::InvalidLastSymbol(
+            start_of_leftovers + morsels_in_leftover - 1,
+            last_symbol,
+        ));
+    }
+
+    let mut leftover_bits_appended_to_buf = 0;
+    while leftover_bits_appended_to_buf < leftover_bits_ready_to_append {
+        // `as` simply truncates the higher bits, which is what we want here
+        let selected_bits = (leftover_bits >> (56 - leftover_bits_appended_to_buf)) as u8;
+        output[output_index] = selected_bits;
+        output_index += 1;
+
+        leftover_bits_appended_to_buf += 8;
+    }
+
+    Ok(output_index)
+}
+
+#[inline]
+fn write_u64(output: &mut [u8], value: u64) {
+    output[..8].copy_from_slice(&value.to_be_bytes());
+}
+
+/// Decode 8 bytes of input into 6 bytes of output. 8 bytes of output will be written, but only the
+/// first 6 of those contain meaningful data.
+///
+/// `input` is the bytes to decode, of which the first 8 bytes will be processed.
+/// `index_at_start_of_input` is the offset in the overall input (used for reporting errors
+/// accurately)
+/// `decode_table` is the lookup table for the particular base64 alphabet.
+/// `output` will have its first 8 bytes overwritten, of which only the first 6 are valid decoded
+/// data.
+// yes, really inline (worth 30-50% speedup)
+#[inline(always)]
+fn decode_chunk(
+    input: &[u8],
+    index_at_start_of_input: usize,
+    decode_table: &[u8; 256],
+    output: &mut [u8],
+) -> Result<(), DecodeError> {
+    let mut accum: u64;
+
+    let morsel = decode_table[input[0] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(index_at_start_of_input, input[0]));
+    }
+    accum = (morsel as u64) << 58;
+
+    let morsel = decode_table[input[1] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 1,
+            input[1],
+        ));
+    }
+    accum |= (morsel as u64) << 52;
+
+    let morsel = decode_table[input[2] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 2,
+            input[2],
+        ));
+    }
+    accum |= (morsel as u64) << 46;
+
+    let morsel = decode_table[input[3] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 3,
+            input[3],
+        ));
+    }
+    accum |= (morsel as u64) << 40;
+
+    let morsel = decode_table[input[4] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 4,
+            input[4],
+        ));
+    }
+    accum |= (morsel as u64) << 34;
+
+    let morsel = decode_table[input[5] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 5,
+            input[5],
+        ));
+    }
+    accum |= (morsel as u64) << 28;
+
+    let morsel = decode_table[input[6] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 6,
+            input[6],
+        ));
+    }
+    accum |= (morsel as u64) << 22;
+
+    let morsel = decode_table[input[7] as usize];
+    if morsel == tables::INVALID_VALUE {
+        return Err(DecodeError::InvalidByte(
+            index_at_start_of_input + 7,
+            input[7],
+        ));
+    }
+    accum |= (morsel as u64) << 16;
+
+    write_u64(output, accum);
+
+    Ok(())
+}
+
+/// Decode an 8-byte chunk, but only write the 6 bytes actually decoded instead of including 2
+/// trailing garbage bytes.
+#[inline]
+fn decode_chunk_precise(
+    input: &[u8],
+    index_at_start_of_input: usize,
+    decode_table: &[u8; 256],
+    output: &mut [u8],
+) -> Result<(), DecodeError> {
+    let mut tmp_buf = [0_u8; 8];
+
+    decode_chunk(
+        input,
+        index_at_start_of_input,
+        decode_table,
+        &mut tmp_buf[..],
+    )?;
+
+    output[0..6].copy_from_slice(&tmp_buf[0..6]);
+
+    Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        encode::encode_config_buf,
+        encode::encode_config_slice,
+        tests::{assert_encode_sanity, random_config},
+    };
+
+    use rand::{
+        distributions::{Distribution, Uniform},
+        FromEntropy, Rng,
+    };
+
+    #[test]
+    fn decode_chunk_precise_writes_only_6_bytes() {
+        let input = b"Zm9vYmFy"; // "foobar"
+        let mut output = [0_u8, 1, 2, 3, 4, 5, 6, 7];
+        decode_chunk_precise(&input[..], 0, tables::STANDARD_DECODE, &mut output).unwrap();
+        assert_eq!(&vec![b'f', b'o', b'o', b'b', b'a', b'r', 6, 7], &output);
+    }
+
+    #[test]
+    fn decode_chunk_writes_8_bytes() {
+        let input = b"Zm9vYmFy"; // "foobar"
+        let mut output = [0_u8, 1, 2, 3, 4, 5, 6, 7];
+        decode_chunk(&input[..], 0, tables::STANDARD_DECODE, &mut output).unwrap();
+        assert_eq!(&vec![b'f', b'o', b'o', b'b', b'a', b'r', 0, 0], &output);
+    }
+
+    #[test]
+    fn decode_into_nonempty_vec_doesnt_clobber_existing_prefix() {
+        let mut orig_data = Vec::new();
+        let mut encoded_data = String::new();
+        let mut decoded_with_prefix = Vec::new();
+        let mut decoded_without_prefix = Vec::new();
+        let mut prefix = Vec::new();
+
+        let prefix_len_range = Uniform::new(0, 1000);
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            orig_data.clear();
+            encoded_data.clear();
+            decoded_with_prefix.clear();
+            decoded_without_prefix.clear();
+            prefix.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                orig_data.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+            encode_config_buf(&orig_data, config, &mut encoded_data);
+            assert_encode_sanity(&encoded_data, config, input_len);
+
+            let prefix_len = prefix_len_range.sample(&mut rng);
+
+            // fill the buf with a prefix
+            for _ in 0..prefix_len {
+                prefix.push(rng.gen());
+            }
+
+            decoded_with_prefix.resize(prefix_len, 0);
+            decoded_with_prefix.copy_from_slice(&prefix);
+
+            // decode into the non-empty buf
+            decode_config_buf(&encoded_data, config, &mut decoded_with_prefix).unwrap();
+            // also decode into the empty buf
+            decode_config_buf(&encoded_data, config, &mut decoded_without_prefix).unwrap();
+
+            assert_eq!(
+                prefix_len + decoded_without_prefix.len(),
+                decoded_with_prefix.len()
+            );
+            assert_eq!(orig_data, decoded_without_prefix);
+
+            // append plain decode onto prefix
+            prefix.append(&mut decoded_without_prefix);
+
+            assert_eq!(prefix, decoded_with_prefix);
+        }
+    }
+
+    #[test]
+    fn decode_into_slice_doesnt_clobber_existing_prefix_or_suffix() {
+        let mut orig_data = Vec::new();
+        let mut encoded_data = String::new();
+        let mut decode_buf = Vec::new();
+        let mut decode_buf_copy: Vec<u8> = Vec::new();
+
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            orig_data.clear();
+            encoded_data.clear();
+            decode_buf.clear();
+            decode_buf_copy.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                orig_data.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+            encode_config_buf(&orig_data, config, &mut encoded_data);
+            assert_encode_sanity(&encoded_data, config, input_len);
+
+            // fill the buffer with random garbage, long enough to have some room before and after
+            for _ in 0..5000 {
+                decode_buf.push(rng.gen());
+            }
+
+            // keep a copy for later comparison
+            decode_buf_copy.extend(decode_buf.iter());
+
+            let offset = 1000;
+
+            // decode into the non-empty buf
+            let decode_bytes_written =
+                decode_config_slice(&encoded_data, config, &mut decode_buf[offset..]).unwrap();
+
+            assert_eq!(orig_data.len(), decode_bytes_written);
+            assert_eq!(
+                orig_data,
+                &decode_buf[offset..(offset + decode_bytes_written)]
+            );
+            assert_eq!(&decode_buf_copy[0..offset], &decode_buf[0..offset]);
+            assert_eq!(
+                &decode_buf_copy[offset + decode_bytes_written..],
+                &decode_buf[offset + decode_bytes_written..]
+            );
+        }
+    }
+
+    #[test]
+    fn decode_into_slice_fits_in_precisely_sized_slice() {
+        let mut orig_data = Vec::new();
+        let mut encoded_data = String::new();
+        let mut decode_buf = Vec::new();
+
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            orig_data.clear();
+            encoded_data.clear();
+            decode_buf.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                orig_data.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+            encode_config_buf(&orig_data, config, &mut encoded_data);
+            assert_encode_sanity(&encoded_data, config, input_len);
+
+            decode_buf.resize(input_len, 0);
+
+            // decode into the non-empty buf
+            let decode_bytes_written =
+                decode_config_slice(&encoded_data, config, &mut decode_buf[..]).unwrap();
+
+            assert_eq!(orig_data.len(), decode_bytes_written);
+            assert_eq!(orig_data, decode_buf);
+        }
+    }
+
+    #[test]
+    fn detect_invalid_last_symbol_two_bytes() {
+        let decode =
+            |input, forgiving| decode_config(input, STANDARD.decode_allow_trailing_bits(forgiving));
+
+        // example from https://github.com/marshallpierce/rust-base64/issues/75
+        assert!(decode("iYU=", false).is_ok());
+        // trailing 01
+        assert_eq!(
+            Err(DecodeError::InvalidLastSymbol(2, b'V')),
+            decode("iYV=", false)
+        );
+        assert_eq!(Ok(vec![137, 133]), decode("iYV=", true));
+        // trailing 10
+        assert_eq!(
+            Err(DecodeError::InvalidLastSymbol(2, b'W')),
+            decode("iYW=", false)
+        );
+        assert_eq!(Ok(vec![137, 133]), decode("iYV=", true));
+        // trailing 11
+        assert_eq!(
+            Err(DecodeError::InvalidLastSymbol(2, b'X')),
+            decode("iYX=", false)
+        );
+        assert_eq!(Ok(vec![137, 133]), decode("iYV=", true));
+
+        // also works when there are 2 quads in the last block
+        assert_eq!(
+            Err(DecodeError::InvalidLastSymbol(6, b'X')),
+            decode("AAAAiYX=", false)
+        );
+        assert_eq!(Ok(vec![0, 0, 0, 137, 133]), decode("AAAAiYX=", true));
+    }
+
+    #[test]
+    fn detect_invalid_last_symbol_one_byte() {
+        // 0xFF -> "/w==", so all letters > w, 0-9, and '+', '/' should get InvalidLastSymbol
+
+        assert!(decode("/w==").is_ok());
+        // trailing 01
+        assert_eq!(Err(DecodeError::InvalidLastSymbol(1, b'x')), decode("/x=="));
+        assert_eq!(Err(DecodeError::InvalidLastSymbol(1, b'z')), decode("/z=="));
+        assert_eq!(Err(DecodeError::InvalidLastSymbol(1, b'0')), decode("/0=="));
+        assert_eq!(Err(DecodeError::InvalidLastSymbol(1, b'9')), decode("/9=="));
+        assert_eq!(Err(DecodeError::InvalidLastSymbol(1, b'+')), decode("/+=="));
+        assert_eq!(Err(DecodeError::InvalidLastSymbol(1, b'/')), decode("//=="));
+
+        // also works when there are 2 quads in the last block
+        assert_eq!(
+            Err(DecodeError::InvalidLastSymbol(5, b'x')),
+            decode("AAAA/x==")
+        );
+    }
+
+    #[test]
+    fn detect_invalid_last_symbol_every_possible_three_symbols() {
+        let mut base64_to_bytes = ::std::collections::HashMap::new();
+
+        let mut bytes = [0_u8; 2];
+        for b1 in 0_u16..256 {
+            bytes[0] = b1 as u8;
+            for b2 in 0_u16..256 {
+                bytes[1] = b2 as u8;
+                let mut b64 = vec![0_u8; 4];
+                assert_eq!(4, encode_config_slice(&bytes, STANDARD, &mut b64[..]));
+                let mut v = ::std::vec::Vec::with_capacity(2);
+                v.extend_from_slice(&bytes[..]);
+
+                assert!(base64_to_bytes.insert(b64, v).is_none());
+            }
+        }
+
+        // every possible combination of symbols must either decode to 2 bytes or get InvalidLastSymbol
+
+        let mut symbols = [0_u8; 4];
+        for &s1 in STANDARD.char_set.encode_table().iter() {
+            symbols[0] = s1;
+            for &s2 in STANDARD.char_set.encode_table().iter() {
+                symbols[1] = s2;
+                for &s3 in STANDARD.char_set.encode_table().iter() {
+                    symbols[2] = s3;
+                    symbols[3] = PAD_BYTE;
+
+                    match base64_to_bytes.get(&symbols[..]) {
+                        Some(bytes) => {
+                            assert_eq!(Ok(bytes.to_vec()), decode_config(&symbols, STANDARD))
+                        }
+                        None => assert_eq!(
+                            Err(DecodeError::InvalidLastSymbol(2, s3)),
+                            decode_config(&symbols[..], STANDARD)
+                        ),
+                    }
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn detect_invalid_last_symbol_every_possible_two_symbols() {
+        let mut base64_to_bytes = ::std::collections::HashMap::new();
+
+        for b in 0_u16..256 {
+            let mut b64 = vec![0_u8; 4];
+            assert_eq!(4, encode_config_slice(&[b as u8], STANDARD, &mut b64[..]));
+            let mut v = ::std::vec::Vec::with_capacity(1);
+            v.push(b as u8);
+
+            assert!(base64_to_bytes.insert(b64, v).is_none());
+        }
+
+        // every possible combination of symbols must either decode to 1 byte or get InvalidLastSymbol
+
+        let mut symbols = [0_u8; 4];
+        for &s1 in STANDARD.char_set.encode_table().iter() {
+            symbols[0] = s1;
+            for &s2 in STANDARD.char_set.encode_table().iter() {
+                symbols[1] = s2;
+                symbols[2] = PAD_BYTE;
+                symbols[3] = PAD_BYTE;
+
+                match base64_to_bytes.get(&symbols[..]) {
+                    Some(bytes) => {
+                        assert_eq!(Ok(bytes.to_vec()), decode_config(&symbols, STANDARD))
+                    }
+                    None => assert_eq!(
+                        Err(DecodeError::InvalidLastSymbol(1, s2)),
+                        decode_config(&symbols[..], STANDARD)
+                    ),
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn decode_config_estimation_works_for_various_lengths() {
+        for num_prefix_quads in 0..100 {
+            for suffix in &["AA", "AAA", "AAAA"] {
+                let mut prefix = "AAAA".repeat(num_prefix_quads);
+                prefix.push_str(suffix);
+                // make sure no overflow (and thus a panic) occurs
+                let res = decode_config(prefix, STANDARD);
+                assert!(res.is_ok());
+            }
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/display.rs cargo-0.66.0+ds1/vendor/base64/src/display.rs
--- cargo-0.66.0/vendor/base64/src/display.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/display.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,88 @@
+//! Enables base64'd output anywhere you might use a `Display` implementation, like a format string.
+//!
+//! ```
+//! use base64::display::Base64Display;
+//!
+//! let data = vec![0x0, 0x1, 0x2, 0x3];
+//! let wrapper = Base64Display::with_config(&data, base64::STANDARD);
+//!
+//! assert_eq!("base64: AAECAw==", format!("base64: {}", wrapper));
+//! ```
+
+use super::chunked_encoder::ChunkedEncoder;
+use super::Config;
+use core::fmt::{Display, Formatter};
+use core::{fmt, str};
+
+/// A convenience wrapper for base64'ing bytes into a format string without heap allocation.
+pub struct Base64Display<'a> {
+    bytes: &'a [u8],
+    chunked_encoder: ChunkedEncoder,
+}
+
+impl<'a> Base64Display<'a> {
+    /// Create a `Base64Display` with the provided config.
+    pub fn with_config(bytes: &[u8], config: Config) -> Base64Display {
+        Base64Display {
+            bytes,
+            chunked_encoder: ChunkedEncoder::new(config),
+        }
+    }
+}
+
+impl<'a> Display for Base64Display<'a> {
+    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
+        let mut sink = FormatterSink { f: formatter };
+        self.chunked_encoder.encode(self.bytes, &mut sink)
+    }
+}
+
+struct FormatterSink<'a, 'b: 'a> {
+    f: &'a mut Formatter<'b>,
+}
+
+impl<'a, 'b: 'a> super::chunked_encoder::Sink for FormatterSink<'a, 'b> {
+    type Error = fmt::Error;
+
+    fn write_encoded_bytes(&mut self, encoded: &[u8]) -> Result<(), Self::Error> {
+        // Avoid unsafe. If max performance is needed, write your own display wrapper that uses
+        // unsafe here to gain about 10-15%.
+        self.f
+            .write_str(str::from_utf8(encoded).expect("base64 data was not utf8"))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::chunked_encoder::tests::{
+        chunked_encode_matches_normal_encode_random, SinkTestHelper,
+    };
+    use super::super::*;
+    use super::*;
+
+    #[test]
+    fn basic_display() {
+        assert_eq!(
+            "~$Zm9vYmFy#*",
+            format!("~${}#*", Base64Display::with_config(b"foobar", STANDARD))
+        );
+        assert_eq!(
+            "~$Zm9vYmFyZg==#*",
+            format!("~${}#*", Base64Display::with_config(b"foobarf", STANDARD))
+        );
+    }
+
+    #[test]
+    fn display_encode_matches_normal_encode() {
+        let helper = DisplaySinkTestHelper;
+        chunked_encode_matches_normal_encode_random(&helper);
+    }
+
+    struct DisplaySinkTestHelper;
+
+    impl SinkTestHelper for DisplaySinkTestHelper {
+        fn encode_to_string(&self, config: Config, bytes: &[u8]) -> String {
+            format!("{}", Base64Display::with_config(bytes, config))
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/encode.rs cargo-0.66.0+ds1/vendor/base64/src/encode.rs
--- cargo-0.66.0/vendor/base64/src/encode.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/encode.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,675 @@
+use crate::{Config, PAD_BYTE};
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use crate::{chunked_encoder, STANDARD};
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use alloc::{string::String, vec};
+use core::convert::TryInto;
+
+///Encode arbitrary octets as base64.
+///Returns a String.
+///Convenience for `encode_config(input, base64::STANDARD);`.
+///
+///# Example
+///
+///```rust
+///extern crate base64;
+///
+///fn main() {
+///    let b64 = base64::encode(b"hello world");
+///    println!("{}", b64);
+///}
+///```
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub fn encode<T: AsRef<[u8]>>(input: T) -> String {
+    encode_config(input, STANDARD)
+}
+
+///Encode arbitrary octets as base64.
+///Returns a String.
+///
+///# Example
+///
+///```rust
+///extern crate base64;
+///
+///fn main() {
+///    let b64 = base64::encode_config(b"hello world~", base64::STANDARD);
+///    println!("{}", b64);
+///
+///    let b64_url = base64::encode_config(b"hello internet~", base64::URL_SAFE);
+///    println!("{}", b64_url);
+///}
+///```
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub fn encode_config<T: AsRef<[u8]>>(input: T, config: Config) -> String {
+    let mut buf = match encoded_size(input.as_ref().len(), config) {
+        Some(n) => vec![0; n],
+        None => panic!("integer overflow when calculating buffer size"),
+    };
+
+    encode_with_padding(input.as_ref(), config, buf.len(), &mut buf[..]);
+
+    String::from_utf8(buf).expect("Invalid UTF8")
+}
+
+///Encode arbitrary octets as base64.
+///Writes into the supplied output buffer, which will grow the buffer if needed.
+///
+///# Example
+///
+///```rust
+///extern crate base64;
+///
+///fn main() {
+///    let mut buf = String::new();
+///    base64::encode_config_buf(b"hello world~", base64::STANDARD, &mut buf);
+///    println!("{}", buf);
+///
+///    buf.clear();
+///    base64::encode_config_buf(b"hello internet~", base64::URL_SAFE, &mut buf);
+///    println!("{}", buf);
+///}
+///```
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub fn encode_config_buf<T: AsRef<[u8]>>(input: T, config: Config, buf: &mut String) {
+    let input_bytes = input.as_ref();
+
+    {
+        let mut sink = chunked_encoder::StringSink::new(buf);
+        let encoder = chunked_encoder::ChunkedEncoder::new(config);
+
+        encoder
+            .encode(input_bytes, &mut sink)
+            .expect("Writing to a String shouldn't fail")
+    }
+}
+
+/// Encode arbitrary octets as base64.
+/// Writes into the supplied output buffer.
+///
+/// This is useful if you wish to avoid allocation entirely (e.g. encoding into a stack-resident
+/// or statically-allocated buffer).
+///
+/// # Panics
+///
+/// If `output` is too small to hold the encoded version of `input`, a panic will result.
+///
+/// # Example
+///
+/// ```rust
+/// extern crate base64;
+///
+/// fn main() {
+///     let s = b"hello internet!";
+///     let mut buf = Vec::new();
+///     // make sure we'll have a slice big enough for base64 + padding
+///     buf.resize(s.len() * 4 / 3 + 4, 0);
+///
+///     let bytes_written = base64::encode_config_slice(s,
+///                             base64::STANDARD, &mut buf);
+///
+///     // shorten our vec down to just what was written
+///     buf.resize(bytes_written, 0);
+///
+///     assert_eq!(s, base64::decode(&buf).unwrap().as_slice());
+/// }
+/// ```
+pub fn encode_config_slice<T: AsRef<[u8]>>(input: T, config: Config, output: &mut [u8]) -> usize {
+    let input_bytes = input.as_ref();
+
+    let encoded_size = encoded_size(input_bytes.len(), config)
+        .expect("usize overflow when calculating buffer size");
+
+    let mut b64_output = &mut output[0..encoded_size];
+
+    encode_with_padding(&input_bytes, config, encoded_size, &mut b64_output);
+
+    encoded_size
+}
+
+/// B64-encode and pad (if configured).
+///
+/// This helper exists to avoid recalculating encoded_size, which is relatively expensive on short
+/// inputs.
+///
+/// `encoded_size` is the encoded size calculated for `input`.
+///
+/// `output` must be of size `encoded_size`.
+///
+/// All bytes in `output` will be written to since it is exactly the size of the output.
+fn encode_with_padding(input: &[u8], config: Config, encoded_size: usize, output: &mut [u8]) {
+    debug_assert_eq!(encoded_size, output.len());
+
+    let b64_bytes_written = encode_to_slice(input, output, config.char_set.encode_table());
+
+    let padding_bytes = if config.pad {
+        add_padding(input.len(), &mut output[b64_bytes_written..])
+    } else {
+        0
+    };
+
+    let encoded_bytes = b64_bytes_written
+        .checked_add(padding_bytes)
+        .expect("usize overflow when calculating b64 length");
+
+    debug_assert_eq!(encoded_size, encoded_bytes);
+}
+
+#[inline]
+fn read_u64(s: &[u8]) -> u64 {
+    u64::from_be_bytes(s[..8].try_into().unwrap())
+}
+
+/// Encode input bytes to utf8 base64 bytes. Does not pad.
+/// `output` must be long enough to hold the encoded `input` without padding.
+/// Returns the number of bytes written.
+#[inline]
+pub fn encode_to_slice(input: &[u8], output: &mut [u8], encode_table: &[u8; 64]) -> usize {
+    let mut input_index: usize = 0;
+
+    const BLOCKS_PER_FAST_LOOP: usize = 4;
+    const LOW_SIX_BITS: u64 = 0x3F;
+
+    // we read 8 bytes at a time (u64) but only actually consume 6 of those bytes. Thus, we need
+    // 2 trailing bytes to be available to read..
+    let last_fast_index = input.len().saturating_sub(BLOCKS_PER_FAST_LOOP * 6 + 2);
+    let mut output_index = 0;
+
+    if last_fast_index > 0 {
+        while input_index <= last_fast_index {
+            // Major performance wins from letting the optimizer do the bounds check once, mostly
+            // on the output side
+            let input_chunk = &input[input_index..(input_index + (BLOCKS_PER_FAST_LOOP * 6 + 2))];
+            let output_chunk = &mut output[output_index..(output_index + BLOCKS_PER_FAST_LOOP * 8)];
+
+            // Hand-unrolling for 32 vs 16 or 8 bytes produces yields performance about equivalent
+            // to unsafe pointer code on a Xeon E5-1650v3. 64 byte unrolling was slightly better for
+            // large inputs but significantly worse for 50-byte input, unsurprisingly. I suspect
+            // that it's a not uncommon use case to encode smallish chunks of data (e.g. a 64-byte
+            // SHA-512 digest), so it would be nice if that fit in the unrolled loop at least once.
+            // Plus, single-digit percentage performance differences might well be quite different
+            // on different hardware.
+
+            let input_u64 = read_u64(&input_chunk[0..]);
+
+            output_chunk[0] = encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize];
+            output_chunk[1] = encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize];
+            output_chunk[2] = encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize];
+            output_chunk[3] = encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize];
+            output_chunk[4] = encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize];
+            output_chunk[5] = encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize];
+            output_chunk[6] = encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize];
+            output_chunk[7] = encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize];
+
+            let input_u64 = read_u64(&input_chunk[6..]);
+
+            output_chunk[8] = encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize];
+            output_chunk[9] = encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize];
+            output_chunk[10] = encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize];
+            output_chunk[11] = encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize];
+            output_chunk[12] = encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize];
+            output_chunk[13] = encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize];
+            output_chunk[14] = encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize];
+            output_chunk[15] = encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize];
+
+            let input_u64 = read_u64(&input_chunk[12..]);
+
+            output_chunk[16] = encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize];
+            output_chunk[17] = encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize];
+            output_chunk[18] = encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize];
+            output_chunk[19] = encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize];
+            output_chunk[20] = encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize];
+            output_chunk[21] = encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize];
+            output_chunk[22] = encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize];
+            output_chunk[23] = encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize];
+
+            let input_u64 = read_u64(&input_chunk[18..]);
+
+            output_chunk[24] = encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize];
+            output_chunk[25] = encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize];
+            output_chunk[26] = encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize];
+            output_chunk[27] = encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize];
+            output_chunk[28] = encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize];
+            output_chunk[29] = encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize];
+            output_chunk[30] = encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize];
+            output_chunk[31] = encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize];
+
+            output_index += BLOCKS_PER_FAST_LOOP * 8;
+            input_index += BLOCKS_PER_FAST_LOOP * 6;
+        }
+    }
+
+    // Encode what's left after the fast loop.
+
+    const LOW_SIX_BITS_U8: u8 = 0x3F;
+
+    let rem = input.len() % 3;
+    let start_of_rem = input.len() - rem;
+
+    // start at the first index not handled by fast loop, which may be 0.
+
+    while input_index < start_of_rem {
+        let input_chunk = &input[input_index..(input_index + 3)];
+        let output_chunk = &mut output[output_index..(output_index + 4)];
+
+        output_chunk[0] = encode_table[(input_chunk[0] >> 2) as usize];
+        output_chunk[1] =
+            encode_table[((input_chunk[0] << 4 | input_chunk[1] >> 4) & LOW_SIX_BITS_U8) as usize];
+        output_chunk[2] =
+            encode_table[((input_chunk[1] << 2 | input_chunk[2] >> 6) & LOW_SIX_BITS_U8) as usize];
+        output_chunk[3] = encode_table[(input_chunk[2] & LOW_SIX_BITS_U8) as usize];
+
+        input_index += 3;
+        output_index += 4;
+    }
+
+    if rem == 2 {
+        output[output_index] = encode_table[(input[start_of_rem] >> 2) as usize];
+        output[output_index + 1] = encode_table[((input[start_of_rem] << 4
+            | input[start_of_rem + 1] >> 4)
+            & LOW_SIX_BITS_U8) as usize];
+        output[output_index + 2] =
+            encode_table[((input[start_of_rem + 1] << 2) & LOW_SIX_BITS_U8) as usize];
+        output_index += 3;
+    } else if rem == 1 {
+        output[output_index] = encode_table[(input[start_of_rem] >> 2) as usize];
+        output[output_index + 1] =
+            encode_table[((input[start_of_rem] << 4) & LOW_SIX_BITS_U8) as usize];
+        output_index += 2;
+    }
+
+    output_index
+}
+
+/// calculate the base64 encoded string size, including padding if appropriate
+pub fn encoded_size(bytes_len: usize, config: Config) -> Option<usize> {
+    let rem = bytes_len % 3;
+
+    let complete_input_chunks = bytes_len / 3;
+    let complete_chunk_output = complete_input_chunks.checked_mul(4);
+
+    if rem > 0 {
+        if config.pad {
+            complete_chunk_output.and_then(|c| c.checked_add(4))
+        } else {
+            let encoded_rem = match rem {
+                1 => 2,
+                2 => 3,
+                _ => unreachable!("Impossible remainder"),
+            };
+            complete_chunk_output.and_then(|c| c.checked_add(encoded_rem))
+        }
+    } else {
+        complete_chunk_output
+    }
+}
+
+/// Write padding characters.
+/// `output` is the slice where padding should be written, of length at least 2.
+///
+/// Returns the number of padding bytes written.
+pub fn add_padding(input_len: usize, output: &mut [u8]) -> usize {
+    let rem = input_len % 3;
+    let mut bytes_written = 0;
+    for _ in 0..((3 - rem) % 3) {
+        output[bytes_written] = PAD_BYTE;
+        bytes_written += 1;
+    }
+
+    bytes_written
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        decode::decode_config_buf,
+        tests::{assert_encode_sanity, random_config},
+        Config, STANDARD, URL_SAFE_NO_PAD,
+    };
+
+    use rand::{
+        distributions::{Distribution, Uniform},
+        FromEntropy, Rng,
+    };
+    use std;
+    use std::str;
+
+    #[test]
+    fn encoded_size_correct_standard() {
+        assert_encoded_length(0, 0, STANDARD);
+
+        assert_encoded_length(1, 4, STANDARD);
+        assert_encoded_length(2, 4, STANDARD);
+        assert_encoded_length(3, 4, STANDARD);
+
+        assert_encoded_length(4, 8, STANDARD);
+        assert_encoded_length(5, 8, STANDARD);
+        assert_encoded_length(6, 8, STANDARD);
+
+        assert_encoded_length(7, 12, STANDARD);
+        assert_encoded_length(8, 12, STANDARD);
+        assert_encoded_length(9, 12, STANDARD);
+
+        assert_encoded_length(54, 72, STANDARD);
+
+        assert_encoded_length(55, 76, STANDARD);
+        assert_encoded_length(56, 76, STANDARD);
+        assert_encoded_length(57, 76, STANDARD);
+
+        assert_encoded_length(58, 80, STANDARD);
+    }
+
+    #[test]
+    fn encoded_size_correct_no_pad() {
+        assert_encoded_length(0, 0, URL_SAFE_NO_PAD);
+
+        assert_encoded_length(1, 2, URL_SAFE_NO_PAD);
+        assert_encoded_length(2, 3, URL_SAFE_NO_PAD);
+        assert_encoded_length(3, 4, URL_SAFE_NO_PAD);
+
+        assert_encoded_length(4, 6, URL_SAFE_NO_PAD);
+        assert_encoded_length(5, 7, URL_SAFE_NO_PAD);
+        assert_encoded_length(6, 8, URL_SAFE_NO_PAD);
+
+        assert_encoded_length(7, 10, URL_SAFE_NO_PAD);
+        assert_encoded_length(8, 11, URL_SAFE_NO_PAD);
+        assert_encoded_length(9, 12, URL_SAFE_NO_PAD);
+
+        assert_encoded_length(54, 72, URL_SAFE_NO_PAD);
+
+        assert_encoded_length(55, 74, URL_SAFE_NO_PAD);
+        assert_encoded_length(56, 75, URL_SAFE_NO_PAD);
+        assert_encoded_length(57, 76, URL_SAFE_NO_PAD);
+
+        assert_encoded_length(58, 78, URL_SAFE_NO_PAD);
+    }
+
+    #[test]
+    fn encoded_size_overflow() {
+        assert_eq!(None, encoded_size(std::usize::MAX, STANDARD));
+    }
+
+    #[test]
+    fn encode_config_buf_into_nonempty_buffer_doesnt_clobber_prefix() {
+        let mut orig_data = Vec::new();
+        let mut prefix = String::new();
+        let mut encoded_data_no_prefix = String::new();
+        let mut encoded_data_with_prefix = String::new();
+        let mut decoded = Vec::new();
+
+        let prefix_len_range = Uniform::new(0, 1000);
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            orig_data.clear();
+            prefix.clear();
+            encoded_data_no_prefix.clear();
+            encoded_data_with_prefix.clear();
+            decoded.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                orig_data.push(rng.gen());
+            }
+
+            let prefix_len = prefix_len_range.sample(&mut rng);
+            for _ in 0..prefix_len {
+                // getting convenient random single-byte printable chars that aren't base64 is
+                // annoying
+                prefix.push('#');
+            }
+            encoded_data_with_prefix.push_str(&prefix);
+
+            let config = random_config(&mut rng);
+            encode_config_buf(&orig_data, config, &mut encoded_data_no_prefix);
+            encode_config_buf(&orig_data, config, &mut encoded_data_with_prefix);
+
+            assert_eq!(
+                encoded_data_no_prefix.len() + prefix_len,
+                encoded_data_with_prefix.len()
+            );
+            assert_encode_sanity(&encoded_data_no_prefix, config, input_len);
+            assert_encode_sanity(&encoded_data_with_prefix[prefix_len..], config, input_len);
+
+            // append plain encode onto prefix
+            prefix.push_str(&mut encoded_data_no_prefix);
+
+            assert_eq!(prefix, encoded_data_with_prefix);
+
+            decode_config_buf(&encoded_data_no_prefix, config, &mut decoded).unwrap();
+            assert_eq!(orig_data, decoded);
+        }
+    }
+
+    #[test]
+    fn encode_config_slice_into_nonempty_buffer_doesnt_clobber_suffix() {
+        let mut orig_data = Vec::new();
+        let mut encoded_data = Vec::new();
+        let mut encoded_data_original_state = Vec::new();
+        let mut decoded = Vec::new();
+
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            orig_data.clear();
+            encoded_data.clear();
+            encoded_data_original_state.clear();
+            decoded.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                orig_data.push(rng.gen());
+            }
+
+            // plenty of existing garbage in the encoded buffer
+            for _ in 0..10 * input_len {
+                encoded_data.push(rng.gen());
+            }
+
+            encoded_data_original_state.extend_from_slice(&encoded_data);
+
+            let config = random_config(&mut rng);
+
+            let encoded_size = encoded_size(input_len, config).unwrap();
+
+            assert_eq!(
+                encoded_size,
+                encode_config_slice(&orig_data, config, &mut encoded_data)
+            );
+
+            assert_encode_sanity(
+                std::str::from_utf8(&encoded_data[0..encoded_size]).unwrap(),
+                config,
+                input_len,
+            );
+
+            assert_eq!(
+                &encoded_data[encoded_size..],
+                &encoded_data_original_state[encoded_size..]
+            );
+
+            decode_config_buf(&encoded_data[0..encoded_size], config, &mut decoded).unwrap();
+            assert_eq!(orig_data, decoded);
+        }
+    }
+
+    #[test]
+    fn encode_config_slice_fits_into_precisely_sized_slice() {
+        let mut orig_data = Vec::new();
+        let mut encoded_data = Vec::new();
+        let mut decoded = Vec::new();
+
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            orig_data.clear();
+            encoded_data.clear();
+            decoded.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                orig_data.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+
+            let encoded_size = encoded_size(input_len, config).unwrap();
+
+            encoded_data.resize(encoded_size, 0);
+
+            assert_eq!(
+                encoded_size,
+                encode_config_slice(&orig_data, config, &mut encoded_data)
+            );
+
+            assert_encode_sanity(
+                std::str::from_utf8(&encoded_data[0..encoded_size]).unwrap(),
+                config,
+                input_len,
+            );
+
+            decode_config_buf(&encoded_data[0..encoded_size], config, &mut decoded).unwrap();
+            assert_eq!(orig_data, decoded);
+        }
+    }
+
+    #[test]
+    fn encode_to_slice_random_valid_utf8() {
+        let mut input = Vec::new();
+        let mut output = Vec::new();
+
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            input.clear();
+            output.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                input.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+
+            // fill up the output buffer with garbage
+            let encoded_size = encoded_size(input_len, config).unwrap();
+            for _ in 0..encoded_size {
+                output.push(rng.gen());
+            }
+
+            let orig_output_buf = output.to_vec();
+
+            let bytes_written =
+                encode_to_slice(&input, &mut output, config.char_set.encode_table());
+
+            // make sure the part beyond bytes_written is the same garbage it was before
+            assert_eq!(orig_output_buf[bytes_written..], output[bytes_written..]);
+
+            // make sure the encoded bytes are UTF-8
+            let _ = str::from_utf8(&output[0..bytes_written]).unwrap();
+        }
+    }
+
+    #[test]
+    fn encode_with_padding_random_valid_utf8() {
+        let mut input = Vec::new();
+        let mut output = Vec::new();
+
+        let input_len_range = Uniform::new(0, 1000);
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..10_000 {
+            input.clear();
+            output.clear();
+
+            let input_len = input_len_range.sample(&mut rng);
+
+            for _ in 0..input_len {
+                input.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+
+            // fill up the output buffer with garbage
+            let encoded_size = encoded_size(input_len, config).unwrap();
+            for _ in 0..encoded_size + 1000 {
+                output.push(rng.gen());
+            }
+
+            let orig_output_buf = output.to_vec();
+
+            encode_with_padding(&input, config, encoded_size, &mut output[0..encoded_size]);
+
+            // make sure the part beyond b64 is the same garbage it was before
+            assert_eq!(orig_output_buf[encoded_size..], output[encoded_size..]);
+
+            // make sure the encoded bytes are UTF-8
+            let _ = str::from_utf8(&output[0..encoded_size]).unwrap();
+        }
+    }
+
+    #[test]
+    fn add_padding_random_valid_utf8() {
+        let mut output = Vec::new();
+
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        // cover our bases for length % 3
+        for input_len in 0..10 {
+            output.clear();
+
+            // fill output with random
+            for _ in 0..10 {
+                output.push(rng.gen());
+            }
+
+            let orig_output_buf = output.to_vec();
+
+            let bytes_written = add_padding(input_len, &mut output);
+
+            // make sure the part beyond bytes_written is the same garbage it was before
+            assert_eq!(orig_output_buf[bytes_written..], output[bytes_written..]);
+
+            // make sure the encoded bytes are UTF-8
+            let _ = str::from_utf8(&output[0..bytes_written]).unwrap();
+        }
+    }
+
+    fn assert_encoded_length(input_len: usize, encoded_len: usize, config: Config) {
+        assert_eq!(encoded_len, encoded_size(input_len, config).unwrap());
+
+        let mut bytes: Vec<u8> = Vec::new();
+        let mut rng = rand::rngs::SmallRng::from_entropy();
+
+        for _ in 0..input_len {
+            bytes.push(rng.gen());
+        }
+
+        let encoded = encode_config(&bytes, config);
+        assert_encode_sanity(&encoded, config, input_len);
+
+        assert_eq!(encoded_len, encoded.len());
+    }
+
+    #[test]
+    fn encode_imap() {
+        assert_eq!(
+            encode_config(b"\xFB\xFF", crate::IMAP_MUTF7),
+            encode_config(b"\xFB\xFF", crate::STANDARD_NO_PAD).replace("/", ",")
+        );
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/lib.rs cargo-0.66.0+ds1/vendor/base64/src/lib.rs
--- cargo-0.66.0/vendor/base64/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,245 @@
+//! # Configs
+//!
+//! There isn't just one type of Base64; that would be too simple. You need to choose a character
+//! set (standard, URL-safe, etc) and padding suffix (yes/no).
+//! The `Config` struct encapsulates this info. There are some common configs included: `STANDARD`,
+//! `URL_SAFE`, etc. You can also make your own `Config` if needed.
+//!
+//! The functions that don't have `config` in the name (e.g. `encode()` and `decode()`) use the
+//! `STANDARD` config .
+//!
+//! The functions that write to a slice (the ones that end in `_slice`) are generally the fastest
+//! because they don't need to resize anything. If it fits in your workflow and you care about
+//! performance, keep using the same buffer (growing as need be) and use the `_slice` methods for
+//! the best performance.
+//!
+//! # Encoding
+//!
+//! Several different encoding functions are available to you depending on your desire for
+//! convenience vs performance.
+//!
+//! | Function                | Output                       | Allocates                      |
+//! | ----------------------- | ---------------------------- | ------------------------------ |
+//! | `encode`                | Returns a new `String`       | Always                         |
+//! | `encode_config`         | Returns a new `String`       | Always                         |
+//! | `encode_config_buf`     | Appends to provided `String` | Only if `String` needs to grow |
+//! | `encode_config_slice`   | Writes to provided `&[u8]`   | Never                          |
+//!
+//! All of the encoding functions that take a `Config` will pad as per the config.
+//!
+//! # Decoding
+//!
+//! Just as for encoding, there are different decoding functions available.
+//!
+//! | Function                | Output                        | Allocates                      |
+//! | ----------------------- | ----------------------------- | ------------------------------ |
+//! | `decode`                | Returns a new `Vec<u8>`       | Always                         |
+//! | `decode_config`         | Returns a new `Vec<u8>`       | Always                         |
+//! | `decode_config_buf`     | Appends to provided `Vec<u8>` | Only if `Vec` needs to grow    |
+//! | `decode_config_slice`   | Writes to provided `&[u8]`    | Never                          |
+//!
+//! Unlike encoding, where all possible input is valid, decoding can fail (see `DecodeError`).
+//!
+//! Input can be invalid because it has invalid characters or invalid padding. (No padding at all is
+//! valid, but excess padding is not.) Whitespace in the input is invalid.
+//!
+//! # `Read` and `Write`
+//!
+//! To map a `Read` of b64 bytes to the decoded bytes, wrap a reader (file, network socket, etc)
+//! with `base64::read::DecoderReader`. To write raw bytes and have them b64 encoded on the fly,
+//! wrap a writer with `base64::write::EncoderWriter`. There is some performance overhead (15% or
+//! so) because of the necessary buffer shuffling -- still fast enough that almost nobody cares.
+//! Also, these implementations do not heap allocate.
+//!
+//! # Panics
+//!
+//! If length calculations result in overflowing `usize`, a panic will result.
+//!
+//! The `_slice` flavors of encode or decode will panic if the provided output slice is too small,
+
+#![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))]
+#![deny(
+    missing_docs,
+    trivial_casts,
+    trivial_numeric_casts,
+    unused_extern_crates,
+    unused_import_braces,
+    unused_results,
+    variant_size_differences,
+    warnings
+)]
+#![forbid(unsafe_code)]
+#![cfg_attr(not(any(feature = "std", test)), no_std)]
+
+#[cfg(all(feature = "alloc", not(any(feature = "std", test))))]
+extern crate alloc;
+#[cfg(any(feature = "std", test))]
+extern crate std as alloc;
+
+mod chunked_encoder;
+pub mod display;
+#[cfg(any(feature = "std", test))]
+pub mod read;
+mod tables;
+#[cfg(any(feature = "std", test))]
+pub mod write;
+
+mod encode;
+pub use crate::encode::encode_config_slice;
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub use crate::encode::{encode, encode_config, encode_config_buf};
+
+mod decode;
+#[cfg(any(feature = "alloc", feature = "std", test))]
+pub use crate::decode::{decode, decode_config, decode_config_buf};
+pub use crate::decode::{decode_config_slice, DecodeError};
+
+#[cfg(test)]
+mod tests;
+
+/// Available encoding character sets
+#[derive(Clone, Copy, Debug)]
+pub enum CharacterSet {
+    /// The standard character set (uses `+` and `/`).
+    ///
+    /// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
+    Standard,
+    /// The URL safe character set (uses `-` and `_`).
+    ///
+    /// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-4).
+    UrlSafe,
+    /// The `crypt(3)` character set (uses `./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`).
+    ///
+    /// Not standardized, but folk wisdom on the net asserts that this alphabet is what crypt uses.
+    Crypt,
+    /// The bcrypt character set (uses `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`).
+    Bcrypt,
+    /// The character set used in IMAP-modified UTF-7 (uses `+` and `,`).
+    ///
+    /// See [RFC 3501](https://tools.ietf.org/html/rfc3501#section-5.1.3)
+    ImapMutf7,
+    /// The character set used in BinHex 4.0 files.
+    ///
+    /// See [BinHex 4.0 Definition](http://files.stairways.com/other/binhex-40-specs-info.txt)
+    BinHex,
+}
+
+impl CharacterSet {
+    fn encode_table(self) -> &'static [u8; 64] {
+        match self {
+            CharacterSet::Standard => tables::STANDARD_ENCODE,
+            CharacterSet::UrlSafe => tables::URL_SAFE_ENCODE,
+            CharacterSet::Crypt => tables::CRYPT_ENCODE,
+            CharacterSet::Bcrypt => tables::BCRYPT_ENCODE,
+            CharacterSet::ImapMutf7 => tables::IMAP_MUTF7_ENCODE,
+            CharacterSet::BinHex => tables::BINHEX_ENCODE,
+        }
+    }
+
+    fn decode_table(self) -> &'static [u8; 256] {
+        match self {
+            CharacterSet::Standard => tables::STANDARD_DECODE,
+            CharacterSet::UrlSafe => tables::URL_SAFE_DECODE,
+            CharacterSet::Crypt => tables::CRYPT_DECODE,
+            CharacterSet::Bcrypt => tables::BCRYPT_DECODE,
+            CharacterSet::ImapMutf7 => tables::IMAP_MUTF7_DECODE,
+            CharacterSet::BinHex => tables::BINHEX_DECODE,
+        }
+    }
+}
+
+/// Contains configuration parameters for base64 encoding
+#[derive(Clone, Copy, Debug)]
+pub struct Config {
+    /// Character set to use
+    char_set: CharacterSet,
+    /// True to pad output with `=` characters
+    pad: bool,
+    /// True to ignore excess nonzero bits in the last few symbols, otherwise an error is returned.
+    decode_allow_trailing_bits: bool,
+}
+
+impl Config {
+    /// Create a new `Config`.
+    pub const fn new(char_set: CharacterSet, pad: bool) -> Config {
+        Config {
+            char_set,
+            pad,
+            decode_allow_trailing_bits: false,
+        }
+    }
+
+    /// Sets whether to pad output with `=` characters.
+    pub const fn pad(self, pad: bool) -> Config {
+        Config { pad, ..self }
+    }
+
+    /// Sets whether to emit errors for nonzero trailing bits.
+    ///
+    /// This is useful when implementing
+    /// [forgiving-base64 decode](https://infra.spec.whatwg.org/#forgiving-base64-decode).
+    pub const fn decode_allow_trailing_bits(self, allow: bool) -> Config {
+        Config {
+            decode_allow_trailing_bits: allow,
+            ..self
+        }
+    }
+}
+
+/// Standard character set with padding.
+pub const STANDARD: Config = Config {
+    char_set: CharacterSet::Standard,
+    pad: true,
+    decode_allow_trailing_bits: false,
+};
+
+/// Standard character set without padding.
+pub const STANDARD_NO_PAD: Config = Config {
+    char_set: CharacterSet::Standard,
+    pad: false,
+    decode_allow_trailing_bits: false,
+};
+
+/// URL-safe character set with padding
+pub const URL_SAFE: Config = Config {
+    char_set: CharacterSet::UrlSafe,
+    pad: true,
+    decode_allow_trailing_bits: false,
+};
+
+/// URL-safe character set without padding
+pub const URL_SAFE_NO_PAD: Config = Config {
+    char_set: CharacterSet::UrlSafe,
+    pad: false,
+    decode_allow_trailing_bits: false,
+};
+
+/// As per `crypt(3)` requirements
+pub const CRYPT: Config = Config {
+    char_set: CharacterSet::Crypt,
+    pad: false,
+    decode_allow_trailing_bits: false,
+};
+
+/// Bcrypt character set
+pub const BCRYPT: Config = Config {
+    char_set: CharacterSet::Bcrypt,
+    pad: false,
+    decode_allow_trailing_bits: false,
+};
+
+/// IMAP modified UTF-7 requirements
+pub const IMAP_MUTF7: Config = Config {
+    char_set: CharacterSet::ImapMutf7,
+    pad: false,
+    decode_allow_trailing_bits: false,
+};
+
+/// BinHex character set
+pub const BINHEX: Config = Config {
+    char_set: CharacterSet::BinHex,
+    pad: false,
+    decode_allow_trailing_bits: false,
+};
+
+const PAD_BYTE: u8 = b'=';
diff -Nru cargo-0.66.0/vendor/base64/src/read/decoder.rs cargo-0.66.0+ds1/vendor/base64/src/read/decoder.rs
--- cargo-0.66.0/vendor/base64/src/read/decoder.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/read/decoder.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,282 @@
+use crate::{decode_config_slice, Config, DecodeError};
+use std::io::Read;
+use std::{cmp, fmt, io};
+
+// This should be large, but it has to fit on the stack.
+pub(crate) const BUF_SIZE: usize = 1024;
+
+// 4 bytes of base64 data encode 3 bytes of raw data (modulo padding).
+const BASE64_CHUNK_SIZE: usize = 4;
+const DECODED_CHUNK_SIZE: usize = 3;
+
+/// A `Read` implementation that decodes base64 data read from an underlying reader.
+///
+/// # Examples
+///
+/// ```
+/// use std::io::Read;
+/// use std::io::Cursor;
+///
+/// // use a cursor as the simplest possible `Read` -- in real code this is probably a file, etc.
+/// let mut wrapped_reader = Cursor::new(b"YXNkZg==");
+/// let mut decoder = base64::read::DecoderReader::new(
+///     &mut wrapped_reader, base64::STANDARD);
+///
+/// // handle errors as you normally would
+/// let mut result = Vec::new();
+/// decoder.read_to_end(&mut result).unwrap();
+///
+/// assert_eq!(b"asdf", &result[..]);
+///
+/// ```
+pub struct DecoderReader<'a, R: 'a + io::Read> {
+    config: Config,
+    /// Where b64 data is read from
+    r: &'a mut R,
+
+    // Holds b64 data read from the delegate reader.
+    b64_buffer: [u8; BUF_SIZE],
+    // The start of the pending buffered data in b64_buffer.
+    b64_offset: usize,
+    // The amount of buffered b64 data.
+    b64_len: usize,
+    // Since the caller may provide us with a buffer of size 1 or 2 that's too small to copy a
+    // decoded chunk in to, we have to be able to hang on to a few decoded bytes.
+    // Technically we only need to hold 2 bytes but then we'd need a separate temporary buffer to
+    // decode 3 bytes into and then juggle copying one byte into the provided read buf and the rest
+    // into here, which seems like a lot of complexity for 1 extra byte of storage.
+    decoded_buffer: [u8; 3],
+    // index of start of decoded data
+    decoded_offset: usize,
+    // length of decoded data
+    decoded_len: usize,
+    // used to provide accurate offsets in errors
+    total_b64_decoded: usize,
+}
+
+impl<'a, R: io::Read> fmt::Debug for DecoderReader<'a, R> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("DecoderReader")
+            .field("config", &self.config)
+            .field("b64_offset", &self.b64_offset)
+            .field("b64_len", &self.b64_len)
+            .field("decoded_buffer", &self.decoded_buffer)
+            .field("decoded_offset", &self.decoded_offset)
+            .field("decoded_len", &self.decoded_len)
+            .field("total_b64_decoded", &self.total_b64_decoded)
+            .finish()
+    }
+}
+
+impl<'a, R: io::Read> DecoderReader<'a, R> {
+    /// Create a new decoder that will read from the provided reader `r`.
+    pub fn new(r: &'a mut R, config: Config) -> Self {
+        DecoderReader {
+            config,
+            r,
+            b64_buffer: [0; BUF_SIZE],
+            b64_offset: 0,
+            b64_len: 0,
+            decoded_buffer: [0; DECODED_CHUNK_SIZE],
+            decoded_offset: 0,
+            decoded_len: 0,
+            total_b64_decoded: 0,
+        }
+    }
+
+    /// Write as much as possible of the decoded buffer into the target buffer.
+    /// Must only be called when there is something to write and space to write into.
+    /// Returns a Result with the number of (decoded) bytes copied.
+    fn flush_decoded_buf(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        debug_assert!(self.decoded_len > 0);
+        debug_assert!(buf.len() > 0);
+
+        let copy_len = cmp::min(self.decoded_len, buf.len());
+        debug_assert!(copy_len > 0);
+        debug_assert!(copy_len <= self.decoded_len);
+
+        buf[..copy_len].copy_from_slice(
+            &self.decoded_buffer[self.decoded_offset..self.decoded_offset + copy_len],
+        );
+
+        self.decoded_offset += copy_len;
+        self.decoded_len -= copy_len;
+
+        debug_assert!(self.decoded_len < DECODED_CHUNK_SIZE);
+
+        Ok(copy_len)
+    }
+
+    /// Read into the remaining space in the buffer after the current contents.
+    /// Must only be called when there is space to read into in the buffer.
+    /// Returns the number of bytes read.
+    fn read_from_delegate(&mut self) -> io::Result<usize> {
+        debug_assert!(self.b64_offset + self.b64_len < BUF_SIZE);
+
+        let read = self
+            .r
+            .read(&mut self.b64_buffer[self.b64_offset + self.b64_len..])?;
+        self.b64_len += read;
+
+        debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE);
+
+        return Ok(read);
+    }
+
+    /// Decode the requested number of bytes from the b64 buffer into the provided buffer. It's the
+    /// caller's responsibility to choose the number of b64 bytes to decode correctly.
+    ///
+    /// Returns a Result with the number of decoded bytes written to `buf`.
+    fn decode_to_buf(&mut self, num_bytes: usize, buf: &mut [u8]) -> io::Result<usize> {
+        debug_assert!(self.b64_len >= num_bytes);
+        debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE);
+        debug_assert!(buf.len() > 0);
+
+        let decoded = decode_config_slice(
+            &self.b64_buffer[self.b64_offset..self.b64_offset + num_bytes],
+            self.config,
+            &mut buf[..],
+        )
+        .map_err(|e| match e {
+            DecodeError::InvalidByte(offset, byte) => {
+                DecodeError::InvalidByte(self.total_b64_decoded + offset, byte)
+            }
+            DecodeError::InvalidLength => DecodeError::InvalidLength,
+            DecodeError::InvalidLastSymbol(offset, byte) => {
+                DecodeError::InvalidLastSymbol(self.total_b64_decoded + offset, byte)
+            }
+        })
+        .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
+
+        self.total_b64_decoded += num_bytes;
+        self.b64_offset += num_bytes;
+        self.b64_len -= num_bytes;
+
+        debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE);
+
+        Ok(decoded)
+    }
+}
+
+impl<'a, R: Read> Read for DecoderReader<'a, R> {
+    /// Decode input from the wrapped reader.
+    ///
+    /// Under non-error circumstances, this returns `Ok` with the value being the number of bytes
+    /// written in `buf`.
+    ///
+    /// Where possible, this function buffers base64 to minimize the number of read() calls to the
+    /// delegate reader.
+    ///
+    /// # Errors
+    ///
+    /// Any errors emitted by the delegate reader are returned. Decoding errors due to invalid
+    /// base64 are also possible, and will have `io::ErrorKind::InvalidData`.
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        if buf.len() == 0 {
+            return Ok(0);
+        }
+
+        // offset == BUF_SIZE when we copied it all last time
+        debug_assert!(self.b64_offset <= BUF_SIZE);
+        debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE);
+        debug_assert!(if self.b64_offset == BUF_SIZE {
+            self.b64_len == 0
+        } else {
+            self.b64_len <= BUF_SIZE
+        });
+
+        debug_assert!(if self.decoded_len == 0 {
+            // can be = when we were able to copy the complete chunk
+            self.decoded_offset <= DECODED_CHUNK_SIZE
+        } else {
+            self.decoded_offset < DECODED_CHUNK_SIZE
+        });
+
+        // We shouldn't ever decode into here when we can't immediately write at least one byte into
+        // the provided buf, so the effective length should only be 3 momentarily between when we
+        // decode and when we copy into the target buffer.
+        debug_assert!(self.decoded_len < DECODED_CHUNK_SIZE);
+        debug_assert!(self.decoded_len + self.decoded_offset <= DECODED_CHUNK_SIZE);
+
+        if self.decoded_len > 0 {
+            // we have a few leftover decoded bytes; flush that rather than pull in more b64
+            self.flush_decoded_buf(buf)
+        } else {
+            let mut at_eof = false;
+            while self.b64_len < BASE64_CHUNK_SIZE {
+                // Work around lack of copy_within, which is only present in 1.37
+                // Copy any bytes we have to the start of the buffer.
+                // We know we have < 1 chunk, so we can use a tiny tmp buffer.
+                let mut memmove_buf = [0_u8; BASE64_CHUNK_SIZE];
+                memmove_buf[..self.b64_len].copy_from_slice(
+                    &self.b64_buffer[self.b64_offset..self.b64_offset + self.b64_len],
+                );
+                self.b64_buffer[0..self.b64_len].copy_from_slice(&memmove_buf[..self.b64_len]);
+                self.b64_offset = 0;
+
+                // then fill in more data
+                let read = self.read_from_delegate()?;
+                if read == 0 {
+                    // we never pass in an empty buf, so 0 => we've hit EOF
+                    at_eof = true;
+                    break;
+                }
+            }
+
+            if self.b64_len == 0 {
+                debug_assert!(at_eof);
+                // we must be at EOF, and we have no data left to decode
+                return Ok(0);
+            };
+
+            debug_assert!(if at_eof {
+                // if we are at eof, we may not have a complete chunk
+                self.b64_len > 0
+            } else {
+                // otherwise, we must have at least one chunk
+                self.b64_len >= BASE64_CHUNK_SIZE
+            });
+
+            debug_assert_eq!(0, self.decoded_len);
+
+            if buf.len() < DECODED_CHUNK_SIZE {
+                // caller requested an annoyingly short read
+                // have to write to a tmp buf first to avoid double mutable borrow
+                let mut decoded_chunk = [0_u8; DECODED_CHUNK_SIZE];
+                // if we are at eof, could have less than BASE64_CHUNK_SIZE, in which case we have
+                // to assume that these last few tokens are, in fact, valid (i.e. must be 2-4 b64
+                // tokens, not 1, since 1 token can't decode to 1 byte).
+                let to_decode = cmp::min(self.b64_len, BASE64_CHUNK_SIZE);
+
+                let decoded = self.decode_to_buf(to_decode, &mut decoded_chunk[..])?;
+                self.decoded_buffer[..decoded].copy_from_slice(&decoded_chunk[..decoded]);
+
+                self.decoded_offset = 0;
+                self.decoded_len = decoded;
+
+                // can be less than 3 on last block due to padding
+                debug_assert!(decoded <= 3);
+
+                self.flush_decoded_buf(buf)
+            } else {
+                let b64_bytes_that_can_decode_into_buf = (buf.len() / DECODED_CHUNK_SIZE)
+                    .checked_mul(BASE64_CHUNK_SIZE)
+                    .expect("too many chunks");
+                debug_assert!(b64_bytes_that_can_decode_into_buf >= BASE64_CHUNK_SIZE);
+
+                let b64_bytes_available_to_decode = if at_eof {
+                    self.b64_len
+                } else {
+                    // only use complete chunks
+                    self.b64_len - self.b64_len % 4
+                };
+
+                let actual_decode_len = cmp::min(
+                    b64_bytes_that_can_decode_into_buf,
+                    b64_bytes_available_to_decode,
+                );
+                self.decode_to_buf(actual_decode_len, buf)
+            }
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/read/decoder_tests.rs cargo-0.66.0+ds1/vendor/base64/src/read/decoder_tests.rs
--- cargo-0.66.0/vendor/base64/src/read/decoder_tests.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/read/decoder_tests.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,335 @@
+use std::io::{self, Read};
+
+use rand::{Rng, RngCore};
+use std::{cmp, iter};
+
+use super::decoder::{DecoderReader, BUF_SIZE};
+use crate::encode::encode_config_buf;
+use crate::tests::random_config;
+use crate::{decode_config_buf, DecodeError, STANDARD};
+
+#[test]
+fn simple() {
+    let tests: &[(&[u8], &[u8])] = &[
+        (&b"0"[..], &b"MA=="[..]),
+        (b"01", b"MDE="),
+        (b"012", b"MDEy"),
+        (b"0123", b"MDEyMw=="),
+        (b"01234", b"MDEyMzQ="),
+        (b"012345", b"MDEyMzQ1"),
+        (b"0123456", b"MDEyMzQ1Ng=="),
+        (b"01234567", b"MDEyMzQ1Njc="),
+        (b"012345678", b"MDEyMzQ1Njc4"),
+        (b"0123456789", b"MDEyMzQ1Njc4OQ=="),
+    ][..];
+
+    for (text_expected, base64data) in tests.iter() {
+        // Read n bytes at a time.
+        for n in 1..base64data.len() + 1 {
+            let mut wrapped_reader = io::Cursor::new(base64data);
+            let mut decoder = DecoderReader::new(&mut wrapped_reader, STANDARD);
+
+            // handle errors as you normally would
+            let mut text_got = Vec::new();
+            let mut buffer = vec![0u8; n];
+            while let Ok(read) = decoder.read(&mut buffer[..]) {
+                if read == 0 {
+                    break;
+                }
+                text_got.extend_from_slice(&buffer[..read]);
+            }
+
+            assert_eq!(
+                text_got,
+                *text_expected,
+                "\nGot: {}\nExpected: {}",
+                String::from_utf8_lossy(&text_got[..]),
+                String::from_utf8_lossy(text_expected)
+            );
+        }
+    }
+}
+
+// Make sure we error out on trailing junk.
+#[test]
+fn trailing_junk() {
+    let tests: &[&[u8]] = &[&b"MDEyMzQ1Njc4*!@#$%^&"[..], b"MDEyMzQ1Njc4OQ== "][..];
+
+    for base64data in tests.iter() {
+        // Read n bytes at a time.
+        for n in 1..base64data.len() + 1 {
+            let mut wrapped_reader = io::Cursor::new(base64data);
+            let mut decoder = DecoderReader::new(&mut wrapped_reader, STANDARD);
+
+            // handle errors as you normally would
+            let mut buffer = vec![0u8; n];
+            let mut saw_error = false;
+            loop {
+                match decoder.read(&mut buffer[..]) {
+                    Err(_) => {
+                        saw_error = true;
+                        break;
+                    }
+                    Ok(read) if read == 0 => break,
+                    Ok(_) => (),
+                }
+            }
+
+            assert!(saw_error);
+        }
+    }
+}
+
+#[test]
+fn handles_short_read_from_delegate() {
+    let mut rng = rand::thread_rng();
+    let mut bytes = Vec::new();
+    let mut b64 = String::new();
+    let mut decoded = Vec::new();
+
+    for _ in 0..10_000 {
+        bytes.clear();
+        b64.clear();
+        decoded.clear();
+
+        let size = rng.gen_range(0, 10 * BUF_SIZE);
+        bytes.extend(iter::repeat(0).take(size));
+        bytes.truncate(size);
+        rng.fill_bytes(&mut bytes[..size]);
+        assert_eq!(size, bytes.len());
+
+        let config = random_config(&mut rng);
+        encode_config_buf(&bytes[..], config, &mut b64);
+
+        let mut wrapped_reader = io::Cursor::new(b64.as_bytes());
+        let mut short_reader = RandomShortRead {
+            delegate: &mut wrapped_reader,
+            rng: &mut rng,
+        };
+
+        let mut decoder = DecoderReader::new(&mut short_reader, config);
+
+        let decoded_len = decoder.read_to_end(&mut decoded).unwrap();
+        assert_eq!(size, decoded_len);
+        assert_eq!(&bytes[..], &decoded[..]);
+    }
+}
+
+#[test]
+fn read_in_short_increments() {
+    let mut rng = rand::thread_rng();
+    let mut bytes = Vec::new();
+    let mut b64 = String::new();
+    let mut decoded = Vec::new();
+
+    for _ in 0..10_000 {
+        bytes.clear();
+        b64.clear();
+        decoded.clear();
+
+        let size = rng.gen_range(0, 10 * BUF_SIZE);
+        bytes.extend(iter::repeat(0).take(size));
+        // leave room to play around with larger buffers
+        decoded.extend(iter::repeat(0).take(size * 3));
+
+        rng.fill_bytes(&mut bytes[..]);
+        assert_eq!(size, bytes.len());
+
+        let config = random_config(&mut rng);
+
+        encode_config_buf(&bytes[..], config, &mut b64);
+
+        let mut wrapped_reader = io::Cursor::new(&b64[..]);
+        let mut decoder = DecoderReader::new(&mut wrapped_reader, config);
+
+        consume_with_short_reads_and_validate(&mut rng, &bytes[..], &mut decoded, &mut decoder);
+    }
+}
+
+#[test]
+fn read_in_short_increments_with_short_delegate_reads() {
+    let mut rng = rand::thread_rng();
+    let mut bytes = Vec::new();
+    let mut b64 = String::new();
+    let mut decoded = Vec::new();
+
+    for _ in 0..10_000 {
+        bytes.clear();
+        b64.clear();
+        decoded.clear();
+
+        let size = rng.gen_range(0, 10 * BUF_SIZE);
+        bytes.extend(iter::repeat(0).take(size));
+        // leave room to play around with larger buffers
+        decoded.extend(iter::repeat(0).take(size * 3));
+
+        rng.fill_bytes(&mut bytes[..]);
+        assert_eq!(size, bytes.len());
+
+        let config = random_config(&mut rng);
+
+        encode_config_buf(&bytes[..], config, &mut b64);
+
+        let mut base_reader = io::Cursor::new(&b64[..]);
+        let mut decoder = DecoderReader::new(&mut base_reader, config);
+        let mut short_reader = RandomShortRead {
+            delegate: &mut decoder,
+            rng: &mut rand::thread_rng(),
+        };
+
+        consume_with_short_reads_and_validate(&mut rng, &bytes[..], &mut decoded, &mut short_reader)
+    }
+}
+
+#[test]
+fn reports_invalid_last_symbol_correctly() {
+    let mut rng = rand::thread_rng();
+    let mut bytes = Vec::new();
+    let mut b64 = String::new();
+    let mut b64_bytes = Vec::new();
+    let mut decoded = Vec::new();
+    let mut bulk_decoded = Vec::new();
+
+    for _ in 0..1_000 {
+        bytes.clear();
+        b64.clear();
+        b64_bytes.clear();
+
+        let size = rng.gen_range(1, 10 * BUF_SIZE);
+        bytes.extend(iter::repeat(0).take(size));
+        decoded.extend(iter::repeat(0).take(size));
+        rng.fill_bytes(&mut bytes[..]);
+        assert_eq!(size, bytes.len());
+
+        let mut config = random_config(&mut rng);
+        // changing padding will cause invalid padding errors when we twiddle the last byte
+        config.pad = false;
+
+        encode_config_buf(&bytes[..], config, &mut b64);
+        b64_bytes.extend(b64.bytes());
+        assert_eq!(b64_bytes.len(), b64.len());
+
+        // change the last character to every possible symbol. Should behave the same as bulk
+        // decoding whether invalid or valid.
+        for &s1 in config.char_set.encode_table().iter() {
+            decoded.clear();
+            bulk_decoded.clear();
+
+            // replace the last
+            *b64_bytes.last_mut().unwrap() = s1;
+            let bulk_res = decode_config_buf(&b64_bytes[..], config, &mut bulk_decoded);
+
+            let mut wrapped_reader = io::Cursor::new(&b64_bytes[..]);
+            let mut decoder = DecoderReader::new(&mut wrapped_reader, config);
+
+            let stream_res = decoder.read_to_end(&mut decoded).map(|_| ()).map_err(|e| {
+                e.into_inner()
+                    .and_then(|e| e.downcast::<DecodeError>().ok())
+            });
+
+            assert_eq!(bulk_res.map_err(|e| Some(Box::new(e))), stream_res);
+        }
+    }
+}
+
+#[test]
+fn reports_invalid_byte_correctly() {
+    let mut rng = rand::thread_rng();
+    let mut bytes = Vec::new();
+    let mut b64 = String::new();
+    let mut decoded = Vec::new();
+
+    for _ in 0..10_000 {
+        bytes.clear();
+        b64.clear();
+        decoded.clear();
+
+        let size = rng.gen_range(1, 10 * BUF_SIZE);
+        bytes.extend(iter::repeat(0).take(size));
+        rng.fill_bytes(&mut bytes[..size]);
+        assert_eq!(size, bytes.len());
+
+        let config = random_config(&mut rng);
+        encode_config_buf(&bytes[..], config, &mut b64);
+        // replace one byte, somewhere, with '*', which is invalid
+        let bad_byte_pos = rng.gen_range(0, &b64.len());
+        let mut b64_bytes = b64.bytes().collect::<Vec<u8>>();
+        b64_bytes[bad_byte_pos] = b'*';
+
+        let mut wrapped_reader = io::Cursor::new(b64_bytes.clone());
+        let mut decoder = DecoderReader::new(&mut wrapped_reader, config);
+
+        // some gymnastics to avoid double-moving the io::Error, which is not Copy
+        let read_decode_err = decoder
+            .read_to_end(&mut decoded)
+            .map_err(|e| {
+                let kind = e.kind();
+                let inner = e
+                    .into_inner()
+                    .and_then(|e| e.downcast::<DecodeError>().ok());
+                inner.map(|i| (*i, kind))
+            })
+            .err()
+            .and_then(|o| o);
+
+        let mut bulk_buf = Vec::new();
+        let bulk_decode_err = decode_config_buf(&b64_bytes[..], config, &mut bulk_buf).err();
+
+        // it's tricky to predict where the invalid data's offset will be since if it's in the last
+        // chunk it will be reported at the first padding location because it's treated as invalid
+        // padding. So, we just check that it's the same as it is for decoding all at once.
+        assert_eq!(
+            bulk_decode_err.map(|e| (e, io::ErrorKind::InvalidData)),
+            read_decode_err
+        );
+    }
+}
+
+fn consume_with_short_reads_and_validate<R: Read>(
+    rng: &mut rand::rngs::ThreadRng,
+    expected_bytes: &[u8],
+    decoded: &mut Vec<u8>,
+    short_reader: &mut R,
+) -> () {
+    let mut total_read = 0_usize;
+    loop {
+        assert!(
+            total_read <= expected_bytes.len(),
+            "tr {} size {}",
+            total_read,
+            expected_bytes.len()
+        );
+        if total_read == expected_bytes.len() {
+            assert_eq!(expected_bytes, &decoded[..total_read]);
+            // should be done
+            assert_eq!(0, short_reader.read(&mut decoded[..]).unwrap());
+            // didn't write anything
+            assert_eq!(expected_bytes, &decoded[..total_read]);
+
+            break;
+        }
+        let decode_len = rng.gen_range(1, cmp::max(2, expected_bytes.len() * 2));
+
+        let read = short_reader
+            .read(&mut decoded[total_read..total_read + decode_len])
+            .unwrap();
+        total_read += read;
+    }
+}
+
+/// Limits how many bytes a reader will provide in each read call.
+/// Useful for shaking out code that may work fine only with typical input sources that always fill
+/// the buffer.
+struct RandomShortRead<'a, 'b, R: io::Read, N: rand::Rng> {
+    delegate: &'b mut R,
+    rng: &'a mut N,
+}
+
+impl<'a, 'b, R: io::Read, N: rand::Rng> io::Read for RandomShortRead<'a, 'b, R, N> {
+    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
+        // avoid 0 since it means EOF for non-empty buffers
+        let effective_len = cmp::min(self.rng.gen_range(1, 20), buf.len());
+
+        self.delegate.read(&mut buf[..effective_len])
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/read/mod.rs cargo-0.66.0+ds1/vendor/base64/src/read/mod.rs
--- cargo-0.66.0/vendor/base64/src/read/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/read/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,6 @@
+//! Implementations of `io::Read` to transparently decode base64.
+mod decoder;
+pub use self::decoder::DecoderReader;
+
+#[cfg(test)]
+mod decoder_tests;
diff -Nru cargo-0.66.0/vendor/base64/src/tables.rs cargo-0.66.0+ds1/vendor/base64/src/tables.rs
--- cargo-0.66.0/vendor/base64/src/tables.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/tables.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,1957 @@
+pub const INVALID_VALUE: u8 = 255;
+#[rustfmt::skip]
+pub const STANDARD_ENCODE: &[u8; 64] = &[
+    65, // input 0 (0x0) => 'A' (0x41)
+    66, // input 1 (0x1) => 'B' (0x42)
+    67, // input 2 (0x2) => 'C' (0x43)
+    68, // input 3 (0x3) => 'D' (0x44)
+    69, // input 4 (0x4) => 'E' (0x45)
+    70, // input 5 (0x5) => 'F' (0x46)
+    71, // input 6 (0x6) => 'G' (0x47)
+    72, // input 7 (0x7) => 'H' (0x48)
+    73, // input 8 (0x8) => 'I' (0x49)
+    74, // input 9 (0x9) => 'J' (0x4A)
+    75, // input 10 (0xA) => 'K' (0x4B)
+    76, // input 11 (0xB) => 'L' (0x4C)
+    77, // input 12 (0xC) => 'M' (0x4D)
+    78, // input 13 (0xD) => 'N' (0x4E)
+    79, // input 14 (0xE) => 'O' (0x4F)
+    80, // input 15 (0xF) => 'P' (0x50)
+    81, // input 16 (0x10) => 'Q' (0x51)
+    82, // input 17 (0x11) => 'R' (0x52)
+    83, // input 18 (0x12) => 'S' (0x53)
+    84, // input 19 (0x13) => 'T' (0x54)
+    85, // input 20 (0x14) => 'U' (0x55)
+    86, // input 21 (0x15) => 'V' (0x56)
+    87, // input 22 (0x16) => 'W' (0x57)
+    88, // input 23 (0x17) => 'X' (0x58)
+    89, // input 24 (0x18) => 'Y' (0x59)
+    90, // input 25 (0x19) => 'Z' (0x5A)
+    97, // input 26 (0x1A) => 'a' (0x61)
+    98, // input 27 (0x1B) => 'b' (0x62)
+    99, // input 28 (0x1C) => 'c' (0x63)
+    100, // input 29 (0x1D) => 'd' (0x64)
+    101, // input 30 (0x1E) => 'e' (0x65)
+    102, // input 31 (0x1F) => 'f' (0x66)
+    103, // input 32 (0x20) => 'g' (0x67)
+    104, // input 33 (0x21) => 'h' (0x68)
+    105, // input 34 (0x22) => 'i' (0x69)
+    106, // input 35 (0x23) => 'j' (0x6A)
+    107, // input 36 (0x24) => 'k' (0x6B)
+    108, // input 37 (0x25) => 'l' (0x6C)
+    109, // input 38 (0x26) => 'm' (0x6D)
+    110, // input 39 (0x27) => 'n' (0x6E)
+    111, // input 40 (0x28) => 'o' (0x6F)
+    112, // input 41 (0x29) => 'p' (0x70)
+    113, // input 42 (0x2A) => 'q' (0x71)
+    114, // input 43 (0x2B) => 'r' (0x72)
+    115, // input 44 (0x2C) => 's' (0x73)
+    116, // input 45 (0x2D) => 't' (0x74)
+    117, // input 46 (0x2E) => 'u' (0x75)
+    118, // input 47 (0x2F) => 'v' (0x76)
+    119, // input 48 (0x30) => 'w' (0x77)
+    120, // input 49 (0x31) => 'x' (0x78)
+    121, // input 50 (0x32) => 'y' (0x79)
+    122, // input 51 (0x33) => 'z' (0x7A)
+    48, // input 52 (0x34) => '0' (0x30)
+    49, // input 53 (0x35) => '1' (0x31)
+    50, // input 54 (0x36) => '2' (0x32)
+    51, // input 55 (0x37) => '3' (0x33)
+    52, // input 56 (0x38) => '4' (0x34)
+    53, // input 57 (0x39) => '5' (0x35)
+    54, // input 58 (0x3A) => '6' (0x36)
+    55, // input 59 (0x3B) => '7' (0x37)
+    56, // input 60 (0x3C) => '8' (0x38)
+    57, // input 61 (0x3D) => '9' (0x39)
+    43, // input 62 (0x3E) => '+' (0x2B)
+    47, // input 63 (0x3F) => '/' (0x2F)
+];
+#[rustfmt::skip]
+pub const STANDARD_DECODE: &[u8; 256] = &[
+    INVALID_VALUE, // input 0 (0x0)
+    INVALID_VALUE, // input 1 (0x1)
+    INVALID_VALUE, // input 2 (0x2)
+    INVALID_VALUE, // input 3 (0x3)
+    INVALID_VALUE, // input 4 (0x4)
+    INVALID_VALUE, // input 5 (0x5)
+    INVALID_VALUE, // input 6 (0x6)
+    INVALID_VALUE, // input 7 (0x7)
+    INVALID_VALUE, // input 8 (0x8)
+    INVALID_VALUE, // input 9 (0x9)
+    INVALID_VALUE, // input 10 (0xA)
+    INVALID_VALUE, // input 11 (0xB)
+    INVALID_VALUE, // input 12 (0xC)
+    INVALID_VALUE, // input 13 (0xD)
+    INVALID_VALUE, // input 14 (0xE)
+    INVALID_VALUE, // input 15 (0xF)
+    INVALID_VALUE, // input 16 (0x10)
+    INVALID_VALUE, // input 17 (0x11)
+    INVALID_VALUE, // input 18 (0x12)
+    INVALID_VALUE, // input 19 (0x13)
+    INVALID_VALUE, // input 20 (0x14)
+    INVALID_VALUE, // input 21 (0x15)
+    INVALID_VALUE, // input 22 (0x16)
+    INVALID_VALUE, // input 23 (0x17)
+    INVALID_VALUE, // input 24 (0x18)
+    INVALID_VALUE, // input 25 (0x19)
+    INVALID_VALUE, // input 26 (0x1A)
+    INVALID_VALUE, // input 27 (0x1B)
+    INVALID_VALUE, // input 28 (0x1C)
+    INVALID_VALUE, // input 29 (0x1D)
+    INVALID_VALUE, // input 30 (0x1E)
+    INVALID_VALUE, // input 31 (0x1F)
+    INVALID_VALUE, // input 32 (0x20)
+    INVALID_VALUE, // input 33 (0x21)
+    INVALID_VALUE, // input 34 (0x22)
+    INVALID_VALUE, // input 35 (0x23)
+    INVALID_VALUE, // input 36 (0x24)
+    INVALID_VALUE, // input 37 (0x25)
+    INVALID_VALUE, // input 38 (0x26)
+    INVALID_VALUE, // input 39 (0x27)
+    INVALID_VALUE, // input 40 (0x28)
+    INVALID_VALUE, // input 41 (0x29)
+    INVALID_VALUE, // input 42 (0x2A)
+    62, // input 43 (0x2B char '+') => 62 (0x3E)
+    INVALID_VALUE, // input 44 (0x2C)
+    INVALID_VALUE, // input 45 (0x2D)
+    INVALID_VALUE, // input 46 (0x2E)
+    63, // input 47 (0x2F char '/') => 63 (0x3F)
+    52, // input 48 (0x30 char '0') => 52 (0x34)
+    53, // input 49 (0x31 char '1') => 53 (0x35)
+    54, // input 50 (0x32 char '2') => 54 (0x36)
+    55, // input 51 (0x33 char '3') => 55 (0x37)
+    56, // input 52 (0x34 char '4') => 56 (0x38)
+    57, // input 53 (0x35 char '5') => 57 (0x39)
+    58, // input 54 (0x36 char '6') => 58 (0x3A)
+    59, // input 55 (0x37 char '7') => 59 (0x3B)
+    60, // input 56 (0x38 char '8') => 60 (0x3C)
+    61, // input 57 (0x39 char '9') => 61 (0x3D)
+    INVALID_VALUE, // input 58 (0x3A)
+    INVALID_VALUE, // input 59 (0x3B)
+    INVALID_VALUE, // input 60 (0x3C)
+    INVALID_VALUE, // input 61 (0x3D)
+    INVALID_VALUE, // input 62 (0x3E)
+    INVALID_VALUE, // input 63 (0x3F)
+    INVALID_VALUE, // input 64 (0x40)
+    0, // input 65 (0x41 char 'A') => 0 (0x0)
+    1, // input 66 (0x42 char 'B') => 1 (0x1)
+    2, // input 67 (0x43 char 'C') => 2 (0x2)
+    3, // input 68 (0x44 char 'D') => 3 (0x3)
+    4, // input 69 (0x45 char 'E') => 4 (0x4)
+    5, // input 70 (0x46 char 'F') => 5 (0x5)
+    6, // input 71 (0x47 char 'G') => 6 (0x6)
+    7, // input 72 (0x48 char 'H') => 7 (0x7)
+    8, // input 73 (0x49 char 'I') => 8 (0x8)
+    9, // input 74 (0x4A char 'J') => 9 (0x9)
+    10, // input 75 (0x4B char 'K') => 10 (0xA)
+    11, // input 76 (0x4C char 'L') => 11 (0xB)
+    12, // input 77 (0x4D char 'M') => 12 (0xC)
+    13, // input 78 (0x4E char 'N') => 13 (0xD)
+    14, // input 79 (0x4F char 'O') => 14 (0xE)
+    15, // input 80 (0x50 char 'P') => 15 (0xF)
+    16, // input 81 (0x51 char 'Q') => 16 (0x10)
+    17, // input 82 (0x52 char 'R') => 17 (0x11)
+    18, // input 83 (0x53 char 'S') => 18 (0x12)
+    19, // input 84 (0x54 char 'T') => 19 (0x13)
+    20, // input 85 (0x55 char 'U') => 20 (0x14)
+    21, // input 86 (0x56 char 'V') => 21 (0x15)
+    22, // input 87 (0x57 char 'W') => 22 (0x16)
+    23, // input 88 (0x58 char 'X') => 23 (0x17)
+    24, // input 89 (0x59 char 'Y') => 24 (0x18)
+    25, // input 90 (0x5A char 'Z') => 25 (0x19)
+    INVALID_VALUE, // input 91 (0x5B)
+    INVALID_VALUE, // input 92 (0x5C)
+    INVALID_VALUE, // input 93 (0x5D)
+    INVALID_VALUE, // input 94 (0x5E)
+    INVALID_VALUE, // input 95 (0x5F)
+    INVALID_VALUE, // input 96 (0x60)
+    26, // input 97 (0x61 char 'a') => 26 (0x1A)
+    27, // input 98 (0x62 char 'b') => 27 (0x1B)
+    28, // input 99 (0x63 char 'c') => 28 (0x1C)
+    29, // input 100 (0x64 char 'd') => 29 (0x1D)
+    30, // input 101 (0x65 char 'e') => 30 (0x1E)
+    31, // input 102 (0x66 char 'f') => 31 (0x1F)
+    32, // input 103 (0x67 char 'g') => 32 (0x20)
+    33, // input 104 (0x68 char 'h') => 33 (0x21)
+    34, // input 105 (0x69 char 'i') => 34 (0x22)
+    35, // input 106 (0x6A char 'j') => 35 (0x23)
+    36, // input 107 (0x6B char 'k') => 36 (0x24)
+    37, // input 108 (0x6C char 'l') => 37 (0x25)
+    38, // input 109 (0x6D char 'm') => 38 (0x26)
+    39, // input 110 (0x6E char 'n') => 39 (0x27)
+    40, // input 111 (0x6F char 'o') => 40 (0x28)
+    41, // input 112 (0x70 char 'p') => 41 (0x29)
+    42, // input 113 (0x71 char 'q') => 42 (0x2A)
+    43, // input 114 (0x72 char 'r') => 43 (0x2B)
+    44, // input 115 (0x73 char 's') => 44 (0x2C)
+    45, // input 116 (0x74 char 't') => 45 (0x2D)
+    46, // input 117 (0x75 char 'u') => 46 (0x2E)
+    47, // input 118 (0x76 char 'v') => 47 (0x2F)
+    48, // input 119 (0x77 char 'w') => 48 (0x30)
+    49, // input 120 (0x78 char 'x') => 49 (0x31)
+    50, // input 121 (0x79 char 'y') => 50 (0x32)
+    51, // input 122 (0x7A char 'z') => 51 (0x33)
+    INVALID_VALUE, // input 123 (0x7B)
+    INVALID_VALUE, // input 124 (0x7C)
+    INVALID_VALUE, // input 125 (0x7D)
+    INVALID_VALUE, // input 126 (0x7E)
+    INVALID_VALUE, // input 127 (0x7F)
+    INVALID_VALUE, // input 128 (0x80)
+    INVALID_VALUE, // input 129 (0x81)
+    INVALID_VALUE, // input 130 (0x82)
+    INVALID_VALUE, // input 131 (0x83)
+    INVALID_VALUE, // input 132 (0x84)
+    INVALID_VALUE, // input 133 (0x85)
+    INVALID_VALUE, // input 134 (0x86)
+    INVALID_VALUE, // input 135 (0x87)
+    INVALID_VALUE, // input 136 (0x88)
+    INVALID_VALUE, // input 137 (0x89)
+    INVALID_VALUE, // input 138 (0x8A)
+    INVALID_VALUE, // input 139 (0x8B)
+    INVALID_VALUE, // input 140 (0x8C)
+    INVALID_VALUE, // input 141 (0x8D)
+    INVALID_VALUE, // input 142 (0x8E)
+    INVALID_VALUE, // input 143 (0x8F)
+    INVALID_VALUE, // input 144 (0x90)
+    INVALID_VALUE, // input 145 (0x91)
+    INVALID_VALUE, // input 146 (0x92)
+    INVALID_VALUE, // input 147 (0x93)
+    INVALID_VALUE, // input 148 (0x94)
+    INVALID_VALUE, // input 149 (0x95)
+    INVALID_VALUE, // input 150 (0x96)
+    INVALID_VALUE, // input 151 (0x97)
+    INVALID_VALUE, // input 152 (0x98)
+    INVALID_VALUE, // input 153 (0x99)
+    INVALID_VALUE, // input 154 (0x9A)
+    INVALID_VALUE, // input 155 (0x9B)
+    INVALID_VALUE, // input 156 (0x9C)
+    INVALID_VALUE, // input 157 (0x9D)
+    INVALID_VALUE, // input 158 (0x9E)
+    INVALID_VALUE, // input 159 (0x9F)
+    INVALID_VALUE, // input 160 (0xA0)
+    INVALID_VALUE, // input 161 (0xA1)
+    INVALID_VALUE, // input 162 (0xA2)
+    INVALID_VALUE, // input 163 (0xA3)
+    INVALID_VALUE, // input 164 (0xA4)
+    INVALID_VALUE, // input 165 (0xA5)
+    INVALID_VALUE, // input 166 (0xA6)
+    INVALID_VALUE, // input 167 (0xA7)
+    INVALID_VALUE, // input 168 (0xA8)
+    INVALID_VALUE, // input 169 (0xA9)
+    INVALID_VALUE, // input 170 (0xAA)
+    INVALID_VALUE, // input 171 (0xAB)
+    INVALID_VALUE, // input 172 (0xAC)
+    INVALID_VALUE, // input 173 (0xAD)
+    INVALID_VALUE, // input 174 (0xAE)
+    INVALID_VALUE, // input 175 (0xAF)
+    INVALID_VALUE, // input 176 (0xB0)
+    INVALID_VALUE, // input 177 (0xB1)
+    INVALID_VALUE, // input 178 (0xB2)
+    INVALID_VALUE, // input 179 (0xB3)
+    INVALID_VALUE, // input 180 (0xB4)
+    INVALID_VALUE, // input 181 (0xB5)
+    INVALID_VALUE, // input 182 (0xB6)
+    INVALID_VALUE, // input 183 (0xB7)
+    INVALID_VALUE, // input 184 (0xB8)
+    INVALID_VALUE, // input 185 (0xB9)
+    INVALID_VALUE, // input 186 (0xBA)
+    INVALID_VALUE, // input 187 (0xBB)
+    INVALID_VALUE, // input 188 (0xBC)
+    INVALID_VALUE, // input 189 (0xBD)
+    INVALID_VALUE, // input 190 (0xBE)
+    INVALID_VALUE, // input 191 (0xBF)
+    INVALID_VALUE, // input 192 (0xC0)
+    INVALID_VALUE, // input 193 (0xC1)
+    INVALID_VALUE, // input 194 (0xC2)
+    INVALID_VALUE, // input 195 (0xC3)
+    INVALID_VALUE, // input 196 (0xC4)
+    INVALID_VALUE, // input 197 (0xC5)
+    INVALID_VALUE, // input 198 (0xC6)
+    INVALID_VALUE, // input 199 (0xC7)
+    INVALID_VALUE, // input 200 (0xC8)
+    INVALID_VALUE, // input 201 (0xC9)
+    INVALID_VALUE, // input 202 (0xCA)
+    INVALID_VALUE, // input 203 (0xCB)
+    INVALID_VALUE, // input 204 (0xCC)
+    INVALID_VALUE, // input 205 (0xCD)
+    INVALID_VALUE, // input 206 (0xCE)
+    INVALID_VALUE, // input 207 (0xCF)
+    INVALID_VALUE, // input 208 (0xD0)
+    INVALID_VALUE, // input 209 (0xD1)
+    INVALID_VALUE, // input 210 (0xD2)
+    INVALID_VALUE, // input 211 (0xD3)
+    INVALID_VALUE, // input 212 (0xD4)
+    INVALID_VALUE, // input 213 (0xD5)
+    INVALID_VALUE, // input 214 (0xD6)
+    INVALID_VALUE, // input 215 (0xD7)
+    INVALID_VALUE, // input 216 (0xD8)
+    INVALID_VALUE, // input 217 (0xD9)
+    INVALID_VALUE, // input 218 (0xDA)
+    INVALID_VALUE, // input 219 (0xDB)
+    INVALID_VALUE, // input 220 (0xDC)
+    INVALID_VALUE, // input 221 (0xDD)
+    INVALID_VALUE, // input 222 (0xDE)
+    INVALID_VALUE, // input 223 (0xDF)
+    INVALID_VALUE, // input 224 (0xE0)
+    INVALID_VALUE, // input 225 (0xE1)
+    INVALID_VALUE, // input 226 (0xE2)
+    INVALID_VALUE, // input 227 (0xE3)
+    INVALID_VALUE, // input 228 (0xE4)
+    INVALID_VALUE, // input 229 (0xE5)
+    INVALID_VALUE, // input 230 (0xE6)
+    INVALID_VALUE, // input 231 (0xE7)
+    INVALID_VALUE, // input 232 (0xE8)
+    INVALID_VALUE, // input 233 (0xE9)
+    INVALID_VALUE, // input 234 (0xEA)
+    INVALID_VALUE, // input 235 (0xEB)
+    INVALID_VALUE, // input 236 (0xEC)
+    INVALID_VALUE, // input 237 (0xED)
+    INVALID_VALUE, // input 238 (0xEE)
+    INVALID_VALUE, // input 239 (0xEF)
+    INVALID_VALUE, // input 240 (0xF0)
+    INVALID_VALUE, // input 241 (0xF1)
+    INVALID_VALUE, // input 242 (0xF2)
+    INVALID_VALUE, // input 243 (0xF3)
+    INVALID_VALUE, // input 244 (0xF4)
+    INVALID_VALUE, // input 245 (0xF5)
+    INVALID_VALUE, // input 246 (0xF6)
+    INVALID_VALUE, // input 247 (0xF7)
+    INVALID_VALUE, // input 248 (0xF8)
+    INVALID_VALUE, // input 249 (0xF9)
+    INVALID_VALUE, // input 250 (0xFA)
+    INVALID_VALUE, // input 251 (0xFB)
+    INVALID_VALUE, // input 252 (0xFC)
+    INVALID_VALUE, // input 253 (0xFD)
+    INVALID_VALUE, // input 254 (0xFE)
+    INVALID_VALUE, // input 255 (0xFF)
+];
+#[rustfmt::skip]
+pub const URL_SAFE_ENCODE: &[u8; 64] = &[
+    65, // input 0 (0x0) => 'A' (0x41)
+    66, // input 1 (0x1) => 'B' (0x42)
+    67, // input 2 (0x2) => 'C' (0x43)
+    68, // input 3 (0x3) => 'D' (0x44)
+    69, // input 4 (0x4) => 'E' (0x45)
+    70, // input 5 (0x5) => 'F' (0x46)
+    71, // input 6 (0x6) => 'G' (0x47)
+    72, // input 7 (0x7) => 'H' (0x48)
+    73, // input 8 (0x8) => 'I' (0x49)
+    74, // input 9 (0x9) => 'J' (0x4A)
+    75, // input 10 (0xA) => 'K' (0x4B)
+    76, // input 11 (0xB) => 'L' (0x4C)
+    77, // input 12 (0xC) => 'M' (0x4D)
+    78, // input 13 (0xD) => 'N' (0x4E)
+    79, // input 14 (0xE) => 'O' (0x4F)
+    80, // input 15 (0xF) => 'P' (0x50)
+    81, // input 16 (0x10) => 'Q' (0x51)
+    82, // input 17 (0x11) => 'R' (0x52)
+    83, // input 18 (0x12) => 'S' (0x53)
+    84, // input 19 (0x13) => 'T' (0x54)
+    85, // input 20 (0x14) => 'U' (0x55)
+    86, // input 21 (0x15) => 'V' (0x56)
+    87, // input 22 (0x16) => 'W' (0x57)
+    88, // input 23 (0x17) => 'X' (0x58)
+    89, // input 24 (0x18) => 'Y' (0x59)
+    90, // input 25 (0x19) => 'Z' (0x5A)
+    97, // input 26 (0x1A) => 'a' (0x61)
+    98, // input 27 (0x1B) => 'b' (0x62)
+    99, // input 28 (0x1C) => 'c' (0x63)
+    100, // input 29 (0x1D) => 'd' (0x64)
+    101, // input 30 (0x1E) => 'e' (0x65)
+    102, // input 31 (0x1F) => 'f' (0x66)
+    103, // input 32 (0x20) => 'g' (0x67)
+    104, // input 33 (0x21) => 'h' (0x68)
+    105, // input 34 (0x22) => 'i' (0x69)
+    106, // input 35 (0x23) => 'j' (0x6A)
+    107, // input 36 (0x24) => 'k' (0x6B)
+    108, // input 37 (0x25) => 'l' (0x6C)
+    109, // input 38 (0x26) => 'm' (0x6D)
+    110, // input 39 (0x27) => 'n' (0x6E)
+    111, // input 40 (0x28) => 'o' (0x6F)
+    112, // input 41 (0x29) => 'p' (0x70)
+    113, // input 42 (0x2A) => 'q' (0x71)
+    114, // input 43 (0x2B) => 'r' (0x72)
+    115, // input 44 (0x2C) => 's' (0x73)
+    116, // input 45 (0x2D) => 't' (0x74)
+    117, // input 46 (0x2E) => 'u' (0x75)
+    118, // input 47 (0x2F) => 'v' (0x76)
+    119, // input 48 (0x30) => 'w' (0x77)
+    120, // input 49 (0x31) => 'x' (0x78)
+    121, // input 50 (0x32) => 'y' (0x79)
+    122, // input 51 (0x33) => 'z' (0x7A)
+    48, // input 52 (0x34) => '0' (0x30)
+    49, // input 53 (0x35) => '1' (0x31)
+    50, // input 54 (0x36) => '2' (0x32)
+    51, // input 55 (0x37) => '3' (0x33)
+    52, // input 56 (0x38) => '4' (0x34)
+    53, // input 57 (0x39) => '5' (0x35)
+    54, // input 58 (0x3A) => '6' (0x36)
+    55, // input 59 (0x3B) => '7' (0x37)
+    56, // input 60 (0x3C) => '8' (0x38)
+    57, // input 61 (0x3D) => '9' (0x39)
+    45, // input 62 (0x3E) => '-' (0x2D)
+    95, // input 63 (0x3F) => '_' (0x5F)
+];
+#[rustfmt::skip]
+pub const URL_SAFE_DECODE: &[u8; 256] = &[
+    INVALID_VALUE, // input 0 (0x0)
+    INVALID_VALUE, // input 1 (0x1)
+    INVALID_VALUE, // input 2 (0x2)
+    INVALID_VALUE, // input 3 (0x3)
+    INVALID_VALUE, // input 4 (0x4)
+    INVALID_VALUE, // input 5 (0x5)
+    INVALID_VALUE, // input 6 (0x6)
+    INVALID_VALUE, // input 7 (0x7)
+    INVALID_VALUE, // input 8 (0x8)
+    INVALID_VALUE, // input 9 (0x9)
+    INVALID_VALUE, // input 10 (0xA)
+    INVALID_VALUE, // input 11 (0xB)
+    INVALID_VALUE, // input 12 (0xC)
+    INVALID_VALUE, // input 13 (0xD)
+    INVALID_VALUE, // input 14 (0xE)
+    INVALID_VALUE, // input 15 (0xF)
+    INVALID_VALUE, // input 16 (0x10)
+    INVALID_VALUE, // input 17 (0x11)
+    INVALID_VALUE, // input 18 (0x12)
+    INVALID_VALUE, // input 19 (0x13)
+    INVALID_VALUE, // input 20 (0x14)
+    INVALID_VALUE, // input 21 (0x15)
+    INVALID_VALUE, // input 22 (0x16)
+    INVALID_VALUE, // input 23 (0x17)
+    INVALID_VALUE, // input 24 (0x18)
+    INVALID_VALUE, // input 25 (0x19)
+    INVALID_VALUE, // input 26 (0x1A)
+    INVALID_VALUE, // input 27 (0x1B)
+    INVALID_VALUE, // input 28 (0x1C)
+    INVALID_VALUE, // input 29 (0x1D)
+    INVALID_VALUE, // input 30 (0x1E)
+    INVALID_VALUE, // input 31 (0x1F)
+    INVALID_VALUE, // input 32 (0x20)
+    INVALID_VALUE, // input 33 (0x21)
+    INVALID_VALUE, // input 34 (0x22)
+    INVALID_VALUE, // input 35 (0x23)
+    INVALID_VALUE, // input 36 (0x24)
+    INVALID_VALUE, // input 37 (0x25)
+    INVALID_VALUE, // input 38 (0x26)
+    INVALID_VALUE, // input 39 (0x27)
+    INVALID_VALUE, // input 40 (0x28)
+    INVALID_VALUE, // input 41 (0x29)
+    INVALID_VALUE, // input 42 (0x2A)
+    INVALID_VALUE, // input 43 (0x2B)
+    INVALID_VALUE, // input 44 (0x2C)
+    62, // input 45 (0x2D char '-') => 62 (0x3E)
+    INVALID_VALUE, // input 46 (0x2E)
+    INVALID_VALUE, // input 47 (0x2F)
+    52, // input 48 (0x30 char '0') => 52 (0x34)
+    53, // input 49 (0x31 char '1') => 53 (0x35)
+    54, // input 50 (0x32 char '2') => 54 (0x36)
+    55, // input 51 (0x33 char '3') => 55 (0x37)
+    56, // input 52 (0x34 char '4') => 56 (0x38)
+    57, // input 53 (0x35 char '5') => 57 (0x39)
+    58, // input 54 (0x36 char '6') => 58 (0x3A)
+    59, // input 55 (0x37 char '7') => 59 (0x3B)
+    60, // input 56 (0x38 char '8') => 60 (0x3C)
+    61, // input 57 (0x39 char '9') => 61 (0x3D)
+    INVALID_VALUE, // input 58 (0x3A)
+    INVALID_VALUE, // input 59 (0x3B)
+    INVALID_VALUE, // input 60 (0x3C)
+    INVALID_VALUE, // input 61 (0x3D)
+    INVALID_VALUE, // input 62 (0x3E)
+    INVALID_VALUE, // input 63 (0x3F)
+    INVALID_VALUE, // input 64 (0x40)
+    0, // input 65 (0x41 char 'A') => 0 (0x0)
+    1, // input 66 (0x42 char 'B') => 1 (0x1)
+    2, // input 67 (0x43 char 'C') => 2 (0x2)
+    3, // input 68 (0x44 char 'D') => 3 (0x3)
+    4, // input 69 (0x45 char 'E') => 4 (0x4)
+    5, // input 70 (0x46 char 'F') => 5 (0x5)
+    6, // input 71 (0x47 char 'G') => 6 (0x6)
+    7, // input 72 (0x48 char 'H') => 7 (0x7)
+    8, // input 73 (0x49 char 'I') => 8 (0x8)
+    9, // input 74 (0x4A char 'J') => 9 (0x9)
+    10, // input 75 (0x4B char 'K') => 10 (0xA)
+    11, // input 76 (0x4C char 'L') => 11 (0xB)
+    12, // input 77 (0x4D char 'M') => 12 (0xC)
+    13, // input 78 (0x4E char 'N') => 13 (0xD)
+    14, // input 79 (0x4F char 'O') => 14 (0xE)
+    15, // input 80 (0x50 char 'P') => 15 (0xF)
+    16, // input 81 (0x51 char 'Q') => 16 (0x10)
+    17, // input 82 (0x52 char 'R') => 17 (0x11)
+    18, // input 83 (0x53 char 'S') => 18 (0x12)
+    19, // input 84 (0x54 char 'T') => 19 (0x13)
+    20, // input 85 (0x55 char 'U') => 20 (0x14)
+    21, // input 86 (0x56 char 'V') => 21 (0x15)
+    22, // input 87 (0x57 char 'W') => 22 (0x16)
+    23, // input 88 (0x58 char 'X') => 23 (0x17)
+    24, // input 89 (0x59 char 'Y') => 24 (0x18)
+    25, // input 90 (0x5A char 'Z') => 25 (0x19)
+    INVALID_VALUE, // input 91 (0x5B)
+    INVALID_VALUE, // input 92 (0x5C)
+    INVALID_VALUE, // input 93 (0x5D)
+    INVALID_VALUE, // input 94 (0x5E)
+    63, // input 95 (0x5F char '_') => 63 (0x3F)
+    INVALID_VALUE, // input 96 (0x60)
+    26, // input 97 (0x61 char 'a') => 26 (0x1A)
+    27, // input 98 (0x62 char 'b') => 27 (0x1B)
+    28, // input 99 (0x63 char 'c') => 28 (0x1C)
+    29, // input 100 (0x64 char 'd') => 29 (0x1D)
+    30, // input 101 (0x65 char 'e') => 30 (0x1E)
+    31, // input 102 (0x66 char 'f') => 31 (0x1F)
+    32, // input 103 (0x67 char 'g') => 32 (0x20)
+    33, // input 104 (0x68 char 'h') => 33 (0x21)
+    34, // input 105 (0x69 char 'i') => 34 (0x22)
+    35, // input 106 (0x6A char 'j') => 35 (0x23)
+    36, // input 107 (0x6B char 'k') => 36 (0x24)
+    37, // input 108 (0x6C char 'l') => 37 (0x25)
+    38, // input 109 (0x6D char 'm') => 38 (0x26)
+    39, // input 110 (0x6E char 'n') => 39 (0x27)
+    40, // input 111 (0x6F char 'o') => 40 (0x28)
+    41, // input 112 (0x70 char 'p') => 41 (0x29)
+    42, // input 113 (0x71 char 'q') => 42 (0x2A)
+    43, // input 114 (0x72 char 'r') => 43 (0x2B)
+    44, // input 115 (0x73 char 's') => 44 (0x2C)
+    45, // input 116 (0x74 char 't') => 45 (0x2D)
+    46, // input 117 (0x75 char 'u') => 46 (0x2E)
+    47, // input 118 (0x76 char 'v') => 47 (0x2F)
+    48, // input 119 (0x77 char 'w') => 48 (0x30)
+    49, // input 120 (0x78 char 'x') => 49 (0x31)
+    50, // input 121 (0x79 char 'y') => 50 (0x32)
+    51, // input 122 (0x7A char 'z') => 51 (0x33)
+    INVALID_VALUE, // input 123 (0x7B)
+    INVALID_VALUE, // input 124 (0x7C)
+    INVALID_VALUE, // input 125 (0x7D)
+    INVALID_VALUE, // input 126 (0x7E)
+    INVALID_VALUE, // input 127 (0x7F)
+    INVALID_VALUE, // input 128 (0x80)
+    INVALID_VALUE, // input 129 (0x81)
+    INVALID_VALUE, // input 130 (0x82)
+    INVALID_VALUE, // input 131 (0x83)
+    INVALID_VALUE, // input 132 (0x84)
+    INVALID_VALUE, // input 133 (0x85)
+    INVALID_VALUE, // input 134 (0x86)
+    INVALID_VALUE, // input 135 (0x87)
+    INVALID_VALUE, // input 136 (0x88)
+    INVALID_VALUE, // input 137 (0x89)
+    INVALID_VALUE, // input 138 (0x8A)
+    INVALID_VALUE, // input 139 (0x8B)
+    INVALID_VALUE, // input 140 (0x8C)
+    INVALID_VALUE, // input 141 (0x8D)
+    INVALID_VALUE, // input 142 (0x8E)
+    INVALID_VALUE, // input 143 (0x8F)
+    INVALID_VALUE, // input 144 (0x90)
+    INVALID_VALUE, // input 145 (0x91)
+    INVALID_VALUE, // input 146 (0x92)
+    INVALID_VALUE, // input 147 (0x93)
+    INVALID_VALUE, // input 148 (0x94)
+    INVALID_VALUE, // input 149 (0x95)
+    INVALID_VALUE, // input 150 (0x96)
+    INVALID_VALUE, // input 151 (0x97)
+    INVALID_VALUE, // input 152 (0x98)
+    INVALID_VALUE, // input 153 (0x99)
+    INVALID_VALUE, // input 154 (0x9A)
+    INVALID_VALUE, // input 155 (0x9B)
+    INVALID_VALUE, // input 156 (0x9C)
+    INVALID_VALUE, // input 157 (0x9D)
+    INVALID_VALUE, // input 158 (0x9E)
+    INVALID_VALUE, // input 159 (0x9F)
+    INVALID_VALUE, // input 160 (0xA0)
+    INVALID_VALUE, // input 161 (0xA1)
+    INVALID_VALUE, // input 162 (0xA2)
+    INVALID_VALUE, // input 163 (0xA3)
+    INVALID_VALUE, // input 164 (0xA4)
+    INVALID_VALUE, // input 165 (0xA5)
+    INVALID_VALUE, // input 166 (0xA6)
+    INVALID_VALUE, // input 167 (0xA7)
+    INVALID_VALUE, // input 168 (0xA8)
+    INVALID_VALUE, // input 169 (0xA9)
+    INVALID_VALUE, // input 170 (0xAA)
+    INVALID_VALUE, // input 171 (0xAB)
+    INVALID_VALUE, // input 172 (0xAC)
+    INVALID_VALUE, // input 173 (0xAD)
+    INVALID_VALUE, // input 174 (0xAE)
+    INVALID_VALUE, // input 175 (0xAF)
+    INVALID_VALUE, // input 176 (0xB0)
+    INVALID_VALUE, // input 177 (0xB1)
+    INVALID_VALUE, // input 178 (0xB2)
+    INVALID_VALUE, // input 179 (0xB3)
+    INVALID_VALUE, // input 180 (0xB4)
+    INVALID_VALUE, // input 181 (0xB5)
+    INVALID_VALUE, // input 182 (0xB6)
+    INVALID_VALUE, // input 183 (0xB7)
+    INVALID_VALUE, // input 184 (0xB8)
+    INVALID_VALUE, // input 185 (0xB9)
+    INVALID_VALUE, // input 186 (0xBA)
+    INVALID_VALUE, // input 187 (0xBB)
+    INVALID_VALUE, // input 188 (0xBC)
+    INVALID_VALUE, // input 189 (0xBD)
+    INVALID_VALUE, // input 190 (0xBE)
+    INVALID_VALUE, // input 191 (0xBF)
+    INVALID_VALUE, // input 192 (0xC0)
+    INVALID_VALUE, // input 193 (0xC1)
+    INVALID_VALUE, // input 194 (0xC2)
+    INVALID_VALUE, // input 195 (0xC3)
+    INVALID_VALUE, // input 196 (0xC4)
+    INVALID_VALUE, // input 197 (0xC5)
+    INVALID_VALUE, // input 198 (0xC6)
+    INVALID_VALUE, // input 199 (0xC7)
+    INVALID_VALUE, // input 200 (0xC8)
+    INVALID_VALUE, // input 201 (0xC9)
+    INVALID_VALUE, // input 202 (0xCA)
+    INVALID_VALUE, // input 203 (0xCB)
+    INVALID_VALUE, // input 204 (0xCC)
+    INVALID_VALUE, // input 205 (0xCD)
+    INVALID_VALUE, // input 206 (0xCE)
+    INVALID_VALUE, // input 207 (0xCF)
+    INVALID_VALUE, // input 208 (0xD0)
+    INVALID_VALUE, // input 209 (0xD1)
+    INVALID_VALUE, // input 210 (0xD2)
+    INVALID_VALUE, // input 211 (0xD3)
+    INVALID_VALUE, // input 212 (0xD4)
+    INVALID_VALUE, // input 213 (0xD5)
+    INVALID_VALUE, // input 214 (0xD6)
+    INVALID_VALUE, // input 215 (0xD7)
+    INVALID_VALUE, // input 216 (0xD8)
+    INVALID_VALUE, // input 217 (0xD9)
+    INVALID_VALUE, // input 218 (0xDA)
+    INVALID_VALUE, // input 219 (0xDB)
+    INVALID_VALUE, // input 220 (0xDC)
+    INVALID_VALUE, // input 221 (0xDD)
+    INVALID_VALUE, // input 222 (0xDE)
+    INVALID_VALUE, // input 223 (0xDF)
+    INVALID_VALUE, // input 224 (0xE0)
+    INVALID_VALUE, // input 225 (0xE1)
+    INVALID_VALUE, // input 226 (0xE2)
+    INVALID_VALUE, // input 227 (0xE3)
+    INVALID_VALUE, // input 228 (0xE4)
+    INVALID_VALUE, // input 229 (0xE5)
+    INVALID_VALUE, // input 230 (0xE6)
+    INVALID_VALUE, // input 231 (0xE7)
+    INVALID_VALUE, // input 232 (0xE8)
+    INVALID_VALUE, // input 233 (0xE9)
+    INVALID_VALUE, // input 234 (0xEA)
+    INVALID_VALUE, // input 235 (0xEB)
+    INVALID_VALUE, // input 236 (0xEC)
+    INVALID_VALUE, // input 237 (0xED)
+    INVALID_VALUE, // input 238 (0xEE)
+    INVALID_VALUE, // input 239 (0xEF)
+    INVALID_VALUE, // input 240 (0xF0)
+    INVALID_VALUE, // input 241 (0xF1)
+    INVALID_VALUE, // input 242 (0xF2)
+    INVALID_VALUE, // input 243 (0xF3)
+    INVALID_VALUE, // input 244 (0xF4)
+    INVALID_VALUE, // input 245 (0xF5)
+    INVALID_VALUE, // input 246 (0xF6)
+    INVALID_VALUE, // input 247 (0xF7)
+    INVALID_VALUE, // input 248 (0xF8)
+    INVALID_VALUE, // input 249 (0xF9)
+    INVALID_VALUE, // input 250 (0xFA)
+    INVALID_VALUE, // input 251 (0xFB)
+    INVALID_VALUE, // input 252 (0xFC)
+    INVALID_VALUE, // input 253 (0xFD)
+    INVALID_VALUE, // input 254 (0xFE)
+    INVALID_VALUE, // input 255 (0xFF)
+];
+#[rustfmt::skip]
+pub const CRYPT_ENCODE: &[u8; 64] = &[
+    46, // input 0 (0x0) => '.' (0x2E)
+    47, // input 1 (0x1) => '/' (0x2F)
+    48, // input 2 (0x2) => '0' (0x30)
+    49, // input 3 (0x3) => '1' (0x31)
+    50, // input 4 (0x4) => '2' (0x32)
+    51, // input 5 (0x5) => '3' (0x33)
+    52, // input 6 (0x6) => '4' (0x34)
+    53, // input 7 (0x7) => '5' (0x35)
+    54, // input 8 (0x8) => '6' (0x36)
+    55, // input 9 (0x9) => '7' (0x37)
+    56, // input 10 (0xA) => '8' (0x38)
+    57, // input 11 (0xB) => '9' (0x39)
+    65, // input 12 (0xC) => 'A' (0x41)
+    66, // input 13 (0xD) => 'B' (0x42)
+    67, // input 14 (0xE) => 'C' (0x43)
+    68, // input 15 (0xF) => 'D' (0x44)
+    69, // input 16 (0x10) => 'E' (0x45)
+    70, // input 17 (0x11) => 'F' (0x46)
+    71, // input 18 (0x12) => 'G' (0x47)
+    72, // input 19 (0x13) => 'H' (0x48)
+    73, // input 20 (0x14) => 'I' (0x49)
+    74, // input 21 (0x15) => 'J' (0x4A)
+    75, // input 22 (0x16) => 'K' (0x4B)
+    76, // input 23 (0x17) => 'L' (0x4C)
+    77, // input 24 (0x18) => 'M' (0x4D)
+    78, // input 25 (0x19) => 'N' (0x4E)
+    79, // input 26 (0x1A) => 'O' (0x4F)
+    80, // input 27 (0x1B) => 'P' (0x50)
+    81, // input 28 (0x1C) => 'Q' (0x51)
+    82, // input 29 (0x1D) => 'R' (0x52)
+    83, // input 30 (0x1E) => 'S' (0x53)
+    84, // input 31 (0x1F) => 'T' (0x54)
+    85, // input 32 (0x20) => 'U' (0x55)
+    86, // input 33 (0x21) => 'V' (0x56)
+    87, // input 34 (0x22) => 'W' (0x57)
+    88, // input 35 (0x23) => 'X' (0x58)
+    89, // input 36 (0x24) => 'Y' (0x59)
+    90, // input 37 (0x25) => 'Z' (0x5A)
+    97, // input 38 (0x26) => 'a' (0x61)
+    98, // input 39 (0x27) => 'b' (0x62)
+    99, // input 40 (0x28) => 'c' (0x63)
+    100, // input 41 (0x29) => 'd' (0x64)
+    101, // input 42 (0x2A) => 'e' (0x65)
+    102, // input 43 (0x2B) => 'f' (0x66)
+    103, // input 44 (0x2C) => 'g' (0x67)
+    104, // input 45 (0x2D) => 'h' (0x68)
+    105, // input 46 (0x2E) => 'i' (0x69)
+    106, // input 47 (0x2F) => 'j' (0x6A)
+    107, // input 48 (0x30) => 'k' (0x6B)
+    108, // input 49 (0x31) => 'l' (0x6C)
+    109, // input 50 (0x32) => 'm' (0x6D)
+    110, // input 51 (0x33) => 'n' (0x6E)
+    111, // input 52 (0x34) => 'o' (0x6F)
+    112, // input 53 (0x35) => 'p' (0x70)
+    113, // input 54 (0x36) => 'q' (0x71)
+    114, // input 55 (0x37) => 'r' (0x72)
+    115, // input 56 (0x38) => 's' (0x73)
+    116, // input 57 (0x39) => 't' (0x74)
+    117, // input 58 (0x3A) => 'u' (0x75)
+    118, // input 59 (0x3B) => 'v' (0x76)
+    119, // input 60 (0x3C) => 'w' (0x77)
+    120, // input 61 (0x3D) => 'x' (0x78)
+    121, // input 62 (0x3E) => 'y' (0x79)
+    122, // input 63 (0x3F) => 'z' (0x7A)
+];
+#[rustfmt::skip]
+pub const CRYPT_DECODE: &[u8; 256] = &[
+    INVALID_VALUE, // input 0 (0x0)
+    INVALID_VALUE, // input 1 (0x1)
+    INVALID_VALUE, // input 2 (0x2)
+    INVALID_VALUE, // input 3 (0x3)
+    INVALID_VALUE, // input 4 (0x4)
+    INVALID_VALUE, // input 5 (0x5)
+    INVALID_VALUE, // input 6 (0x6)
+    INVALID_VALUE, // input 7 (0x7)
+    INVALID_VALUE, // input 8 (0x8)
+    INVALID_VALUE, // input 9 (0x9)
+    INVALID_VALUE, // input 10 (0xA)
+    INVALID_VALUE, // input 11 (0xB)
+    INVALID_VALUE, // input 12 (0xC)
+    INVALID_VALUE, // input 13 (0xD)
+    INVALID_VALUE, // input 14 (0xE)
+    INVALID_VALUE, // input 15 (0xF)
+    INVALID_VALUE, // input 16 (0x10)
+    INVALID_VALUE, // input 17 (0x11)
+    INVALID_VALUE, // input 18 (0x12)
+    INVALID_VALUE, // input 19 (0x13)
+    INVALID_VALUE, // input 20 (0x14)
+    INVALID_VALUE, // input 21 (0x15)
+    INVALID_VALUE, // input 22 (0x16)
+    INVALID_VALUE, // input 23 (0x17)
+    INVALID_VALUE, // input 24 (0x18)
+    INVALID_VALUE, // input 25 (0x19)
+    INVALID_VALUE, // input 26 (0x1A)
+    INVALID_VALUE, // input 27 (0x1B)
+    INVALID_VALUE, // input 28 (0x1C)
+    INVALID_VALUE, // input 29 (0x1D)
+    INVALID_VALUE, // input 30 (0x1E)
+    INVALID_VALUE, // input 31 (0x1F)
+    INVALID_VALUE, // input 32 (0x20)
+    INVALID_VALUE, // input 33 (0x21)
+    INVALID_VALUE, // input 34 (0x22)
+    INVALID_VALUE, // input 35 (0x23)
+    INVALID_VALUE, // input 36 (0x24)
+    INVALID_VALUE, // input 37 (0x25)
+    INVALID_VALUE, // input 38 (0x26)
+    INVALID_VALUE, // input 39 (0x27)
+    INVALID_VALUE, // input 40 (0x28)
+    INVALID_VALUE, // input 41 (0x29)
+    INVALID_VALUE, // input 42 (0x2A)
+    INVALID_VALUE, // input 43 (0x2B)
+    INVALID_VALUE, // input 44 (0x2C)
+    INVALID_VALUE, // input 45 (0x2D)
+    0, // input 46 (0x2E char '.') => 0 (0x0)
+    1, // input 47 (0x2F char '/') => 1 (0x1)
+    2, // input 48 (0x30 char '0') => 2 (0x2)
+    3, // input 49 (0x31 char '1') => 3 (0x3)
+    4, // input 50 (0x32 char '2') => 4 (0x4)
+    5, // input 51 (0x33 char '3') => 5 (0x5)
+    6, // input 52 (0x34 char '4') => 6 (0x6)
+    7, // input 53 (0x35 char '5') => 7 (0x7)
+    8, // input 54 (0x36 char '6') => 8 (0x8)
+    9, // input 55 (0x37 char '7') => 9 (0x9)
+    10, // input 56 (0x38 char '8') => 10 (0xA)
+    11, // input 57 (0x39 char '9') => 11 (0xB)
+    INVALID_VALUE, // input 58 (0x3A)
+    INVALID_VALUE, // input 59 (0x3B)
+    INVALID_VALUE, // input 60 (0x3C)
+    INVALID_VALUE, // input 61 (0x3D)
+    INVALID_VALUE, // input 62 (0x3E)
+    INVALID_VALUE, // input 63 (0x3F)
+    INVALID_VALUE, // input 64 (0x40)
+    12, // input 65 (0x41 char 'A') => 12 (0xC)
+    13, // input 66 (0x42 char 'B') => 13 (0xD)
+    14, // input 67 (0x43 char 'C') => 14 (0xE)
+    15, // input 68 (0x44 char 'D') => 15 (0xF)
+    16, // input 69 (0x45 char 'E') => 16 (0x10)
+    17, // input 70 (0x46 char 'F') => 17 (0x11)
+    18, // input 71 (0x47 char 'G') => 18 (0x12)
+    19, // input 72 (0x48 char 'H') => 19 (0x13)
+    20, // input 73 (0x49 char 'I') => 20 (0x14)
+    21, // input 74 (0x4A char 'J') => 21 (0x15)
+    22, // input 75 (0x4B char 'K') => 22 (0x16)
+    23, // input 76 (0x4C char 'L') => 23 (0x17)
+    24, // input 77 (0x4D char 'M') => 24 (0x18)
+    25, // input 78 (0x4E char 'N') => 25 (0x19)
+    26, // input 79 (0x4F char 'O') => 26 (0x1A)
+    27, // input 80 (0x50 char 'P') => 27 (0x1B)
+    28, // input 81 (0x51 char 'Q') => 28 (0x1C)
+    29, // input 82 (0x52 char 'R') => 29 (0x1D)
+    30, // input 83 (0x53 char 'S') => 30 (0x1E)
+    31, // input 84 (0x54 char 'T') => 31 (0x1F)
+    32, // input 85 (0x55 char 'U') => 32 (0x20)
+    33, // input 86 (0x56 char 'V') => 33 (0x21)
+    34, // input 87 (0x57 char 'W') => 34 (0x22)
+    35, // input 88 (0x58 char 'X') => 35 (0x23)
+    36, // input 89 (0x59 char 'Y') => 36 (0x24)
+    37, // input 90 (0x5A char 'Z') => 37 (0x25)
+    INVALID_VALUE, // input 91 (0x5B)
+    INVALID_VALUE, // input 92 (0x5C)
+    INVALID_VALUE, // input 93 (0x5D)
+    INVALID_VALUE, // input 94 (0x5E)
+    INVALID_VALUE, // input 95 (0x5F)
+    INVALID_VALUE, // input 96 (0x60)
+    38, // input 97 (0x61 char 'a') => 38 (0x26)
+    39, // input 98 (0x62 char 'b') => 39 (0x27)
+    40, // input 99 (0x63 char 'c') => 40 (0x28)
+    41, // input 100 (0x64 char 'd') => 41 (0x29)
+    42, // input 101 (0x65 char 'e') => 42 (0x2A)
+    43, // input 102 (0x66 char 'f') => 43 (0x2B)
+    44, // input 103 (0x67 char 'g') => 44 (0x2C)
+    45, // input 104 (0x68 char 'h') => 45 (0x2D)
+    46, // input 105 (0x69 char 'i') => 46 (0x2E)
+    47, // input 106 (0x6A char 'j') => 47 (0x2F)
+    48, // input 107 (0x6B char 'k') => 48 (0x30)
+    49, // input 108 (0x6C char 'l') => 49 (0x31)
+    50, // input 109 (0x6D char 'm') => 50 (0x32)
+    51, // input 110 (0x6E char 'n') => 51 (0x33)
+    52, // input 111 (0x6F char 'o') => 52 (0x34)
+    53, // input 112 (0x70 char 'p') => 53 (0x35)
+    54, // input 113 (0x71 char 'q') => 54 (0x36)
+    55, // input 114 (0x72 char 'r') => 55 (0x37)
+    56, // input 115 (0x73 char 's') => 56 (0x38)
+    57, // input 116 (0x74 char 't') => 57 (0x39)
+    58, // input 117 (0x75 char 'u') => 58 (0x3A)
+    59, // input 118 (0x76 char 'v') => 59 (0x3B)
+    60, // input 119 (0x77 char 'w') => 60 (0x3C)
+    61, // input 120 (0x78 char 'x') => 61 (0x3D)
+    62, // input 121 (0x79 char 'y') => 62 (0x3E)
+    63, // input 122 (0x7A char 'z') => 63 (0x3F)
+    INVALID_VALUE, // input 123 (0x7B)
+    INVALID_VALUE, // input 124 (0x7C)
+    INVALID_VALUE, // input 125 (0x7D)
+    INVALID_VALUE, // input 126 (0x7E)
+    INVALID_VALUE, // input 127 (0x7F)
+    INVALID_VALUE, // input 128 (0x80)
+    INVALID_VALUE, // input 129 (0x81)
+    INVALID_VALUE, // input 130 (0x82)
+    INVALID_VALUE, // input 131 (0x83)
+    INVALID_VALUE, // input 132 (0x84)
+    INVALID_VALUE, // input 133 (0x85)
+    INVALID_VALUE, // input 134 (0x86)
+    INVALID_VALUE, // input 135 (0x87)
+    INVALID_VALUE, // input 136 (0x88)
+    INVALID_VALUE, // input 137 (0x89)
+    INVALID_VALUE, // input 138 (0x8A)
+    INVALID_VALUE, // input 139 (0x8B)
+    INVALID_VALUE, // input 140 (0x8C)
+    INVALID_VALUE, // input 141 (0x8D)
+    INVALID_VALUE, // input 142 (0x8E)
+    INVALID_VALUE, // input 143 (0x8F)
+    INVALID_VALUE, // input 144 (0x90)
+    INVALID_VALUE, // input 145 (0x91)
+    INVALID_VALUE, // input 146 (0x92)
+    INVALID_VALUE, // input 147 (0x93)
+    INVALID_VALUE, // input 148 (0x94)
+    INVALID_VALUE, // input 149 (0x95)
+    INVALID_VALUE, // input 150 (0x96)
+    INVALID_VALUE, // input 151 (0x97)
+    INVALID_VALUE, // input 152 (0x98)
+    INVALID_VALUE, // input 153 (0x99)
+    INVALID_VALUE, // input 154 (0x9A)
+    INVALID_VALUE, // input 155 (0x9B)
+    INVALID_VALUE, // input 156 (0x9C)
+    INVALID_VALUE, // input 157 (0x9D)
+    INVALID_VALUE, // input 158 (0x9E)
+    INVALID_VALUE, // input 159 (0x9F)
+    INVALID_VALUE, // input 160 (0xA0)
+    INVALID_VALUE, // input 161 (0xA1)
+    INVALID_VALUE, // input 162 (0xA2)
+    INVALID_VALUE, // input 163 (0xA3)
+    INVALID_VALUE, // input 164 (0xA4)
+    INVALID_VALUE, // input 165 (0xA5)
+    INVALID_VALUE, // input 166 (0xA6)
+    INVALID_VALUE, // input 167 (0xA7)
+    INVALID_VALUE, // input 168 (0xA8)
+    INVALID_VALUE, // input 169 (0xA9)
+    INVALID_VALUE, // input 170 (0xAA)
+    INVALID_VALUE, // input 171 (0xAB)
+    INVALID_VALUE, // input 172 (0xAC)
+    INVALID_VALUE, // input 173 (0xAD)
+    INVALID_VALUE, // input 174 (0xAE)
+    INVALID_VALUE, // input 175 (0xAF)
+    INVALID_VALUE, // input 176 (0xB0)
+    INVALID_VALUE, // input 177 (0xB1)
+    INVALID_VALUE, // input 178 (0xB2)
+    INVALID_VALUE, // input 179 (0xB3)
+    INVALID_VALUE, // input 180 (0xB4)
+    INVALID_VALUE, // input 181 (0xB5)
+    INVALID_VALUE, // input 182 (0xB6)
+    INVALID_VALUE, // input 183 (0xB7)
+    INVALID_VALUE, // input 184 (0xB8)
+    INVALID_VALUE, // input 185 (0xB9)
+    INVALID_VALUE, // input 186 (0xBA)
+    INVALID_VALUE, // input 187 (0xBB)
+    INVALID_VALUE, // input 188 (0xBC)
+    INVALID_VALUE, // input 189 (0xBD)
+    INVALID_VALUE, // input 190 (0xBE)
+    INVALID_VALUE, // input 191 (0xBF)
+    INVALID_VALUE, // input 192 (0xC0)
+    INVALID_VALUE, // input 193 (0xC1)
+    INVALID_VALUE, // input 194 (0xC2)
+    INVALID_VALUE, // input 195 (0xC3)
+    INVALID_VALUE, // input 196 (0xC4)
+    INVALID_VALUE, // input 197 (0xC5)
+    INVALID_VALUE, // input 198 (0xC6)
+    INVALID_VALUE, // input 199 (0xC7)
+    INVALID_VALUE, // input 200 (0xC8)
+    INVALID_VALUE, // input 201 (0xC9)
+    INVALID_VALUE, // input 202 (0xCA)
+    INVALID_VALUE, // input 203 (0xCB)
+    INVALID_VALUE, // input 204 (0xCC)
+    INVALID_VALUE, // input 205 (0xCD)
+    INVALID_VALUE, // input 206 (0xCE)
+    INVALID_VALUE, // input 207 (0xCF)
+    INVALID_VALUE, // input 208 (0xD0)
+    INVALID_VALUE, // input 209 (0xD1)
+    INVALID_VALUE, // input 210 (0xD2)
+    INVALID_VALUE, // input 211 (0xD3)
+    INVALID_VALUE, // input 212 (0xD4)
+    INVALID_VALUE, // input 213 (0xD5)
+    INVALID_VALUE, // input 214 (0xD6)
+    INVALID_VALUE, // input 215 (0xD7)
+    INVALID_VALUE, // input 216 (0xD8)
+    INVALID_VALUE, // input 217 (0xD9)
+    INVALID_VALUE, // input 218 (0xDA)
+    INVALID_VALUE, // input 219 (0xDB)
+    INVALID_VALUE, // input 220 (0xDC)
+    INVALID_VALUE, // input 221 (0xDD)
+    INVALID_VALUE, // input 222 (0xDE)
+    INVALID_VALUE, // input 223 (0xDF)
+    INVALID_VALUE, // input 224 (0xE0)
+    INVALID_VALUE, // input 225 (0xE1)
+    INVALID_VALUE, // input 226 (0xE2)
+    INVALID_VALUE, // input 227 (0xE3)
+    INVALID_VALUE, // input 228 (0xE4)
+    INVALID_VALUE, // input 229 (0xE5)
+    INVALID_VALUE, // input 230 (0xE6)
+    INVALID_VALUE, // input 231 (0xE7)
+    INVALID_VALUE, // input 232 (0xE8)
+    INVALID_VALUE, // input 233 (0xE9)
+    INVALID_VALUE, // input 234 (0xEA)
+    INVALID_VALUE, // input 235 (0xEB)
+    INVALID_VALUE, // input 236 (0xEC)
+    INVALID_VALUE, // input 237 (0xED)
+    INVALID_VALUE, // input 238 (0xEE)
+    INVALID_VALUE, // input 239 (0xEF)
+    INVALID_VALUE, // input 240 (0xF0)
+    INVALID_VALUE, // input 241 (0xF1)
+    INVALID_VALUE, // input 242 (0xF2)
+    INVALID_VALUE, // input 243 (0xF3)
+    INVALID_VALUE, // input 244 (0xF4)
+    INVALID_VALUE, // input 245 (0xF5)
+    INVALID_VALUE, // input 246 (0xF6)
+    INVALID_VALUE, // input 247 (0xF7)
+    INVALID_VALUE, // input 248 (0xF8)
+    INVALID_VALUE, // input 249 (0xF9)
+    INVALID_VALUE, // input 250 (0xFA)
+    INVALID_VALUE, // input 251 (0xFB)
+    INVALID_VALUE, // input 252 (0xFC)
+    INVALID_VALUE, // input 253 (0xFD)
+    INVALID_VALUE, // input 254 (0xFE)
+    INVALID_VALUE, // input 255 (0xFF)
+];
+#[rustfmt::skip]
+pub const BCRYPT_ENCODE: &[u8; 64] = &[
+    46, // input 0 (0x0) => '.' (0x2E)
+    47, // input 1 (0x1) => '/' (0x2F)
+    65, // input 2 (0x2) => 'A' (0x41)
+    66, // input 3 (0x3) => 'B' (0x42)
+    67, // input 4 (0x4) => 'C' (0x43)
+    68, // input 5 (0x5) => 'D' (0x44)
+    69, // input 6 (0x6) => 'E' (0x45)
+    70, // input 7 (0x7) => 'F' (0x46)
+    71, // input 8 (0x8) => 'G' (0x47)
+    72, // input 9 (0x9) => 'H' (0x48)
+    73, // input 10 (0xA) => 'I' (0x49)
+    74, // input 11 (0xB) => 'J' (0x4A)
+    75, // input 12 (0xC) => 'K' (0x4B)
+    76, // input 13 (0xD) => 'L' (0x4C)
+    77, // input 14 (0xE) => 'M' (0x4D)
+    78, // input 15 (0xF) => 'N' (0x4E)
+    79, // input 16 (0x10) => 'O' (0x4F)
+    80, // input 17 (0x11) => 'P' (0x50)
+    81, // input 18 (0x12) => 'Q' (0x51)
+    82, // input 19 (0x13) => 'R' (0x52)
+    83, // input 20 (0x14) => 'S' (0x53)
+    84, // input 21 (0x15) => 'T' (0x54)
+    85, // input 22 (0x16) => 'U' (0x55)
+    86, // input 23 (0x17) => 'V' (0x56)
+    87, // input 24 (0x18) => 'W' (0x57)
+    88, // input 25 (0x19) => 'X' (0x58)
+    89, // input 26 (0x1A) => 'Y' (0x59)
+    90, // input 27 (0x1B) => 'Z' (0x5A)
+    97, // input 28 (0x1C) => 'a' (0x61)
+    98, // input 29 (0x1D) => 'b' (0x62)
+    99, // input 30 (0x1E) => 'c' (0x63)
+    100, // input 31 (0x1F) => 'd' (0x64)
+    101, // input 32 (0x20) => 'e' (0x65)
+    102, // input 33 (0x21) => 'f' (0x66)
+    103, // input 34 (0x22) => 'g' (0x67)
+    104, // input 35 (0x23) => 'h' (0x68)
+    105, // input 36 (0x24) => 'i' (0x69)
+    106, // input 37 (0x25) => 'j' (0x6A)
+    107, // input 38 (0x26) => 'k' (0x6B)
+    108, // input 39 (0x27) => 'l' (0x6C)
+    109, // input 40 (0x28) => 'm' (0x6D)
+    110, // input 41 (0x29) => 'n' (0x6E)
+    111, // input 42 (0x2A) => 'o' (0x6F)
+    112, // input 43 (0x2B) => 'p' (0x70)
+    113, // input 44 (0x2C) => 'q' (0x71)
+    114, // input 45 (0x2D) => 'r' (0x72)
+    115, // input 46 (0x2E) => 's' (0x73)
+    116, // input 47 (0x2F) => 't' (0x74)
+    117, // input 48 (0x30) => 'u' (0x75)
+    118, // input 49 (0x31) => 'v' (0x76)
+    119, // input 50 (0x32) => 'w' (0x77)
+    120, // input 51 (0x33) => 'x' (0x78)
+    121, // input 52 (0x34) => 'y' (0x79)
+    122, // input 53 (0x35) => 'z' (0x7A)
+    48, // input 54 (0x36) => '0' (0x30)
+    49, // input 55 (0x37) => '1' (0x31)
+    50, // input 56 (0x38) => '2' (0x32)
+    51, // input 57 (0x39) => '3' (0x33)
+    52, // input 58 (0x3A) => '4' (0x34)
+    53, // input 59 (0x3B) => '5' (0x35)
+    54, // input 60 (0x3C) => '6' (0x36)
+    55, // input 61 (0x3D) => '7' (0x37)
+    56, // input 62 (0x3E) => '8' (0x38)
+    57, // input 63 (0x3F) => '9' (0x39)
+];
+#[rustfmt::skip]
+pub const BCRYPT_DECODE: &[u8; 256] = &[
+    INVALID_VALUE, // input 0 (0x0)
+    INVALID_VALUE, // input 1 (0x1)
+    INVALID_VALUE, // input 2 (0x2)
+    INVALID_VALUE, // input 3 (0x3)
+    INVALID_VALUE, // input 4 (0x4)
+    INVALID_VALUE, // input 5 (0x5)
+    INVALID_VALUE, // input 6 (0x6)
+    INVALID_VALUE, // input 7 (0x7)
+    INVALID_VALUE, // input 8 (0x8)
+    INVALID_VALUE, // input 9 (0x9)
+    INVALID_VALUE, // input 10 (0xA)
+    INVALID_VALUE, // input 11 (0xB)
+    INVALID_VALUE, // input 12 (0xC)
+    INVALID_VALUE, // input 13 (0xD)
+    INVALID_VALUE, // input 14 (0xE)
+    INVALID_VALUE, // input 15 (0xF)
+    INVALID_VALUE, // input 16 (0x10)
+    INVALID_VALUE, // input 17 (0x11)
+    INVALID_VALUE, // input 18 (0x12)
+    INVALID_VALUE, // input 19 (0x13)
+    INVALID_VALUE, // input 20 (0x14)
+    INVALID_VALUE, // input 21 (0x15)
+    INVALID_VALUE, // input 22 (0x16)
+    INVALID_VALUE, // input 23 (0x17)
+    INVALID_VALUE, // input 24 (0x18)
+    INVALID_VALUE, // input 25 (0x19)
+    INVALID_VALUE, // input 26 (0x1A)
+    INVALID_VALUE, // input 27 (0x1B)
+    INVALID_VALUE, // input 28 (0x1C)
+    INVALID_VALUE, // input 29 (0x1D)
+    INVALID_VALUE, // input 30 (0x1E)
+    INVALID_VALUE, // input 31 (0x1F)
+    INVALID_VALUE, // input 32 (0x20)
+    INVALID_VALUE, // input 33 (0x21)
+    INVALID_VALUE, // input 34 (0x22)
+    INVALID_VALUE, // input 35 (0x23)
+    INVALID_VALUE, // input 36 (0x24)
+    INVALID_VALUE, // input 37 (0x25)
+    INVALID_VALUE, // input 38 (0x26)
+    INVALID_VALUE, // input 39 (0x27)
+    INVALID_VALUE, // input 40 (0x28)
+    INVALID_VALUE, // input 41 (0x29)
+    INVALID_VALUE, // input 42 (0x2A)
+    INVALID_VALUE, // input 43 (0x2B)
+    INVALID_VALUE, // input 44 (0x2C)
+    INVALID_VALUE, // input 45 (0x2D)
+    0, // input 46 (0x2E char '.') => 0 (0x0)
+    1, // input 47 (0x2F char '/') => 1 (0x1)
+    54, // input 48 (0x30 char '0') => 54 (0x36)
+    55, // input 49 (0x31 char '1') => 55 (0x37)
+    56, // input 50 (0x32 char '2') => 56 (0x38)
+    57, // input 51 (0x33 char '3') => 57 (0x39)
+    58, // input 52 (0x34 char '4') => 58 (0x3A)
+    59, // input 53 (0x35 char '5') => 59 (0x3B)
+    60, // input 54 (0x36 char '6') => 60 (0x3C)
+    61, // input 55 (0x37 char '7') => 61 (0x3D)
+    62, // input 56 (0x38 char '8') => 62 (0x3E)
+    63, // input 57 (0x39 char '9') => 63 (0x3F)
+    INVALID_VALUE, // input 58 (0x3A)
+    INVALID_VALUE, // input 59 (0x3B)
+    INVALID_VALUE, // input 60 (0x3C)
+    INVALID_VALUE, // input 61 (0x3D)
+    INVALID_VALUE, // input 62 (0x3E)
+    INVALID_VALUE, // input 63 (0x3F)
+    INVALID_VALUE, // input 64 (0x40)
+    2, // input 65 (0x41 char 'A') => 2 (0x2)
+    3, // input 66 (0x42 char 'B') => 3 (0x3)
+    4, // input 67 (0x43 char 'C') => 4 (0x4)
+    5, // input 68 (0x44 char 'D') => 5 (0x5)
+    6, // input 69 (0x45 char 'E') => 6 (0x6)
+    7, // input 70 (0x46 char 'F') => 7 (0x7)
+    8, // input 71 (0x47 char 'G') => 8 (0x8)
+    9, // input 72 (0x48 char 'H') => 9 (0x9)
+    10, // input 73 (0x49 char 'I') => 10 (0xA)
+    11, // input 74 (0x4A char 'J') => 11 (0xB)
+    12, // input 75 (0x4B char 'K') => 12 (0xC)
+    13, // input 76 (0x4C char 'L') => 13 (0xD)
+    14, // input 77 (0x4D char 'M') => 14 (0xE)
+    15, // input 78 (0x4E char 'N') => 15 (0xF)
+    16, // input 79 (0x4F char 'O') => 16 (0x10)
+    17, // input 80 (0x50 char 'P') => 17 (0x11)
+    18, // input 81 (0x51 char 'Q') => 18 (0x12)
+    19, // input 82 (0x52 char 'R') => 19 (0x13)
+    20, // input 83 (0x53 char 'S') => 20 (0x14)
+    21, // input 84 (0x54 char 'T') => 21 (0x15)
+    22, // input 85 (0x55 char 'U') => 22 (0x16)
+    23, // input 86 (0x56 char 'V') => 23 (0x17)
+    24, // input 87 (0x57 char 'W') => 24 (0x18)
+    25, // input 88 (0x58 char 'X') => 25 (0x19)
+    26, // input 89 (0x59 char 'Y') => 26 (0x1A)
+    27, // input 90 (0x5A char 'Z') => 27 (0x1B)
+    INVALID_VALUE, // input 91 (0x5B)
+    INVALID_VALUE, // input 92 (0x5C)
+    INVALID_VALUE, // input 93 (0x5D)
+    INVALID_VALUE, // input 94 (0x5E)
+    INVALID_VALUE, // input 95 (0x5F)
+    INVALID_VALUE, // input 96 (0x60)
+    28, // input 97 (0x61 char 'a') => 28 (0x1C)
+    29, // input 98 (0x62 char 'b') => 29 (0x1D)
+    30, // input 99 (0x63 char 'c') => 30 (0x1E)
+    31, // input 100 (0x64 char 'd') => 31 (0x1F)
+    32, // input 101 (0x65 char 'e') => 32 (0x20)
+    33, // input 102 (0x66 char 'f') => 33 (0x21)
+    34, // input 103 (0x67 char 'g') => 34 (0x22)
+    35, // input 104 (0x68 char 'h') => 35 (0x23)
+    36, // input 105 (0x69 char 'i') => 36 (0x24)
+    37, // input 106 (0x6A char 'j') => 37 (0x25)
+    38, // input 107 (0x6B char 'k') => 38 (0x26)
+    39, // input 108 (0x6C char 'l') => 39 (0x27)
+    40, // input 109 (0x6D char 'm') => 40 (0x28)
+    41, // input 110 (0x6E char 'n') => 41 (0x29)
+    42, // input 111 (0x6F char 'o') => 42 (0x2A)
+    43, // input 112 (0x70 char 'p') => 43 (0x2B)
+    44, // input 113 (0x71 char 'q') => 44 (0x2C)
+    45, // input 114 (0x72 char 'r') => 45 (0x2D)
+    46, // input 115 (0x73 char 's') => 46 (0x2E)
+    47, // input 116 (0x74 char 't') => 47 (0x2F)
+    48, // input 117 (0x75 char 'u') => 48 (0x30)
+    49, // input 118 (0x76 char 'v') => 49 (0x31)
+    50, // input 119 (0x77 char 'w') => 50 (0x32)
+    51, // input 120 (0x78 char 'x') => 51 (0x33)
+    52, // input 121 (0x79 char 'y') => 52 (0x34)
+    53, // input 122 (0x7A char 'z') => 53 (0x35)
+    INVALID_VALUE, // input 123 (0x7B)
+    INVALID_VALUE, // input 124 (0x7C)
+    INVALID_VALUE, // input 125 (0x7D)
+    INVALID_VALUE, // input 126 (0x7E)
+    INVALID_VALUE, // input 127 (0x7F)
+    INVALID_VALUE, // input 128 (0x80)
+    INVALID_VALUE, // input 129 (0x81)
+    INVALID_VALUE, // input 130 (0x82)
+    INVALID_VALUE, // input 131 (0x83)
+    INVALID_VALUE, // input 132 (0x84)
+    INVALID_VALUE, // input 133 (0x85)
+    INVALID_VALUE, // input 134 (0x86)
+    INVALID_VALUE, // input 135 (0x87)
+    INVALID_VALUE, // input 136 (0x88)
+    INVALID_VALUE, // input 137 (0x89)
+    INVALID_VALUE, // input 138 (0x8A)
+    INVALID_VALUE, // input 139 (0x8B)
+    INVALID_VALUE, // input 140 (0x8C)
+    INVALID_VALUE, // input 141 (0x8D)
+    INVALID_VALUE, // input 142 (0x8E)
+    INVALID_VALUE, // input 143 (0x8F)
+    INVALID_VALUE, // input 144 (0x90)
+    INVALID_VALUE, // input 145 (0x91)
+    INVALID_VALUE, // input 146 (0x92)
+    INVALID_VALUE, // input 147 (0x93)
+    INVALID_VALUE, // input 148 (0x94)
+    INVALID_VALUE, // input 149 (0x95)
+    INVALID_VALUE, // input 150 (0x96)
+    INVALID_VALUE, // input 151 (0x97)
+    INVALID_VALUE, // input 152 (0x98)
+    INVALID_VALUE, // input 153 (0x99)
+    INVALID_VALUE, // input 154 (0x9A)
+    INVALID_VALUE, // input 155 (0x9B)
+    INVALID_VALUE, // input 156 (0x9C)
+    INVALID_VALUE, // input 157 (0x9D)
+    INVALID_VALUE, // input 158 (0x9E)
+    INVALID_VALUE, // input 159 (0x9F)
+    INVALID_VALUE, // input 160 (0xA0)
+    INVALID_VALUE, // input 161 (0xA1)
+    INVALID_VALUE, // input 162 (0xA2)
+    INVALID_VALUE, // input 163 (0xA3)
+    INVALID_VALUE, // input 164 (0xA4)
+    INVALID_VALUE, // input 165 (0xA5)
+    INVALID_VALUE, // input 166 (0xA6)
+    INVALID_VALUE, // input 167 (0xA7)
+    INVALID_VALUE, // input 168 (0xA8)
+    INVALID_VALUE, // input 169 (0xA9)
+    INVALID_VALUE, // input 170 (0xAA)
+    INVALID_VALUE, // input 171 (0xAB)
+    INVALID_VALUE, // input 172 (0xAC)
+    INVALID_VALUE, // input 173 (0xAD)
+    INVALID_VALUE, // input 174 (0xAE)
+    INVALID_VALUE, // input 175 (0xAF)
+    INVALID_VALUE, // input 176 (0xB0)
+    INVALID_VALUE, // input 177 (0xB1)
+    INVALID_VALUE, // input 178 (0xB2)
+    INVALID_VALUE, // input 179 (0xB3)
+    INVALID_VALUE, // input 180 (0xB4)
+    INVALID_VALUE, // input 181 (0xB5)
+    INVALID_VALUE, // input 182 (0xB6)
+    INVALID_VALUE, // input 183 (0xB7)
+    INVALID_VALUE, // input 184 (0xB8)
+    INVALID_VALUE, // input 185 (0xB9)
+    INVALID_VALUE, // input 186 (0xBA)
+    INVALID_VALUE, // input 187 (0xBB)
+    INVALID_VALUE, // input 188 (0xBC)
+    INVALID_VALUE, // input 189 (0xBD)
+    INVALID_VALUE, // input 190 (0xBE)
+    INVALID_VALUE, // input 191 (0xBF)
+    INVALID_VALUE, // input 192 (0xC0)
+    INVALID_VALUE, // input 193 (0xC1)
+    INVALID_VALUE, // input 194 (0xC2)
+    INVALID_VALUE, // input 195 (0xC3)
+    INVALID_VALUE, // input 196 (0xC4)
+    INVALID_VALUE, // input 197 (0xC5)
+    INVALID_VALUE, // input 198 (0xC6)
+    INVALID_VALUE, // input 199 (0xC7)
+    INVALID_VALUE, // input 200 (0xC8)
+    INVALID_VALUE, // input 201 (0xC9)
+    INVALID_VALUE, // input 202 (0xCA)
+    INVALID_VALUE, // input 203 (0xCB)
+    INVALID_VALUE, // input 204 (0xCC)
+    INVALID_VALUE, // input 205 (0xCD)
+    INVALID_VALUE, // input 206 (0xCE)
+    INVALID_VALUE, // input 207 (0xCF)
+    INVALID_VALUE, // input 208 (0xD0)
+    INVALID_VALUE, // input 209 (0xD1)
+    INVALID_VALUE, // input 210 (0xD2)
+    INVALID_VALUE, // input 211 (0xD3)
+    INVALID_VALUE, // input 212 (0xD4)
+    INVALID_VALUE, // input 213 (0xD5)
+    INVALID_VALUE, // input 214 (0xD6)
+    INVALID_VALUE, // input 215 (0xD7)
+    INVALID_VALUE, // input 216 (0xD8)
+    INVALID_VALUE, // input 217 (0xD9)
+    INVALID_VALUE, // input 218 (0xDA)
+    INVALID_VALUE, // input 219 (0xDB)
+    INVALID_VALUE, // input 220 (0xDC)
+    INVALID_VALUE, // input 221 (0xDD)
+    INVALID_VALUE, // input 222 (0xDE)
+    INVALID_VALUE, // input 223 (0xDF)
+    INVALID_VALUE, // input 224 (0xE0)
+    INVALID_VALUE, // input 225 (0xE1)
+    INVALID_VALUE, // input 226 (0xE2)
+    INVALID_VALUE, // input 227 (0xE3)
+    INVALID_VALUE, // input 228 (0xE4)
+    INVALID_VALUE, // input 229 (0xE5)
+    INVALID_VALUE, // input 230 (0xE6)
+    INVALID_VALUE, // input 231 (0xE7)
+    INVALID_VALUE, // input 232 (0xE8)
+    INVALID_VALUE, // input 233 (0xE9)
+    INVALID_VALUE, // input 234 (0xEA)
+    INVALID_VALUE, // input 235 (0xEB)
+    INVALID_VALUE, // input 236 (0xEC)
+    INVALID_VALUE, // input 237 (0xED)
+    INVALID_VALUE, // input 238 (0xEE)
+    INVALID_VALUE, // input 239 (0xEF)
+    INVALID_VALUE, // input 240 (0xF0)
+    INVALID_VALUE, // input 241 (0xF1)
+    INVALID_VALUE, // input 242 (0xF2)
+    INVALID_VALUE, // input 243 (0xF3)
+    INVALID_VALUE, // input 244 (0xF4)
+    INVALID_VALUE, // input 245 (0xF5)
+    INVALID_VALUE, // input 246 (0xF6)
+    INVALID_VALUE, // input 247 (0xF7)
+    INVALID_VALUE, // input 248 (0xF8)
+    INVALID_VALUE, // input 249 (0xF9)
+    INVALID_VALUE, // input 250 (0xFA)
+    INVALID_VALUE, // input 251 (0xFB)
+    INVALID_VALUE, // input 252 (0xFC)
+    INVALID_VALUE, // input 253 (0xFD)
+    INVALID_VALUE, // input 254 (0xFE)
+    INVALID_VALUE, // input 255 (0xFF)
+];
+#[rustfmt::skip]
+pub const IMAP_MUTF7_ENCODE: &[u8; 64] = &[
+    65, // input 0 (0x0) => 'A' (0x41)
+    66, // input 1 (0x1) => 'B' (0x42)
+    67, // input 2 (0x2) => 'C' (0x43)
+    68, // input 3 (0x3) => 'D' (0x44)
+    69, // input 4 (0x4) => 'E' (0x45)
+    70, // input 5 (0x5) => 'F' (0x46)
+    71, // input 6 (0x6) => 'G' (0x47)
+    72, // input 7 (0x7) => 'H' (0x48)
+    73, // input 8 (0x8) => 'I' (0x49)
+    74, // input 9 (0x9) => 'J' (0x4A)
+    75, // input 10 (0xA) => 'K' (0x4B)
+    76, // input 11 (0xB) => 'L' (0x4C)
+    77, // input 12 (0xC) => 'M' (0x4D)
+    78, // input 13 (0xD) => 'N' (0x4E)
+    79, // input 14 (0xE) => 'O' (0x4F)
+    80, // input 15 (0xF) => 'P' (0x50)
+    81, // input 16 (0x10) => 'Q' (0x51)
+    82, // input 17 (0x11) => 'R' (0x52)
+    83, // input 18 (0x12) => 'S' (0x53)
+    84, // input 19 (0x13) => 'T' (0x54)
+    85, // input 20 (0x14) => 'U' (0x55)
+    86, // input 21 (0x15) => 'V' (0x56)
+    87, // input 22 (0x16) => 'W' (0x57)
+    88, // input 23 (0x17) => 'X' (0x58)
+    89, // input 24 (0x18) => 'Y' (0x59)
+    90, // input 25 (0x19) => 'Z' (0x5A)
+    97, // input 26 (0x1A) => 'a' (0x61)
+    98, // input 27 (0x1B) => 'b' (0x62)
+    99, // input 28 (0x1C) => 'c' (0x63)
+    100, // input 29 (0x1D) => 'd' (0x64)
+    101, // input 30 (0x1E) => 'e' (0x65)
+    102, // input 31 (0x1F) => 'f' (0x66)
+    103, // input 32 (0x20) => 'g' (0x67)
+    104, // input 33 (0x21) => 'h' (0x68)
+    105, // input 34 (0x22) => 'i' (0x69)
+    106, // input 35 (0x23) => 'j' (0x6A)
+    107, // input 36 (0x24) => 'k' (0x6B)
+    108, // input 37 (0x25) => 'l' (0x6C)
+    109, // input 38 (0x26) => 'm' (0x6D)
+    110, // input 39 (0x27) => 'n' (0x6E)
+    111, // input 40 (0x28) => 'o' (0x6F)
+    112, // input 41 (0x29) => 'p' (0x70)
+    113, // input 42 (0x2A) => 'q' (0x71)
+    114, // input 43 (0x2B) => 'r' (0x72)
+    115, // input 44 (0x2C) => 's' (0x73)
+    116, // input 45 (0x2D) => 't' (0x74)
+    117, // input 46 (0x2E) => 'u' (0x75)
+    118, // input 47 (0x2F) => 'v' (0x76)
+    119, // input 48 (0x30) => 'w' (0x77)
+    120, // input 49 (0x31) => 'x' (0x78)
+    121, // input 50 (0x32) => 'y' (0x79)
+    122, // input 51 (0x33) => 'z' (0x7A)
+    48, // input 52 (0x34) => '0' (0x30)
+    49, // input 53 (0x35) => '1' (0x31)
+    50, // input 54 (0x36) => '2' (0x32)
+    51, // input 55 (0x37) => '3' (0x33)
+    52, // input 56 (0x38) => '4' (0x34)
+    53, // input 57 (0x39) => '5' (0x35)
+    54, // input 58 (0x3A) => '6' (0x36)
+    55, // input 59 (0x3B) => '7' (0x37)
+    56, // input 60 (0x3C) => '8' (0x38)
+    57, // input 61 (0x3D) => '9' (0x39)
+    43, // input 62 (0x3E) => '+' (0x2B)
+    44, // input 63 (0x3F) => ',' (0x2C)
+];
+#[rustfmt::skip]
+pub const IMAP_MUTF7_DECODE: &[u8; 256] = &[
+    INVALID_VALUE, // input 0 (0x0)
+    INVALID_VALUE, // input 1 (0x1)
+    INVALID_VALUE, // input 2 (0x2)
+    INVALID_VALUE, // input 3 (0x3)
+    INVALID_VALUE, // input 4 (0x4)
+    INVALID_VALUE, // input 5 (0x5)
+    INVALID_VALUE, // input 6 (0x6)
+    INVALID_VALUE, // input 7 (0x7)
+    INVALID_VALUE, // input 8 (0x8)
+    INVALID_VALUE, // input 9 (0x9)
+    INVALID_VALUE, // input 10 (0xA)
+    INVALID_VALUE, // input 11 (0xB)
+    INVALID_VALUE, // input 12 (0xC)
+    INVALID_VALUE, // input 13 (0xD)
+    INVALID_VALUE, // input 14 (0xE)
+    INVALID_VALUE, // input 15 (0xF)
+    INVALID_VALUE, // input 16 (0x10)
+    INVALID_VALUE, // input 17 (0x11)
+    INVALID_VALUE, // input 18 (0x12)
+    INVALID_VALUE, // input 19 (0x13)
+    INVALID_VALUE, // input 20 (0x14)
+    INVALID_VALUE, // input 21 (0x15)
+    INVALID_VALUE, // input 22 (0x16)
+    INVALID_VALUE, // input 23 (0x17)
+    INVALID_VALUE, // input 24 (0x18)
+    INVALID_VALUE, // input 25 (0x19)
+    INVALID_VALUE, // input 26 (0x1A)
+    INVALID_VALUE, // input 27 (0x1B)
+    INVALID_VALUE, // input 28 (0x1C)
+    INVALID_VALUE, // input 29 (0x1D)
+    INVALID_VALUE, // input 30 (0x1E)
+    INVALID_VALUE, // input 31 (0x1F)
+    INVALID_VALUE, // input 32 (0x20)
+    INVALID_VALUE, // input 33 (0x21)
+    INVALID_VALUE, // input 34 (0x22)
+    INVALID_VALUE, // input 35 (0x23)
+    INVALID_VALUE, // input 36 (0x24)
+    INVALID_VALUE, // input 37 (0x25)
+    INVALID_VALUE, // input 38 (0x26)
+    INVALID_VALUE, // input 39 (0x27)
+    INVALID_VALUE, // input 40 (0x28)
+    INVALID_VALUE, // input 41 (0x29)
+    INVALID_VALUE, // input 42 (0x2A)
+    62, // input 43 (0x2B char '+') => 62 (0x3E)
+    63, // input 44 (0x2C char ',') => 63 (0x3F)
+    INVALID_VALUE, // input 45 (0x2D)
+    INVALID_VALUE, // input 46 (0x2E)
+    INVALID_VALUE, // input 47 (0x2F)
+    52, // input 48 (0x30 char '0') => 52 (0x34)
+    53, // input 49 (0x31 char '1') => 53 (0x35)
+    54, // input 50 (0x32 char '2') => 54 (0x36)
+    55, // input 51 (0x33 char '3') => 55 (0x37)
+    56, // input 52 (0x34 char '4') => 56 (0x38)
+    57, // input 53 (0x35 char '5') => 57 (0x39)
+    58, // input 54 (0x36 char '6') => 58 (0x3A)
+    59, // input 55 (0x37 char '7') => 59 (0x3B)
+    60, // input 56 (0x38 char '8') => 60 (0x3C)
+    61, // input 57 (0x39 char '9') => 61 (0x3D)
+    INVALID_VALUE, // input 58 (0x3A)
+    INVALID_VALUE, // input 59 (0x3B)
+    INVALID_VALUE, // input 60 (0x3C)
+    INVALID_VALUE, // input 61 (0x3D)
+    INVALID_VALUE, // input 62 (0x3E)
+    INVALID_VALUE, // input 63 (0x3F)
+    INVALID_VALUE, // input 64 (0x40)
+    0, // input 65 (0x41 char 'A') => 0 (0x0)
+    1, // input 66 (0x42 char 'B') => 1 (0x1)
+    2, // input 67 (0x43 char 'C') => 2 (0x2)
+    3, // input 68 (0x44 char 'D') => 3 (0x3)
+    4, // input 69 (0x45 char 'E') => 4 (0x4)
+    5, // input 70 (0x46 char 'F') => 5 (0x5)
+    6, // input 71 (0x47 char 'G') => 6 (0x6)
+    7, // input 72 (0x48 char 'H') => 7 (0x7)
+    8, // input 73 (0x49 char 'I') => 8 (0x8)
+    9, // input 74 (0x4A char 'J') => 9 (0x9)
+    10, // input 75 (0x4B char 'K') => 10 (0xA)
+    11, // input 76 (0x4C char 'L') => 11 (0xB)
+    12, // input 77 (0x4D char 'M') => 12 (0xC)
+    13, // input 78 (0x4E char 'N') => 13 (0xD)
+    14, // input 79 (0x4F char 'O') => 14 (0xE)
+    15, // input 80 (0x50 char 'P') => 15 (0xF)
+    16, // input 81 (0x51 char 'Q') => 16 (0x10)
+    17, // input 82 (0x52 char 'R') => 17 (0x11)
+    18, // input 83 (0x53 char 'S') => 18 (0x12)
+    19, // input 84 (0x54 char 'T') => 19 (0x13)
+    20, // input 85 (0x55 char 'U') => 20 (0x14)
+    21, // input 86 (0x56 char 'V') => 21 (0x15)
+    22, // input 87 (0x57 char 'W') => 22 (0x16)
+    23, // input 88 (0x58 char 'X') => 23 (0x17)
+    24, // input 89 (0x59 char 'Y') => 24 (0x18)
+    25, // input 90 (0x5A char 'Z') => 25 (0x19)
+    INVALID_VALUE, // input 91 (0x5B)
+    INVALID_VALUE, // input 92 (0x5C)
+    INVALID_VALUE, // input 93 (0x5D)
+    INVALID_VALUE, // input 94 (0x5E)
+    INVALID_VALUE, // input 95 (0x5F)
+    INVALID_VALUE, // input 96 (0x60)
+    26, // input 97 (0x61 char 'a') => 26 (0x1A)
+    27, // input 98 (0x62 char 'b') => 27 (0x1B)
+    28, // input 99 (0x63 char 'c') => 28 (0x1C)
+    29, // input 100 (0x64 char 'd') => 29 (0x1D)
+    30, // input 101 (0x65 char 'e') => 30 (0x1E)
+    31, // input 102 (0x66 char 'f') => 31 (0x1F)
+    32, // input 103 (0x67 char 'g') => 32 (0x20)
+    33, // input 104 (0x68 char 'h') => 33 (0x21)
+    34, // input 105 (0x69 char 'i') => 34 (0x22)
+    35, // input 106 (0x6A char 'j') => 35 (0x23)
+    36, // input 107 (0x6B char 'k') => 36 (0x24)
+    37, // input 108 (0x6C char 'l') => 37 (0x25)
+    38, // input 109 (0x6D char 'm') => 38 (0x26)
+    39, // input 110 (0x6E char 'n') => 39 (0x27)
+    40, // input 111 (0x6F char 'o') => 40 (0x28)
+    41, // input 112 (0x70 char 'p') => 41 (0x29)
+    42, // input 113 (0x71 char 'q') => 42 (0x2A)
+    43, // input 114 (0x72 char 'r') => 43 (0x2B)
+    44, // input 115 (0x73 char 's') => 44 (0x2C)
+    45, // input 116 (0x74 char 't') => 45 (0x2D)
+    46, // input 117 (0x75 char 'u') => 46 (0x2E)
+    47, // input 118 (0x76 char 'v') => 47 (0x2F)
+    48, // input 119 (0x77 char 'w') => 48 (0x30)
+    49, // input 120 (0x78 char 'x') => 49 (0x31)
+    50, // input 121 (0x79 char 'y') => 50 (0x32)
+    51, // input 122 (0x7A char 'z') => 51 (0x33)
+    INVALID_VALUE, // input 123 (0x7B)
+    INVALID_VALUE, // input 124 (0x7C)
+    INVALID_VALUE, // input 125 (0x7D)
+    INVALID_VALUE, // input 126 (0x7E)
+    INVALID_VALUE, // input 127 (0x7F)
+    INVALID_VALUE, // input 128 (0x80)
+    INVALID_VALUE, // input 129 (0x81)
+    INVALID_VALUE, // input 130 (0x82)
+    INVALID_VALUE, // input 131 (0x83)
+    INVALID_VALUE, // input 132 (0x84)
+    INVALID_VALUE, // input 133 (0x85)
+    INVALID_VALUE, // input 134 (0x86)
+    INVALID_VALUE, // input 135 (0x87)
+    INVALID_VALUE, // input 136 (0x88)
+    INVALID_VALUE, // input 137 (0x89)
+    INVALID_VALUE, // input 138 (0x8A)
+    INVALID_VALUE, // input 139 (0x8B)
+    INVALID_VALUE, // input 140 (0x8C)
+    INVALID_VALUE, // input 141 (0x8D)
+    INVALID_VALUE, // input 142 (0x8E)
+    INVALID_VALUE, // input 143 (0x8F)
+    INVALID_VALUE, // input 144 (0x90)
+    INVALID_VALUE, // input 145 (0x91)
+    INVALID_VALUE, // input 146 (0x92)
+    INVALID_VALUE, // input 147 (0x93)
+    INVALID_VALUE, // input 148 (0x94)
+    INVALID_VALUE, // input 149 (0x95)
+    INVALID_VALUE, // input 150 (0x96)
+    INVALID_VALUE, // input 151 (0x97)
+    INVALID_VALUE, // input 152 (0x98)
+    INVALID_VALUE, // input 153 (0x99)
+    INVALID_VALUE, // input 154 (0x9A)
+    INVALID_VALUE, // input 155 (0x9B)
+    INVALID_VALUE, // input 156 (0x9C)
+    INVALID_VALUE, // input 157 (0x9D)
+    INVALID_VALUE, // input 158 (0x9E)
+    INVALID_VALUE, // input 159 (0x9F)
+    INVALID_VALUE, // input 160 (0xA0)
+    INVALID_VALUE, // input 161 (0xA1)
+    INVALID_VALUE, // input 162 (0xA2)
+    INVALID_VALUE, // input 163 (0xA3)
+    INVALID_VALUE, // input 164 (0xA4)
+    INVALID_VALUE, // input 165 (0xA5)
+    INVALID_VALUE, // input 166 (0xA6)
+    INVALID_VALUE, // input 167 (0xA7)
+    INVALID_VALUE, // input 168 (0xA8)
+    INVALID_VALUE, // input 169 (0xA9)
+    INVALID_VALUE, // input 170 (0xAA)
+    INVALID_VALUE, // input 171 (0xAB)
+    INVALID_VALUE, // input 172 (0xAC)
+    INVALID_VALUE, // input 173 (0xAD)
+    INVALID_VALUE, // input 174 (0xAE)
+    INVALID_VALUE, // input 175 (0xAF)
+    INVALID_VALUE, // input 176 (0xB0)
+    INVALID_VALUE, // input 177 (0xB1)
+    INVALID_VALUE, // input 178 (0xB2)
+    INVALID_VALUE, // input 179 (0xB3)
+    INVALID_VALUE, // input 180 (0xB4)
+    INVALID_VALUE, // input 181 (0xB5)
+    INVALID_VALUE, // input 182 (0xB6)
+    INVALID_VALUE, // input 183 (0xB7)
+    INVALID_VALUE, // input 184 (0xB8)
+    INVALID_VALUE, // input 185 (0xB9)
+    INVALID_VALUE, // input 186 (0xBA)
+    INVALID_VALUE, // input 187 (0xBB)
+    INVALID_VALUE, // input 188 (0xBC)
+    INVALID_VALUE, // input 189 (0xBD)
+    INVALID_VALUE, // input 190 (0xBE)
+    INVALID_VALUE, // input 191 (0xBF)
+    INVALID_VALUE, // input 192 (0xC0)
+    INVALID_VALUE, // input 193 (0xC1)
+    INVALID_VALUE, // input 194 (0xC2)
+    INVALID_VALUE, // input 195 (0xC3)
+    INVALID_VALUE, // input 196 (0xC4)
+    INVALID_VALUE, // input 197 (0xC5)
+    INVALID_VALUE, // input 198 (0xC6)
+    INVALID_VALUE, // input 199 (0xC7)
+    INVALID_VALUE, // input 200 (0xC8)
+    INVALID_VALUE, // input 201 (0xC9)
+    INVALID_VALUE, // input 202 (0xCA)
+    INVALID_VALUE, // input 203 (0xCB)
+    INVALID_VALUE, // input 204 (0xCC)
+    INVALID_VALUE, // input 205 (0xCD)
+    INVALID_VALUE, // input 206 (0xCE)
+    INVALID_VALUE, // input 207 (0xCF)
+    INVALID_VALUE, // input 208 (0xD0)
+    INVALID_VALUE, // input 209 (0xD1)
+    INVALID_VALUE, // input 210 (0xD2)
+    INVALID_VALUE, // input 211 (0xD3)
+    INVALID_VALUE, // input 212 (0xD4)
+    INVALID_VALUE, // input 213 (0xD5)
+    INVALID_VALUE, // input 214 (0xD6)
+    INVALID_VALUE, // input 215 (0xD7)
+    INVALID_VALUE, // input 216 (0xD8)
+    INVALID_VALUE, // input 217 (0xD9)
+    INVALID_VALUE, // input 218 (0xDA)
+    INVALID_VALUE, // input 219 (0xDB)
+    INVALID_VALUE, // input 220 (0xDC)
+    INVALID_VALUE, // input 221 (0xDD)
+    INVALID_VALUE, // input 222 (0xDE)
+    INVALID_VALUE, // input 223 (0xDF)
+    INVALID_VALUE, // input 224 (0xE0)
+    INVALID_VALUE, // input 225 (0xE1)
+    INVALID_VALUE, // input 226 (0xE2)
+    INVALID_VALUE, // input 227 (0xE3)
+    INVALID_VALUE, // input 228 (0xE4)
+    INVALID_VALUE, // input 229 (0xE5)
+    INVALID_VALUE, // input 230 (0xE6)
+    INVALID_VALUE, // input 231 (0xE7)
+    INVALID_VALUE, // input 232 (0xE8)
+    INVALID_VALUE, // input 233 (0xE9)
+    INVALID_VALUE, // input 234 (0xEA)
+    INVALID_VALUE, // input 235 (0xEB)
+    INVALID_VALUE, // input 236 (0xEC)
+    INVALID_VALUE, // input 237 (0xED)
+    INVALID_VALUE, // input 238 (0xEE)
+    INVALID_VALUE, // input 239 (0xEF)
+    INVALID_VALUE, // input 240 (0xF0)
+    INVALID_VALUE, // input 241 (0xF1)
+    INVALID_VALUE, // input 242 (0xF2)
+    INVALID_VALUE, // input 243 (0xF3)
+    INVALID_VALUE, // input 244 (0xF4)
+    INVALID_VALUE, // input 245 (0xF5)
+    INVALID_VALUE, // input 246 (0xF6)
+    INVALID_VALUE, // input 247 (0xF7)
+    INVALID_VALUE, // input 248 (0xF8)
+    INVALID_VALUE, // input 249 (0xF9)
+    INVALID_VALUE, // input 250 (0xFA)
+    INVALID_VALUE, // input 251 (0xFB)
+    INVALID_VALUE, // input 252 (0xFC)
+    INVALID_VALUE, // input 253 (0xFD)
+    INVALID_VALUE, // input 254 (0xFE)
+    INVALID_VALUE, // input 255 (0xFF)
+];
+#[rustfmt::skip]
+pub const BINHEX_ENCODE: &[u8; 64] = &[
+    33, // input 0 (0x0) => '!' (0x21)
+    34, // input 1 (0x1) => '"' (0x22)
+    35, // input 2 (0x2) => '#' (0x23)
+    36, // input 3 (0x3) => '$' (0x24)
+    37, // input 4 (0x4) => '%' (0x25)
+    38, // input 5 (0x5) => '&' (0x26)
+    39, // input 6 (0x6) => ''' (0x27)
+    40, // input 7 (0x7) => '(' (0x28)
+    41, // input 8 (0x8) => ')' (0x29)
+    42, // input 9 (0x9) => '*' (0x2A)
+    43, // input 10 (0xA) => '+' (0x2B)
+    44, // input 11 (0xB) => ',' (0x2C)
+    45, // input 12 (0xC) => '-' (0x2D)
+    48, // input 13 (0xD) => '0' (0x30)
+    49, // input 14 (0xE) => '1' (0x31)
+    50, // input 15 (0xF) => '2' (0x32)
+    51, // input 16 (0x10) => '3' (0x33)
+    52, // input 17 (0x11) => '4' (0x34)
+    53, // input 18 (0x12) => '5' (0x35)
+    54, // input 19 (0x13) => '6' (0x36)
+    55, // input 20 (0x14) => '7' (0x37)
+    56, // input 21 (0x15) => '8' (0x38)
+    57, // input 22 (0x16) => '9' (0x39)
+    64, // input 23 (0x17) => '@' (0x40)
+    65, // input 24 (0x18) => 'A' (0x41)
+    66, // input 25 (0x19) => 'B' (0x42)
+    67, // input 26 (0x1A) => 'C' (0x43)
+    68, // input 27 (0x1B) => 'D' (0x44)
+    69, // input 28 (0x1C) => 'E' (0x45)
+    70, // input 29 (0x1D) => 'F' (0x46)
+    71, // input 30 (0x1E) => 'G' (0x47)
+    72, // input 31 (0x1F) => 'H' (0x48)
+    73, // input 32 (0x20) => 'I' (0x49)
+    74, // input 33 (0x21) => 'J' (0x4A)
+    75, // input 34 (0x22) => 'K' (0x4B)
+    76, // input 35 (0x23) => 'L' (0x4C)
+    77, // input 36 (0x24) => 'M' (0x4D)
+    78, // input 37 (0x25) => 'N' (0x4E)
+    80, // input 38 (0x26) => 'P' (0x50)
+    81, // input 39 (0x27) => 'Q' (0x51)
+    82, // input 40 (0x28) => 'R' (0x52)
+    83, // input 41 (0x29) => 'S' (0x53)
+    84, // input 42 (0x2A) => 'T' (0x54)
+    85, // input 43 (0x2B) => 'U' (0x55)
+    86, // input 44 (0x2C) => 'V' (0x56)
+    88, // input 45 (0x2D) => 'X' (0x58)
+    89, // input 46 (0x2E) => 'Y' (0x59)
+    90, // input 47 (0x2F) => 'Z' (0x5A)
+    91, // input 48 (0x30) => '[' (0x5B)
+    96, // input 49 (0x31) => '`' (0x60)
+    97, // input 50 (0x32) => 'a' (0x61)
+    98, // input 51 (0x33) => 'b' (0x62)
+    99, // input 52 (0x34) => 'c' (0x63)
+    100, // input 53 (0x35) => 'd' (0x64)
+    101, // input 54 (0x36) => 'e' (0x65)
+    104, // input 55 (0x37) => 'h' (0x68)
+    105, // input 56 (0x38) => 'i' (0x69)
+    106, // input 57 (0x39) => 'j' (0x6A)
+    107, // input 58 (0x3A) => 'k' (0x6B)
+    108, // input 59 (0x3B) => 'l' (0x6C)
+    109, // input 60 (0x3C) => 'm' (0x6D)
+    112, // input 61 (0x3D) => 'p' (0x70)
+    113, // input 62 (0x3E) => 'q' (0x71)
+    114, // input 63 (0x3F) => 'r' (0x72)
+];
+#[rustfmt::skip]
+pub const BINHEX_DECODE: &[u8; 256] = &[
+    INVALID_VALUE, // input 0 (0x0)
+    INVALID_VALUE, // input 1 (0x1)
+    INVALID_VALUE, // input 2 (0x2)
+    INVALID_VALUE, // input 3 (0x3)
+    INVALID_VALUE, // input 4 (0x4)
+    INVALID_VALUE, // input 5 (0x5)
+    INVALID_VALUE, // input 6 (0x6)
+    INVALID_VALUE, // input 7 (0x7)
+    INVALID_VALUE, // input 8 (0x8)
+    INVALID_VALUE, // input 9 (0x9)
+    INVALID_VALUE, // input 10 (0xA)
+    INVALID_VALUE, // input 11 (0xB)
+    INVALID_VALUE, // input 12 (0xC)
+    INVALID_VALUE, // input 13 (0xD)
+    INVALID_VALUE, // input 14 (0xE)
+    INVALID_VALUE, // input 15 (0xF)
+    INVALID_VALUE, // input 16 (0x10)
+    INVALID_VALUE, // input 17 (0x11)
+    INVALID_VALUE, // input 18 (0x12)
+    INVALID_VALUE, // input 19 (0x13)
+    INVALID_VALUE, // input 20 (0x14)
+    INVALID_VALUE, // input 21 (0x15)
+    INVALID_VALUE, // input 22 (0x16)
+    INVALID_VALUE, // input 23 (0x17)
+    INVALID_VALUE, // input 24 (0x18)
+    INVALID_VALUE, // input 25 (0x19)
+    INVALID_VALUE, // input 26 (0x1A)
+    INVALID_VALUE, // input 27 (0x1B)
+    INVALID_VALUE, // input 28 (0x1C)
+    INVALID_VALUE, // input 29 (0x1D)
+    INVALID_VALUE, // input 30 (0x1E)
+    INVALID_VALUE, // input 31 (0x1F)
+    INVALID_VALUE, // input 32 (0x20)
+    0, // input 33 (0x21 char '!') => 0 (0x0)
+    1, // input 34 (0x22 char '"') => 1 (0x1)
+    2, // input 35 (0x23 char '#') => 2 (0x2)
+    3, // input 36 (0x24 char '$') => 3 (0x3)
+    4, // input 37 (0x25 char '%') => 4 (0x4)
+    5, // input 38 (0x26 char '&') => 5 (0x5)
+    6, // input 39 (0x27 char ''') => 6 (0x6)
+    7, // input 40 (0x28 char '(') => 7 (0x7)
+    8, // input 41 (0x29 char ')') => 8 (0x8)
+    9, // input 42 (0x2A char '*') => 9 (0x9)
+    10, // input 43 (0x2B char '+') => 10 (0xA)
+    11, // input 44 (0x2C char ',') => 11 (0xB)
+    12, // input 45 (0x2D char '-') => 12 (0xC)
+    INVALID_VALUE, // input 46 (0x2E)
+    INVALID_VALUE, // input 47 (0x2F)
+    13, // input 48 (0x30 char '0') => 13 (0xD)
+    14, // input 49 (0x31 char '1') => 14 (0xE)
+    15, // input 50 (0x32 char '2') => 15 (0xF)
+    16, // input 51 (0x33 char '3') => 16 (0x10)
+    17, // input 52 (0x34 char '4') => 17 (0x11)
+    18, // input 53 (0x35 char '5') => 18 (0x12)
+    19, // input 54 (0x36 char '6') => 19 (0x13)
+    20, // input 55 (0x37 char '7') => 20 (0x14)
+    21, // input 56 (0x38 char '8') => 21 (0x15)
+    22, // input 57 (0x39 char '9') => 22 (0x16)
+    INVALID_VALUE, // input 58 (0x3A)
+    INVALID_VALUE, // input 59 (0x3B)
+    INVALID_VALUE, // input 60 (0x3C)
+    INVALID_VALUE, // input 61 (0x3D)
+    INVALID_VALUE, // input 62 (0x3E)
+    INVALID_VALUE, // input 63 (0x3F)
+    23, // input 64 (0x40 char '@') => 23 (0x17)
+    24, // input 65 (0x41 char 'A') => 24 (0x18)
+    25, // input 66 (0x42 char 'B') => 25 (0x19)
+    26, // input 67 (0x43 char 'C') => 26 (0x1A)
+    27, // input 68 (0x44 char 'D') => 27 (0x1B)
+    28, // input 69 (0x45 char 'E') => 28 (0x1C)
+    29, // input 70 (0x46 char 'F') => 29 (0x1D)
+    30, // input 71 (0x47 char 'G') => 30 (0x1E)
+    31, // input 72 (0x48 char 'H') => 31 (0x1F)
+    32, // input 73 (0x49 char 'I') => 32 (0x20)
+    33, // input 74 (0x4A char 'J') => 33 (0x21)
+    34, // input 75 (0x4B char 'K') => 34 (0x22)
+    35, // input 76 (0x4C char 'L') => 35 (0x23)
+    36, // input 77 (0x4D char 'M') => 36 (0x24)
+    37, // input 78 (0x4E char 'N') => 37 (0x25)
+    INVALID_VALUE, // input 79 (0x4F)
+    38, // input 80 (0x50 char 'P') => 38 (0x26)
+    39, // input 81 (0x51 char 'Q') => 39 (0x27)
+    40, // input 82 (0x52 char 'R') => 40 (0x28)
+    41, // input 83 (0x53 char 'S') => 41 (0x29)
+    42, // input 84 (0x54 char 'T') => 42 (0x2A)
+    43, // input 85 (0x55 char 'U') => 43 (0x2B)
+    44, // input 86 (0x56 char 'V') => 44 (0x2C)
+    INVALID_VALUE, // input 87 (0x57)
+    45, // input 88 (0x58 char 'X') => 45 (0x2D)
+    46, // input 89 (0x59 char 'Y') => 46 (0x2E)
+    47, // input 90 (0x5A char 'Z') => 47 (0x2F)
+    48, // input 91 (0x5B char '[') => 48 (0x30)
+    INVALID_VALUE, // input 92 (0x5C)
+    INVALID_VALUE, // input 93 (0x5D)
+    INVALID_VALUE, // input 94 (0x5E)
+    INVALID_VALUE, // input 95 (0x5F)
+    49, // input 96 (0x60 char '`') => 49 (0x31)
+    50, // input 97 (0x61 char 'a') => 50 (0x32)
+    51, // input 98 (0x62 char 'b') => 51 (0x33)
+    52, // input 99 (0x63 char 'c') => 52 (0x34)
+    53, // input 100 (0x64 char 'd') => 53 (0x35)
+    54, // input 101 (0x65 char 'e') => 54 (0x36)
+    INVALID_VALUE, // input 102 (0x66)
+    INVALID_VALUE, // input 103 (0x67)
+    55, // input 104 (0x68 char 'h') => 55 (0x37)
+    56, // input 105 (0x69 char 'i') => 56 (0x38)
+    57, // input 106 (0x6A char 'j') => 57 (0x39)
+    58, // input 107 (0x6B char 'k') => 58 (0x3A)
+    59, // input 108 (0x6C char 'l') => 59 (0x3B)
+    60, // input 109 (0x6D char 'm') => 60 (0x3C)
+    INVALID_VALUE, // input 110 (0x6E)
+    INVALID_VALUE, // input 111 (0x6F)
+    61, // input 112 (0x70 char 'p') => 61 (0x3D)
+    62, // input 113 (0x71 char 'q') => 62 (0x3E)
+    63, // input 114 (0x72 char 'r') => 63 (0x3F)
+    INVALID_VALUE, // input 115 (0x73)
+    INVALID_VALUE, // input 116 (0x74)
+    INVALID_VALUE, // input 117 (0x75)
+    INVALID_VALUE, // input 118 (0x76)
+    INVALID_VALUE, // input 119 (0x77)
+    INVALID_VALUE, // input 120 (0x78)
+    INVALID_VALUE, // input 121 (0x79)
+    INVALID_VALUE, // input 122 (0x7A)
+    INVALID_VALUE, // input 123 (0x7B)
+    INVALID_VALUE, // input 124 (0x7C)
+    INVALID_VALUE, // input 125 (0x7D)
+    INVALID_VALUE, // input 126 (0x7E)
+    INVALID_VALUE, // input 127 (0x7F)
+    INVALID_VALUE, // input 128 (0x80)
+    INVALID_VALUE, // input 129 (0x81)
+    INVALID_VALUE, // input 130 (0x82)
+    INVALID_VALUE, // input 131 (0x83)
+    INVALID_VALUE, // input 132 (0x84)
+    INVALID_VALUE, // input 133 (0x85)
+    INVALID_VALUE, // input 134 (0x86)
+    INVALID_VALUE, // input 135 (0x87)
+    INVALID_VALUE, // input 136 (0x88)
+    INVALID_VALUE, // input 137 (0x89)
+    INVALID_VALUE, // input 138 (0x8A)
+    INVALID_VALUE, // input 139 (0x8B)
+    INVALID_VALUE, // input 140 (0x8C)
+    INVALID_VALUE, // input 141 (0x8D)
+    INVALID_VALUE, // input 142 (0x8E)
+    INVALID_VALUE, // input 143 (0x8F)
+    INVALID_VALUE, // input 144 (0x90)
+    INVALID_VALUE, // input 145 (0x91)
+    INVALID_VALUE, // input 146 (0x92)
+    INVALID_VALUE, // input 147 (0x93)
+    INVALID_VALUE, // input 148 (0x94)
+    INVALID_VALUE, // input 149 (0x95)
+    INVALID_VALUE, // input 150 (0x96)
+    INVALID_VALUE, // input 151 (0x97)
+    INVALID_VALUE, // input 152 (0x98)
+    INVALID_VALUE, // input 153 (0x99)
+    INVALID_VALUE, // input 154 (0x9A)
+    INVALID_VALUE, // input 155 (0x9B)
+    INVALID_VALUE, // input 156 (0x9C)
+    INVALID_VALUE, // input 157 (0x9D)
+    INVALID_VALUE, // input 158 (0x9E)
+    INVALID_VALUE, // input 159 (0x9F)
+    INVALID_VALUE, // input 160 (0xA0)
+    INVALID_VALUE, // input 161 (0xA1)
+    INVALID_VALUE, // input 162 (0xA2)
+    INVALID_VALUE, // input 163 (0xA3)
+    INVALID_VALUE, // input 164 (0xA4)
+    INVALID_VALUE, // input 165 (0xA5)
+    INVALID_VALUE, // input 166 (0xA6)
+    INVALID_VALUE, // input 167 (0xA7)
+    INVALID_VALUE, // input 168 (0xA8)
+    INVALID_VALUE, // input 169 (0xA9)
+    INVALID_VALUE, // input 170 (0xAA)
+    INVALID_VALUE, // input 171 (0xAB)
+    INVALID_VALUE, // input 172 (0xAC)
+    INVALID_VALUE, // input 173 (0xAD)
+    INVALID_VALUE, // input 174 (0xAE)
+    INVALID_VALUE, // input 175 (0xAF)
+    INVALID_VALUE, // input 176 (0xB0)
+    INVALID_VALUE, // input 177 (0xB1)
+    INVALID_VALUE, // input 178 (0xB2)
+    INVALID_VALUE, // input 179 (0xB3)
+    INVALID_VALUE, // input 180 (0xB4)
+    INVALID_VALUE, // input 181 (0xB5)
+    INVALID_VALUE, // input 182 (0xB6)
+    INVALID_VALUE, // input 183 (0xB7)
+    INVALID_VALUE, // input 184 (0xB8)
+    INVALID_VALUE, // input 185 (0xB9)
+    INVALID_VALUE, // input 186 (0xBA)
+    INVALID_VALUE, // input 187 (0xBB)
+    INVALID_VALUE, // input 188 (0xBC)
+    INVALID_VALUE, // input 189 (0xBD)
+    INVALID_VALUE, // input 190 (0xBE)
+    INVALID_VALUE, // input 191 (0xBF)
+    INVALID_VALUE, // input 192 (0xC0)
+    INVALID_VALUE, // input 193 (0xC1)
+    INVALID_VALUE, // input 194 (0xC2)
+    INVALID_VALUE, // input 195 (0xC3)
+    INVALID_VALUE, // input 196 (0xC4)
+    INVALID_VALUE, // input 197 (0xC5)
+    INVALID_VALUE, // input 198 (0xC6)
+    INVALID_VALUE, // input 199 (0xC7)
+    INVALID_VALUE, // input 200 (0xC8)
+    INVALID_VALUE, // input 201 (0xC9)
+    INVALID_VALUE, // input 202 (0xCA)
+    INVALID_VALUE, // input 203 (0xCB)
+    INVALID_VALUE, // input 204 (0xCC)
+    INVALID_VALUE, // input 205 (0xCD)
+    INVALID_VALUE, // input 206 (0xCE)
+    INVALID_VALUE, // input 207 (0xCF)
+    INVALID_VALUE, // input 208 (0xD0)
+    INVALID_VALUE, // input 209 (0xD1)
+    INVALID_VALUE, // input 210 (0xD2)
+    INVALID_VALUE, // input 211 (0xD3)
+    INVALID_VALUE, // input 212 (0xD4)
+    INVALID_VALUE, // input 213 (0xD5)
+    INVALID_VALUE, // input 214 (0xD6)
+    INVALID_VALUE, // input 215 (0xD7)
+    INVALID_VALUE, // input 216 (0xD8)
+    INVALID_VALUE, // input 217 (0xD9)
+    INVALID_VALUE, // input 218 (0xDA)
+    INVALID_VALUE, // input 219 (0xDB)
+    INVALID_VALUE, // input 220 (0xDC)
+    INVALID_VALUE, // input 221 (0xDD)
+    INVALID_VALUE, // input 222 (0xDE)
+    INVALID_VALUE, // input 223 (0xDF)
+    INVALID_VALUE, // input 224 (0xE0)
+    INVALID_VALUE, // input 225 (0xE1)
+    INVALID_VALUE, // input 226 (0xE2)
+    INVALID_VALUE, // input 227 (0xE3)
+    INVALID_VALUE, // input 228 (0xE4)
+    INVALID_VALUE, // input 229 (0xE5)
+    INVALID_VALUE, // input 230 (0xE6)
+    INVALID_VALUE, // input 231 (0xE7)
+    INVALID_VALUE, // input 232 (0xE8)
+    INVALID_VALUE, // input 233 (0xE9)
+    INVALID_VALUE, // input 234 (0xEA)
+    INVALID_VALUE, // input 235 (0xEB)
+    INVALID_VALUE, // input 236 (0xEC)
+    INVALID_VALUE, // input 237 (0xED)
+    INVALID_VALUE, // input 238 (0xEE)
+    INVALID_VALUE, // input 239 (0xEF)
+    INVALID_VALUE, // input 240 (0xF0)
+    INVALID_VALUE, // input 241 (0xF1)
+    INVALID_VALUE, // input 242 (0xF2)
+    INVALID_VALUE, // input 243 (0xF3)
+    INVALID_VALUE, // input 244 (0xF4)
+    INVALID_VALUE, // input 245 (0xF5)
+    INVALID_VALUE, // input 246 (0xF6)
+    INVALID_VALUE, // input 247 (0xF7)
+    INVALID_VALUE, // input 248 (0xF8)
+    INVALID_VALUE, // input 249 (0xF9)
+    INVALID_VALUE, // input 250 (0xFA)
+    INVALID_VALUE, // input 251 (0xFB)
+    INVALID_VALUE, // input 252 (0xFC)
+    INVALID_VALUE, // input 253 (0xFD)
+    INVALID_VALUE, // input 254 (0xFE)
+    INVALID_VALUE, // input 255 (0xFF)
+];
diff -Nru cargo-0.66.0/vendor/base64/src/tests.rs cargo-0.66.0+ds1/vendor/base64/src/tests.rs
--- cargo-0.66.0/vendor/base64/src/tests.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/tests.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,81 @@
+use crate::{decode_config, encode::encoded_size, encode_config_buf, CharacterSet, Config};
+
+use std::str;
+
+use rand::{
+    distributions::{Distribution, Uniform},
+    seq::SliceRandom,
+    FromEntropy, Rng,
+};
+
+#[test]
+fn roundtrip_random_config_short() {
+    // exercise the slower encode/decode routines that operate on shorter buffers more vigorously
+    roundtrip_random_config(Uniform::new(0, 50), 10_000);
+}
+
+#[test]
+fn roundtrip_random_config_long() {
+    roundtrip_random_config(Uniform::new(0, 1000), 10_000);
+}
+
+pub fn assert_encode_sanity(encoded: &str, config: Config, input_len: usize) {
+    let input_rem = input_len % 3;
+    let expected_padding_len = if input_rem > 0 {
+        if config.pad {
+            3 - input_rem
+        } else {
+            0
+        }
+    } else {
+        0
+    };
+
+    let expected_encoded_len = encoded_size(input_len, config).unwrap();
+
+    assert_eq!(expected_encoded_len, encoded.len());
+
+    let padding_len = encoded.chars().filter(|&c| c == '=').count();
+
+    assert_eq!(expected_padding_len, padding_len);
+
+    let _ = str::from_utf8(encoded.as_bytes()).expect("Base64 should be valid utf8");
+}
+
+fn roundtrip_random_config(input_len_range: Uniform<usize>, iterations: u32) {
+    let mut input_buf: Vec<u8> = Vec::new();
+    let mut encoded_buf = String::new();
+    let mut rng = rand::rngs::SmallRng::from_entropy();
+
+    for _ in 0..iterations {
+        input_buf.clear();
+        encoded_buf.clear();
+
+        let input_len = input_len_range.sample(&mut rng);
+
+        let config = random_config(&mut rng);
+
+        for _ in 0..input_len {
+            input_buf.push(rng.gen());
+        }
+
+        encode_config_buf(&input_buf, config, &mut encoded_buf);
+
+        assert_encode_sanity(&encoded_buf, config, input_len);
+
+        assert_eq!(input_buf, decode_config(&encoded_buf, config).unwrap());
+    }
+}
+
+pub fn random_config<R: Rng>(rng: &mut R) -> Config {
+    const CHARSETS: &[CharacterSet] = &[
+        CharacterSet::UrlSafe,
+        CharacterSet::Standard,
+        CharacterSet::Crypt,
+        CharacterSet::ImapMutf7,
+        CharacterSet::BinHex,
+    ];
+    let charset = *CHARSETS.choose(rng).unwrap();
+
+    Config::new(charset, rng.gen())
+}
diff -Nru cargo-0.66.0/vendor/base64/src/write/encoder.rs cargo-0.66.0+ds1/vendor/base64/src/write/encoder.rs
--- cargo-0.66.0/vendor/base64/src/write/encoder.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/write/encoder.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,381 @@
+use crate::encode::encode_to_slice;
+use crate::{encode_config_slice, Config};
+use std::{
+    cmp, fmt,
+    io::{ErrorKind, Result, Write},
+};
+
+pub(crate) const BUF_SIZE: usize = 1024;
+/// The most bytes whose encoding will fit in `BUF_SIZE`
+const MAX_INPUT_LEN: usize = BUF_SIZE / 4 * 3;
+// 3 bytes of input = 4 bytes of base64, always (because we don't allow line wrapping)
+const MIN_ENCODE_CHUNK_SIZE: usize = 3;
+
+/// A `Write` implementation that base64 encodes data before delegating to the wrapped writer.
+///
+/// Because base64 has special handling for the end of the input data (padding, etc), there's a
+/// `finish()` method on this type that encodes any leftover input bytes and adds padding if
+/// appropriate. It's called automatically when deallocated (see the `Drop` implementation), but
+/// any error that occurs when invoking the underlying writer will be suppressed. If you want to
+/// handle such errors, call `finish()` yourself.
+///
+/// # Examples
+///
+/// ```
+/// use std::io::Write;
+///
+/// // use a vec as the simplest possible `Write` -- in real code this is probably a file, etc.
+/// let mut enc = base64::write::EncoderWriter::new(Vec::new(), base64::STANDARD);
+///
+/// // handle errors as you normally would
+/// enc.write_all(b"asdf").unwrap();
+///
+/// // could leave this out to be called by Drop, if you don't care
+/// // about handling errors or getting the delegate writer back
+/// let delegate = enc.finish().unwrap();
+///
+/// // base64 was written to the writer
+/// assert_eq!(b"YXNkZg==", &delegate[..]);
+///
+/// ```
+///
+/// # Panics
+///
+/// Calling `write()` (or related methods) or `finish()` after `finish()` has completed without
+/// error is invalid and will panic.
+///
+/// # Errors
+///
+/// Base64 encoding itself does not generate errors, but errors from the wrapped writer will be
+/// returned as per the contract of `Write`.
+///
+/// # Performance
+///
+/// It has some minor performance loss compared to encoding slices (a couple percent).
+/// It does not do any heap allocation.
+pub struct EncoderWriter<W: Write> {
+    config: Config,
+    /// Where encoded data is written to. It's an Option as it's None immediately before Drop is
+    /// called so that finish() can return the underlying writer. None implies that finish() has
+    /// been called successfully.
+    delegate: Option<W>,
+    /// Holds a partial chunk, if any, after the last `write()`, so that we may then fill the chunk
+    /// with the next `write()`, encode it, then proceed with the rest of the input normally.
+    extra_input: [u8; MIN_ENCODE_CHUNK_SIZE],
+    /// How much of `extra` is occupied, in `[0, MIN_ENCODE_CHUNK_SIZE]`.
+    extra_input_occupied_len: usize,
+    /// Buffer to encode into. May hold leftover encoded bytes from a previous write call that the underlying writer
+    /// did not write last time.
+    output: [u8; BUF_SIZE],
+    /// How much of `output` is occupied with encoded data that couldn't be written last time
+    output_occupied_len: usize,
+    /// panic safety: don't write again in destructor if writer panicked while we were writing to it
+    panicked: bool,
+}
+
+impl<W: Write> fmt::Debug for EncoderWriter<W> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "extra_input: {:?} extra_input_occupied_len:{:?} output[..5]: {:?} output_occupied_len: {:?}",
+            self.extra_input,
+            self.extra_input_occupied_len,
+            &self.output[0..5],
+            self.output_occupied_len
+        )
+    }
+}
+
+impl<W: Write> EncoderWriter<W> {
+    /// Create a new encoder that will write to the provided delegate writer `w`.
+    pub fn new(w: W, config: Config) -> EncoderWriter<W> {
+        EncoderWriter {
+            config,
+            delegate: Some(w),
+            extra_input: [0u8; MIN_ENCODE_CHUNK_SIZE],
+            extra_input_occupied_len: 0,
+            output: [0u8; BUF_SIZE],
+            output_occupied_len: 0,
+            panicked: false,
+        }
+    }
+
+    /// Encode all remaining buffered data and write it, including any trailing incomplete input
+    /// triples and associated padding.
+    ///
+    /// Once this succeeds, no further writes or calls to this method are allowed.
+    ///
+    /// This may write to the delegate writer multiple times if the delegate writer does not accept
+    /// all input provided to its `write` each invocation.
+    ///
+    /// If you don't care about error handling, it is not necessary to call this function, as the
+    /// equivalent finalization is done by the Drop impl.
+    ///
+    /// Returns the writer that this was constructed around.
+    ///
+    /// # Errors
+    ///
+    /// The first error that is not of `ErrorKind::Interrupted` will be returned.
+    pub fn finish(&mut self) -> Result<W> {
+        // If we could consume self in finish(), we wouldn't have to worry about this case, but
+        // finish() is retryable in the face of I/O errors, so we can't consume here.
+        if self.delegate.is_none() {
+            panic!("Encoder has already had finish() called")
+        };
+
+        self.write_final_leftovers()?;
+
+        let writer = self.delegate.take().expect("Writer must be present");
+
+        Ok(writer)
+    }
+
+    /// Write any remaining buffered data to the delegate writer.
+    fn write_final_leftovers(&mut self) -> Result<()> {
+        if self.delegate.is_none() {
+            // finish() has already successfully called this, and we are now in drop() with a None
+            // writer, so just no-op
+            return Ok(());
+        }
+
+        self.write_all_encoded_output()?;
+
+        if self.extra_input_occupied_len > 0 {
+            let encoded_len = encode_config_slice(
+                &self.extra_input[..self.extra_input_occupied_len],
+                self.config,
+                &mut self.output[..],
+            );
+
+            self.output_occupied_len = encoded_len;
+
+            self.write_all_encoded_output()?;
+
+            // write succeeded, do not write the encoding of extra again if finish() is retried
+            self.extra_input_occupied_len = 0;
+        }
+
+        Ok(())
+    }
+
+    /// Write as much of the encoded output to the delegate writer as it will accept, and store the
+    /// leftovers to be attempted at the next write() call. Updates `self.output_occupied_len`.
+    ///
+    /// # Errors
+    ///
+    /// Errors from the delegate writer are returned. In the case of an error,
+    /// `self.output_occupied_len` will not be updated, as errors from `write` are specified to mean
+    /// that no write took place.
+    fn write_to_delegate(&mut self, current_output_len: usize) -> Result<()> {
+        self.panicked = true;
+        let res = self
+            .delegate
+            .as_mut()
+            .expect("Writer must be present")
+            .write(&self.output[..current_output_len]);
+        self.panicked = false;
+
+        res.map(|consumed| {
+            debug_assert!(consumed <= current_output_len);
+
+            if consumed < current_output_len {
+                self.output_occupied_len = current_output_len.checked_sub(consumed).unwrap();
+                // If we're blocking on I/O, the minor inefficiency of copying bytes to the
+                // start of the buffer is the least of our concerns...
+                // Rotate moves more than we need to, but copy_within isn't stabilized yet.
+                self.output.rotate_left(consumed);
+            } else {
+                self.output_occupied_len = 0;
+            }
+        })
+    }
+
+    /// Write all buffered encoded output. If this returns `Ok`, `self.output_occupied_len` is `0`.
+    ///
+    /// This is basically write_all for the remaining buffered data but without the undesirable
+    /// abort-on-`Ok(0)` behavior.
+    ///
+    /// # Errors
+    ///
+    /// Any error emitted by the delegate writer abort the write loop and is returned, unless it's
+    /// `Interrupted`, in which case the error is ignored and writes will continue.
+    fn write_all_encoded_output(&mut self) -> Result<()> {
+        while self.output_occupied_len > 0 {
+            let remaining_len = self.output_occupied_len;
+            match self.write_to_delegate(remaining_len) {
+                // try again on interrupts ala write_all
+                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+                // other errors return
+                Err(e) => return Err(e),
+                // success no-ops because remaining length is already updated
+                Ok(_) => {}
+            };
+        }
+
+        debug_assert_eq!(0, self.output_occupied_len);
+        Ok(())
+    }
+}
+
+impl<W: Write> Write for EncoderWriter<W> {
+    /// Encode input and then write to the delegate writer.
+    ///
+    /// Under non-error circumstances, this returns `Ok` with the value being the number of bytes
+    /// of `input` consumed. The value may be `0`, which interacts poorly with `write_all`, which
+    /// interprets `Ok(0)` as an error, despite it being allowed by the contract of `write`. See
+    /// <https://github.com/rust-lang/rust/issues/56889> for more on that.
+    ///
+    /// If the previous call to `write` provided more (encoded) data than the delegate writer could
+    /// accept in a single call to its `write`, the remaining data is buffered. As long as buffered
+    /// data is present, subsequent calls to `write` will try to write the remaining buffered data
+    /// to the delegate and return either `Ok(0)` -- and therefore not consume any of `input` -- or
+    /// an error.
+    ///
+    /// # Errors
+    ///
+    /// Any errors emitted by the delegate writer are returned.
+    fn write(&mut self, input: &[u8]) -> Result<usize> {
+        if self.delegate.is_none() {
+            panic!("Cannot write more after calling finish()");
+        }
+
+        if input.is_empty() {
+            return Ok(0);
+        }
+
+        // The contract of `Write::write` places some constraints on this implementation:
+        // - a call to `write()` represents at most one call to a wrapped `Write`, so we can't
+        // iterate over the input and encode multiple chunks.
+        // - Errors mean that "no bytes were written to this writer", so we need to reset the
+        // internal state to what it was before the error occurred
+
+        // before reading any input, write any leftover encoded output from last time
+        if self.output_occupied_len > 0 {
+            let current_len = self.output_occupied_len;
+            return self
+                .write_to_delegate(current_len)
+                // did not read any input
+                .map(|_| 0);
+        }
+
+        debug_assert_eq!(0, self.output_occupied_len);
+
+        // how many bytes, if any, were read into `extra` to create a triple to encode
+        let mut extra_input_read_len = 0;
+        let mut input = input;
+
+        let orig_extra_len = self.extra_input_occupied_len;
+
+        let mut encoded_size = 0;
+        // always a multiple of MIN_ENCODE_CHUNK_SIZE
+        let mut max_input_len = MAX_INPUT_LEN;
+
+        // process leftover un-encoded input from last write
+        if self.extra_input_occupied_len > 0 {
+            debug_assert!(self.extra_input_occupied_len < 3);
+            if input.len() + self.extra_input_occupied_len >= MIN_ENCODE_CHUNK_SIZE {
+                // Fill up `extra`, encode that into `output`, and consume as much of the rest of
+                // `input` as possible.
+                // We could write just the encoding of `extra` by itself but then we'd have to
+                // return after writing only 4 bytes, which is inefficient if the underlying writer
+                // would make a syscall.
+                extra_input_read_len = MIN_ENCODE_CHUNK_SIZE - self.extra_input_occupied_len;
+                debug_assert!(extra_input_read_len > 0);
+                // overwrite only bytes that weren't already used. If we need to rollback extra_len
+                // (when the subsequent write errors), the old leading bytes will still be there.
+                self.extra_input[self.extra_input_occupied_len..MIN_ENCODE_CHUNK_SIZE]
+                    .copy_from_slice(&input[0..extra_input_read_len]);
+
+                let len = encode_to_slice(
+                    &self.extra_input[0..MIN_ENCODE_CHUNK_SIZE],
+                    &mut self.output[..],
+                    self.config.char_set.encode_table(),
+                );
+                debug_assert_eq!(4, len);
+
+                input = &input[extra_input_read_len..];
+
+                // consider extra to be used up, since we encoded it
+                self.extra_input_occupied_len = 0;
+                // don't clobber where we just encoded to
+                encoded_size = 4;
+                // and don't read more than can be encoded
+                max_input_len = MAX_INPUT_LEN - MIN_ENCODE_CHUNK_SIZE;
+
+            // fall through to normal encoding
+            } else {
+                // `extra` and `input` are non empty, but `|extra| + |input| < 3`, so there must be
+                // 1 byte in each.
+                debug_assert_eq!(1, input.len());
+                debug_assert_eq!(1, self.extra_input_occupied_len);
+
+                self.extra_input[self.extra_input_occupied_len] = input[0];
+                self.extra_input_occupied_len += 1;
+                return Ok(1);
+            };
+        } else if input.len() < MIN_ENCODE_CHUNK_SIZE {
+            // `extra` is empty, and `input` fits inside it
+            self.extra_input[0..input.len()].copy_from_slice(input);
+            self.extra_input_occupied_len = input.len();
+            return Ok(input.len());
+        };
+
+        // either 0 or 1 complete chunks encoded from extra
+        debug_assert!(encoded_size == 0 || encoded_size == 4);
+        debug_assert!(
+            // didn't encode extra input
+            MAX_INPUT_LEN == max_input_len
+                // encoded one triple
+                || MAX_INPUT_LEN == max_input_len + MIN_ENCODE_CHUNK_SIZE
+        );
+
+        // encode complete triples only
+        let input_complete_chunks_len = input.len() - (input.len() % MIN_ENCODE_CHUNK_SIZE);
+        let input_chunks_to_encode_len = cmp::min(input_complete_chunks_len, max_input_len);
+        debug_assert_eq!(0, max_input_len % MIN_ENCODE_CHUNK_SIZE);
+        debug_assert_eq!(0, input_chunks_to_encode_len % MIN_ENCODE_CHUNK_SIZE);
+
+        encoded_size += encode_to_slice(
+            &input[..(input_chunks_to_encode_len)],
+            &mut self.output[encoded_size..],
+            self.config.char_set.encode_table(),
+        );
+
+        // not updating `self.output_occupied_len` here because if the below write fails, it should
+        // "never take place" -- the buffer contents we encoded are ignored and perhaps retried
+        // later, if the consumer chooses.
+
+        self.write_to_delegate(encoded_size)
+            // no matter whether we wrote the full encoded buffer or not, we consumed the same
+            // input
+            .map(|_| extra_input_read_len + input_chunks_to_encode_len)
+            .map_err(|e| {
+                // in case we filled and encoded `extra`, reset extra_len
+                self.extra_input_occupied_len = orig_extra_len;
+
+                e
+            })
+    }
+
+    /// Because this is usually treated as OK to call multiple times, it will *not* flush any
+    /// incomplete chunks of input or write padding.
+    /// # Errors
+    ///
+    /// The first error that is not of [`ErrorKind::Interrupted`] will be returned.
+    fn flush(&mut self) -> Result<()> {
+        self.write_all_encoded_output()?;
+        self.delegate
+            .as_mut()
+            .expect("Writer must be present")
+            .flush()
+    }
+}
+
+impl<W: Write> Drop for EncoderWriter<W> {
+    fn drop(&mut self) {
+        if !self.panicked {
+            // like `BufWriter`, ignore errors during drop
+            let _ = self.write_final_leftovers();
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/write/encoder_string_writer.rs cargo-0.66.0+ds1/vendor/base64/src/write/encoder_string_writer.rs
--- cargo-0.66.0/vendor/base64/src/write/encoder_string_writer.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/write/encoder_string_writer.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,176 @@
+use super::encoder::EncoderWriter;
+use crate::Config;
+use std::io;
+use std::io::Write;
+
+/// A `Write` implementation that base64-encodes data using the provided config and accumulates the
+/// resulting base64 in memory, which is then exposed as a String via `into_inner()`.
+///
+/// # Examples
+///
+/// Buffer base64 in a new String:
+///
+/// ```
+/// use std::io::Write;
+///
+/// let mut enc = base64::write::EncoderStringWriter::new(base64::STANDARD);
+///
+/// enc.write_all(b"asdf").unwrap();
+///
+/// // get the resulting String
+/// let b64_string = enc.into_inner();
+///
+/// assert_eq!("YXNkZg==", &b64_string);
+/// ```
+///
+/// Or, append to an existing String:
+///
+/// ```
+/// use std::io::Write;
+///
+/// let mut buf = String::from("base64: ");
+///
+/// let mut enc = base64::write::EncoderStringWriter::from(&mut buf, base64::STANDARD);
+///
+/// enc.write_all(b"asdf").unwrap();
+///
+/// // release the &mut reference on buf
+/// let _ = enc.into_inner();
+///
+/// assert_eq!("base64: YXNkZg==", &buf);
+/// ```
+///
+/// # Panics
+///
+/// Calling `write()` (or related methods) or `finish()` after `finish()` has completed without
+/// error is invalid and will panic.
+///
+/// # Performance
+///
+/// Because it has to validate that the base64 is UTF-8, it is about 80% as fast as writing plain
+/// bytes to a `io::Write`.
+pub struct EncoderStringWriter<S: StrConsumer> {
+    encoder: EncoderWriter<Utf8SingleCodeUnitWriter<S>>,
+}
+
+impl<S: StrConsumer> EncoderStringWriter<S> {
+    /// Create a EncoderStringWriter that will append to the provided `StrConsumer`.
+    pub fn from(str_consumer: S, config: Config) -> Self {
+        EncoderStringWriter {
+            encoder: EncoderWriter::new(Utf8SingleCodeUnitWriter { str_consumer }, config),
+        }
+    }
+
+    /// Encode all remaining buffered data, including any trailing incomplete input triples and
+    /// associated padding.
+    ///
+    /// Once this succeeds, no further writes or calls to this method are allowed.
+    ///
+    /// Returns the base64-encoded form of the accumulated written data.
+    pub fn into_inner(mut self) -> S {
+        self.encoder
+            .finish()
+            .expect("Writing to a Vec<u8> should never fail")
+            .str_consumer
+    }
+}
+
+impl EncoderStringWriter<String> {
+    /// Create a EncoderStringWriter that will encode into a new String with the provided config.
+    pub fn new(config: Config) -> Self {
+        EncoderStringWriter::from(String::new(), config)
+    }
+}
+
+impl<S: StrConsumer> Write for EncoderStringWriter<S> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.encoder.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.encoder.flush()
+    }
+}
+
+/// An abstraction around consuming `str`s produced by base64 encoding.
+pub trait StrConsumer {
+    /// Consume the base64 encoded data in `buf`
+    fn consume(&mut self, buf: &str);
+}
+
+/// As for io::Write, `StrConsumer` is implemented automatically for `&mut S`.
+impl<S: StrConsumer + ?Sized> StrConsumer for &mut S {
+    fn consume(&mut self, buf: &str) {
+        (**self).consume(buf)
+    }
+}
+
+/// Pushes the str onto the end of the String
+impl StrConsumer for String {
+    fn consume(&mut self, buf: &str) {
+        self.push_str(buf)
+    }
+}
+
+/// A `Write` that only can handle bytes that are valid single-byte UTF-8 code units.
+///
+/// This is safe because we only use it when writing base64, which is always valid UTF-8.
+struct Utf8SingleCodeUnitWriter<S: StrConsumer> {
+    str_consumer: S,
+}
+
+impl<S: StrConsumer> io::Write for Utf8SingleCodeUnitWriter<S> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        // Because we expect all input to be valid utf-8 individual bytes, we can encode any buffer
+        // length
+        let s = std::str::from_utf8(buf).expect("Input must be valid UTF-8");
+
+        self.str_consumer.consume(s);
+
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        // no op
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::encode_config_buf;
+    use crate::tests::random_config;
+    use crate::write::encoder_string_writer::EncoderStringWriter;
+    use rand::Rng;
+    use std::io::Write;
+
+    #[test]
+    fn every_possible_split_of_input() {
+        let mut rng = rand::thread_rng();
+        let mut orig_data = Vec::<u8>::new();
+        let mut normal_encoded = String::new();
+
+        let size = 5_000;
+
+        for i in 0..size {
+            orig_data.clear();
+            normal_encoded.clear();
+
+            for _ in 0..size {
+                orig_data.push(rng.gen());
+            }
+
+            let config = random_config(&mut rng);
+            encode_config_buf(&orig_data, config, &mut normal_encoded);
+
+            let mut stream_encoder = EncoderStringWriter::new(config);
+            // Write the first i bytes, then the rest
+            stream_encoder.write_all(&orig_data[0..i]).unwrap();
+            stream_encoder.write_all(&orig_data[i..]).unwrap();
+
+            let stream_encoded = stream_encoder.into_inner();
+
+            assert_eq!(normal_encoded, stream_encoded);
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/write/encoder_tests.rs cargo-0.66.0+ds1/vendor/base64/src/write/encoder_tests.rs
--- cargo-0.66.0/vendor/base64/src/write/encoder_tests.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/write/encoder_tests.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,568 @@
+use super::EncoderWriter;
+use crate::tests::random_config;
+use crate::{encode_config, encode_config_buf, STANDARD_NO_PAD, URL_SAFE};
+
+use std::io::{Cursor, Write};
+use std::{cmp, io, str};
+
+use rand::Rng;
+
+#[test]
+fn encode_three_bytes() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        let sz = enc.write(b"abc").unwrap();
+        assert_eq!(sz, 3);
+    }
+    assert_eq!(&c.get_ref()[..], encode_config("abc", URL_SAFE).as_bytes());
+}
+
+#[test]
+fn encode_nine_bytes_two_writes() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        let sz = enc.write(b"abcdef").unwrap();
+        assert_eq!(sz, 6);
+        let sz = enc.write(b"ghi").unwrap();
+        assert_eq!(sz, 3);
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdefghi", URL_SAFE).as_bytes()
+    );
+}
+
+#[test]
+fn encode_one_then_two_bytes() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        let sz = enc.write(b"a").unwrap();
+        assert_eq!(sz, 1);
+        let sz = enc.write(b"bc").unwrap();
+        assert_eq!(sz, 2);
+    }
+    assert_eq!(&c.get_ref()[..], encode_config("abc", URL_SAFE).as_bytes());
+}
+
+#[test]
+fn encode_one_then_five_bytes() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        let sz = enc.write(b"a").unwrap();
+        assert_eq!(sz, 1);
+        let sz = enc.write(b"bcdef").unwrap();
+        assert_eq!(sz, 5);
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdef", URL_SAFE).as_bytes()
+    );
+}
+
+#[test]
+fn encode_1_2_3_bytes() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        let sz = enc.write(b"a").unwrap();
+        assert_eq!(sz, 1);
+        let sz = enc.write(b"bc").unwrap();
+        assert_eq!(sz, 2);
+        let sz = enc.write(b"def").unwrap();
+        assert_eq!(sz, 3);
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdef", URL_SAFE).as_bytes()
+    );
+}
+
+#[test]
+fn encode_with_padding() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        enc.write_all(b"abcd").unwrap();
+
+        enc.flush().unwrap();
+    }
+    assert_eq!(&c.get_ref()[..], encode_config("abcd", URL_SAFE).as_bytes());
+}
+
+#[test]
+fn encode_with_padding_multiple_writes() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        assert_eq!(1, enc.write(b"a").unwrap());
+        assert_eq!(2, enc.write(b"bc").unwrap());
+        assert_eq!(3, enc.write(b"def").unwrap());
+        assert_eq!(1, enc.write(b"g").unwrap());
+
+        enc.flush().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdefg", URL_SAFE).as_bytes()
+    );
+}
+
+#[test]
+fn finish_writes_extra_byte() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, URL_SAFE);
+
+        assert_eq!(6, enc.write(b"abcdef").unwrap());
+
+        // will be in extra
+        assert_eq!(1, enc.write(b"g").unwrap());
+
+        // 1 trailing byte = 2 encoded chars
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdefg", URL_SAFE).as_bytes()
+    );
+}
+
+#[test]
+fn write_partial_chunk_encodes_partial_chunk() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        // nothing encoded yet
+        assert_eq!(2, enc.write(b"ab").unwrap());
+        // encoded here
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("ab", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(3, c.get_ref().len());
+}
+
+#[test]
+fn write_1_chunk_encodes_complete_chunk() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        assert_eq!(3, enc.write(b"abc").unwrap());
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abc", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(4, c.get_ref().len());
+}
+
+#[test]
+fn write_1_chunk_and_partial_encodes_only_complete_chunk() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        // "d" not written
+        assert_eq!(3, enc.write(b"abcd").unwrap());
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abc", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(4, c.get_ref().len());
+}
+
+#[test]
+fn write_2_partials_to_exactly_complete_chunk_encodes_complete_chunk() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        assert_eq!(1, enc.write(b"a").unwrap());
+        assert_eq!(2, enc.write(b"bc").unwrap());
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abc", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(4, c.get_ref().len());
+}
+
+#[test]
+fn write_partial_then_enough_to_complete_chunk_but_not_complete_another_chunk_encodes_complete_chunk_without_consuming_remaining(
+) {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        assert_eq!(1, enc.write(b"a").unwrap());
+        // doesn't consume "d"
+        assert_eq!(2, enc.write(b"bcd").unwrap());
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abc", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(4, c.get_ref().len());
+}
+
+#[test]
+fn write_partial_then_enough_to_complete_chunk_and_another_chunk_encodes_complete_chunks() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        assert_eq!(1, enc.write(b"a").unwrap());
+        // completes partial chunk, and another chunk
+        assert_eq!(5, enc.write(b"bcdef").unwrap());
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdef", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(8, c.get_ref().len());
+}
+
+#[test]
+fn write_partial_then_enough_to_complete_chunk_and_another_chunk_and_another_partial_chunk_encodes_only_complete_chunks(
+) {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+
+        assert_eq!(1, enc.write(b"a").unwrap());
+        // completes partial chunk, and another chunk, with one more partial chunk that's not
+        // consumed
+        assert_eq!(5, enc.write(b"bcdefe").unwrap());
+        let _ = enc.finish().unwrap();
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("abcdef", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(8, c.get_ref().len());
+}
+
+#[test]
+fn drop_calls_finish_for_you() {
+    let mut c = Cursor::new(Vec::new());
+    {
+        let mut enc = EncoderWriter::new(&mut c, STANDARD_NO_PAD);
+        assert_eq!(1, enc.write(b"a").unwrap());
+    }
+    assert_eq!(
+        &c.get_ref()[..],
+        encode_config("a", STANDARD_NO_PAD).as_bytes()
+    );
+    assert_eq!(2, c.get_ref().len());
+}
+
+#[test]
+fn every_possible_split_of_input() {
+    let mut rng = rand::thread_rng();
+    let mut orig_data = Vec::<u8>::new();
+    let mut stream_encoded = Vec::<u8>::new();
+    let mut normal_encoded = String::new();
+
+    let size = 5_000;
+
+    for i in 0..size {
+        orig_data.clear();
+        stream_encoded.clear();
+        normal_encoded.clear();
+
+        for _ in 0..size {
+            orig_data.push(rng.gen());
+        }
+
+        let config = random_config(&mut rng);
+        encode_config_buf(&orig_data, config, &mut normal_encoded);
+
+        {
+            let mut stream_encoder = EncoderWriter::new(&mut stream_encoded, config);
+            // Write the first i bytes, then the rest
+            stream_encoder.write_all(&orig_data[0..i]).unwrap();
+            stream_encoder.write_all(&orig_data[i..]).unwrap();
+        }
+
+        assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap());
+    }
+}
+
+#[test]
+fn encode_random_config_matches_normal_encode_reasonable_input_len() {
+    // choose up to 2 * buf size, so ~half the time it'll use a full buffer
+    do_encode_random_config_matches_normal_encode(super::encoder::BUF_SIZE * 2)
+}
+
+#[test]
+fn encode_random_config_matches_normal_encode_tiny_input_len() {
+    do_encode_random_config_matches_normal_encode(10)
+}
+
+#[test]
+fn retrying_writes_that_error_with_interrupted_works() {
+    let mut rng = rand::thread_rng();
+    let mut orig_data = Vec::<u8>::new();
+    let mut stream_encoded = Vec::<u8>::new();
+    let mut normal_encoded = String::new();
+
+    for _ in 0..1_000 {
+        orig_data.clear();
+        stream_encoded.clear();
+        normal_encoded.clear();
+
+        let orig_len: usize = rng.gen_range(100, 20_000);
+        for _ in 0..orig_len {
+            orig_data.push(rng.gen());
+        }
+
+        // encode the normal way
+        let config = random_config(&mut rng);
+        encode_config_buf(&orig_data, config, &mut normal_encoded);
+
+        // encode via the stream encoder
+        {
+            let mut interrupt_rng = rand::thread_rng();
+            let mut interrupting_writer = InterruptingWriter {
+                w: &mut stream_encoded,
+                rng: &mut interrupt_rng,
+                fraction: 0.8,
+            };
+
+            let mut stream_encoder = EncoderWriter::new(&mut interrupting_writer, config);
+            let mut bytes_consumed = 0;
+            while bytes_consumed < orig_len {
+                // use short inputs since we want to use `extra` a lot as that's what needs rollback
+                // when errors occur
+                let input_len: usize = cmp::min(rng.gen_range(0, 10), orig_len - bytes_consumed);
+
+                retry_interrupted_write_all(
+                    &mut stream_encoder,
+                    &orig_data[bytes_consumed..bytes_consumed + input_len],
+                )
+                .unwrap();
+
+                bytes_consumed += input_len;
+            }
+
+            loop {
+                let res = stream_encoder.finish();
+                match res {
+                    Ok(_) => break,
+                    Err(e) => match e.kind() {
+                        io::ErrorKind::Interrupted => continue,
+                        _ => Err(e).unwrap(), // bail
+                    },
+                }
+            }
+
+            assert_eq!(orig_len, bytes_consumed);
+        }
+
+        assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap());
+    }
+}
+
+#[test]
+fn writes_that_only_write_part_of_input_and_sometimes_interrupt_produce_correct_encoded_data() {
+    let mut rng = rand::thread_rng();
+    let mut orig_data = Vec::<u8>::new();
+    let mut stream_encoded = Vec::<u8>::new();
+    let mut normal_encoded = String::new();
+
+    for _ in 0..1_000 {
+        orig_data.clear();
+        stream_encoded.clear();
+        normal_encoded.clear();
+
+        let orig_len: usize = rng.gen_range(100, 20_000);
+        for _ in 0..orig_len {
+            orig_data.push(rng.gen());
+        }
+
+        // encode the normal way
+        let config = random_config(&mut rng);
+        encode_config_buf(&orig_data, config, &mut normal_encoded);
+
+        // encode via the stream encoder
+        {
+            let mut partial_rng = rand::thread_rng();
+            let mut partial_writer = PartialInterruptingWriter {
+                w: &mut stream_encoded,
+                rng: &mut partial_rng,
+                full_input_fraction: 0.1,
+                no_interrupt_fraction: 0.1,
+            };
+
+            let mut stream_encoder = EncoderWriter::new(&mut partial_writer, config);
+            let mut bytes_consumed = 0;
+            while bytes_consumed < orig_len {
+                // use at most medium-length inputs to exercise retry logic more aggressively
+                let input_len: usize = cmp::min(rng.gen_range(0, 100), orig_len - bytes_consumed);
+
+                let res =
+                    stream_encoder.write(&orig_data[bytes_consumed..bytes_consumed + input_len]);
+
+                // retry on interrupt
+                match res {
+                    Ok(len) => bytes_consumed += len,
+                    Err(e) => match e.kind() {
+                        io::ErrorKind::Interrupted => continue,
+                        _ => {
+                            panic!("should not see other errors");
+                        }
+                    },
+                }
+            }
+
+            let _ = stream_encoder.finish().unwrap();
+
+            assert_eq!(orig_len, bytes_consumed);
+        }
+
+        assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap());
+    }
+}
+
+/// Retry writes until all the data is written or an error that isn't Interrupted is returned.
+fn retry_interrupted_write_all<W: Write>(w: &mut W, buf: &[u8]) -> io::Result<()> {
+    let mut bytes_consumed = 0;
+
+    while bytes_consumed < buf.len() {
+        let res = w.write(&buf[bytes_consumed..]);
+
+        match res {
+            Ok(len) => bytes_consumed += len,
+            Err(e) => match e.kind() {
+                io::ErrorKind::Interrupted => continue,
+                _ => return Err(e),
+            },
+        }
+    }
+
+    Ok(())
+}
+
+fn do_encode_random_config_matches_normal_encode(max_input_len: usize) {
+    let mut rng = rand::thread_rng();
+    let mut orig_data = Vec::<u8>::new();
+    let mut stream_encoded = Vec::<u8>::new();
+    let mut normal_encoded = String::new();
+
+    for _ in 0..1_000 {
+        orig_data.clear();
+        stream_encoded.clear();
+        normal_encoded.clear();
+
+        let orig_len: usize = rng.gen_range(100, 20_000);
+        for _ in 0..orig_len {
+            orig_data.push(rng.gen());
+        }
+
+        // encode the normal way
+        let config = random_config(&mut rng);
+        encode_config_buf(&orig_data, config, &mut normal_encoded);
+
+        // encode via the stream encoder
+        {
+            let mut stream_encoder = EncoderWriter::new(&mut stream_encoded, config);
+            let mut bytes_consumed = 0;
+            while bytes_consumed < orig_len {
+                let input_len: usize =
+                    cmp::min(rng.gen_range(0, max_input_len), orig_len - bytes_consumed);
+
+                // write a little bit of the data
+                stream_encoder
+                    .write_all(&orig_data[bytes_consumed..bytes_consumed + input_len])
+                    .unwrap();
+
+                bytes_consumed += input_len;
+            }
+
+            let _ = stream_encoder.finish().unwrap();
+
+            assert_eq!(orig_len, bytes_consumed);
+        }
+
+        assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap());
+    }
+}
+
+/// A `Write` implementation that returns Interrupted some fraction of the time, randomly.
+struct InterruptingWriter<'a, W: 'a + Write, R: 'a + Rng> {
+    w: &'a mut W,
+    rng: &'a mut R,
+    /// In [0, 1]. If a random number in [0, 1] is  `<= threshold`, `Write` methods will return
+    /// an `Interrupted` error
+    fraction: f64,
+}
+
+impl<'a, W: Write, R: Rng> Write for InterruptingWriter<'a, W, R> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        if self.rng.gen_range(0.0, 1.0) <= self.fraction {
+            return Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted"));
+        }
+
+        self.w.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        if self.rng.gen_range(0.0, 1.0) <= self.fraction {
+            return Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted"));
+        }
+
+        self.w.flush()
+    }
+}
+
+/// A `Write` implementation that sometimes will only write part of its input.
+struct PartialInterruptingWriter<'a, W: 'a + Write, R: 'a + Rng> {
+    w: &'a mut W,
+    rng: &'a mut R,
+    /// In [0, 1]. If a random number in [0, 1] is  `<= threshold`, `write()` will write all its
+    /// input. Otherwise, it will write a random substring
+    full_input_fraction: f64,
+    no_interrupt_fraction: f64,
+}
+
+impl<'a, W: Write, R: Rng> Write for PartialInterruptingWriter<'a, W, R> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        if self.rng.gen_range(0.0, 1.0) > self.no_interrupt_fraction {
+            return Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted"));
+        }
+
+        if self.rng.gen_range(0.0, 1.0) <= self.full_input_fraction || buf.len() == 0 {
+            // pass through the buf untouched
+            self.w.write(buf)
+        } else {
+            // only use a prefix of it
+            self.w
+                .write(&buf[0..(self.rng.gen_range(0, buf.len() - 1))])
+        }
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.w.flush()
+    }
+}
diff -Nru cargo-0.66.0/vendor/base64/src/write/mod.rs cargo-0.66.0+ds1/vendor/base64/src/write/mod.rs
--- cargo-0.66.0/vendor/base64/src/write/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/src/write/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,8 @@
+//! Implementations of `io::Write` to transparently handle base64.
+mod encoder;
+mod encoder_string_writer;
+pub use self::encoder::EncoderWriter;
+pub use self::encoder_string_writer::EncoderStringWriter;
+
+#[cfg(test)]
+mod encoder_tests;
diff -Nru cargo-0.66.0/vendor/base64/tests/decode.rs cargo-0.66.0+ds1/vendor/base64/tests/decode.rs
--- cargo-0.66.0/vendor/base64/tests/decode.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/tests/decode.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,330 @@
+extern crate base64;
+
+use base64::*;
+
+mod helpers;
+
+use self::helpers::*;
+
+#[test]
+fn decode_rfc4648_0() {
+    compare_decode("", "");
+}
+
+#[test]
+fn decode_rfc4648_1() {
+    compare_decode("f", "Zg==");
+}
+
+#[test]
+fn decode_rfc4648_1_just_a_bit_of_padding() {
+    // allows less padding than required
+    compare_decode("f", "Zg=");
+}
+
+#[test]
+fn decode_rfc4648_1_no_padding() {
+    compare_decode("f", "Zg");
+}
+
+#[test]
+fn decode_rfc4648_2() {
+    compare_decode("fo", "Zm8=");
+}
+
+#[test]
+fn decode_rfc4648_2_no_padding() {
+    compare_decode("fo", "Zm8");
+}
+
+#[test]
+fn decode_rfc4648_3() {
+    compare_decode("foo", "Zm9v");
+}
+
+#[test]
+fn decode_rfc4648_4() {
+    compare_decode("foob", "Zm9vYg==");
+}
+
+#[test]
+fn decode_rfc4648_4_no_padding() {
+    compare_decode("foob", "Zm9vYg");
+}
+
+#[test]
+fn decode_rfc4648_5() {
+    compare_decode("fooba", "Zm9vYmE=");
+}
+
+#[test]
+fn decode_rfc4648_5_no_padding() {
+    compare_decode("fooba", "Zm9vYmE");
+}
+
+#[test]
+fn decode_rfc4648_6() {
+    compare_decode("foobar", "Zm9vYmFy");
+}
+
+#[test]
+fn decode_reject_null() {
+    assert_eq!(
+        DecodeError::InvalidByte(3, 0x0),
+        decode_config("YWx\0pY2U==", config_std_pad()).unwrap_err()
+    );
+}
+
+#[test]
+fn decode_single_pad_byte_after_2_chars_in_trailing_quad_ok() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("Zg=");
+
+        let input_len = num_quads * 3 + 1;
+
+        // Since there are 3 bytes in the trailing quad, want to be sure this allows for the fact
+        // that it could be bad padding rather than assuming that it will decode to 2 bytes and
+        // therefore allow 1 extra round of fast decode logic (stage 1 / 2).
+
+        let mut decoded = Vec::new();
+        decoded.resize(input_len, 0);
+
+        assert_eq!(
+            input_len,
+            decode_config_slice(&s, STANDARD, &mut decoded).unwrap()
+        );
+    }
+}
+
+//this is a MAY in the rfc: https://tools.ietf.org/html/rfc4648#section-3.3
+#[test]
+fn decode_1_pad_byte_in_fast_loop_then_extra_padding_chunk_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("YWxpY2U=====");
+
+        // since the first 8 bytes are handled in stage 1 or 2, the padding is detected as a
+        // generic invalid byte, not specifcally a padding issue.
+        // Could argue that the *next* padding byte (in the next quad) is technically the first
+        // erroneous one, but reporting that accurately is more complex and probably nobody cares
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 7, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_2_pad_bytes_in_leftovers_then_extra_padding_chunk_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("YWxpY2UABB====");
+
+        // 6 bytes (4 padding) after last 8-byte chunk, so it's decoded by stage 4.
+        // First padding byte is invalid.
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 10, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_valid_bytes_after_padding_in_leftovers_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("YWxpY2UABB=B");
+
+        // 4 bytes after last 8-byte chunk, so it's decoded by stage 4.
+        // First (and only) padding byte is invalid.
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 10, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_absurd_pad_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("==Y=Wx===pY=2U=====");
+
+        // Plenty of remaining bytes, so handled by stage 1 or 2.
+        // first padding byte
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_extra_padding_after_1_pad_bytes_in_trailing_quad_returns_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("EEE===");
+
+        // handled by stage 1, 2, or 4 depending on length
+        // first padding byte -- which would be legal if it was the only padding
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 3, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_extra_padding_after_2_pad_bytes_in_trailing_quad_2_returns_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("EE====");
+
+        // handled by stage 1, 2, or 4 depending on length
+        // first padding byte -- which would be legal if it was by itself
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 2, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_start_quad_with_padding_returns_error() {
+    for num_quads in 0..25 {
+        // add enough padding to ensure that we'll hit all 4 stages at the different lengths
+        for pad_bytes in 1..32 {
+            let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+            let padding: String = std::iter::repeat("=").take(pad_bytes).collect();
+            s.push_str(&padding);
+
+            if pad_bytes % 4 == 1 {
+                // detected in early length check
+                assert_eq!(DecodeError::InvalidLength, decode(&s).unwrap_err());
+            } else {
+                // padding lengths 2 - 8 are handled by stage 4
+                // padding length >= 8 will hit at least one chunk at stages 1, 2, 3 at different
+                // prefix lengths
+                assert_eq!(
+                    DecodeError::InvalidByte(num_quads * 4, b'='),
+                    decode(&s).unwrap_err()
+                );
+            }
+        }
+    }
+}
+
+#[test]
+fn decode_padding_followed_by_non_padding_returns_error() {
+    for num_quads in 0..25 {
+        for pad_bytes in 0..31 {
+            let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+            let padding: String = std::iter::repeat("=").take(pad_bytes).collect();
+            s.push_str(&padding);
+            s.push_str("E");
+
+            if pad_bytes % 4 == 0 {
+                assert_eq!(DecodeError::InvalidLength, decode(&s).unwrap_err());
+            } else {
+                // pad len 1 - 8 will be handled by stage 4
+                // pad len 9 (suffix len 10) will have 8 bytes of padding handled by stage 3
+                // first padding byte
+                assert_eq!(
+                    DecodeError::InvalidByte(num_quads * 4, b'='),
+                    decode(&s).unwrap_err()
+                );
+            }
+        }
+    }
+}
+
+#[test]
+fn decode_one_char_in_quad_with_padding_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("E=");
+
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 1, b'='),
+            decode(&s).unwrap_err()
+        );
+
+        // more padding doesn't change the error
+        s.push_str("=");
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 1, b'='),
+            decode(&s).unwrap_err()
+        );
+
+        s.push_str("=");
+        assert_eq!(
+            DecodeError::InvalidByte(num_quads * 4 + 1, b'='),
+            decode(&s).unwrap_err()
+        );
+    }
+}
+
+#[test]
+fn decode_one_char_in_quad_without_padding_error() {
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push('E');
+
+        assert_eq!(DecodeError::InvalidLength, decode(&s).unwrap_err());
+    }
+}
+
+#[test]
+fn decode_reject_invalid_bytes_with_correct_error() {
+    for length in 1..100 {
+        for index in 0_usize..length {
+            for invalid_byte in " \t\n\r\x0C\x0B\x00%*.".bytes() {
+                let prefix: String = std::iter::repeat("A").take(index).collect();
+                let suffix: String = std::iter::repeat("B").take(length - index - 1).collect();
+
+                let input = prefix + &String::from_utf8(vec![invalid_byte]).unwrap() + &suffix;
+                assert_eq!(
+                    length,
+                    input.len(),
+                    "length {} error position {}",
+                    length,
+                    index
+                );
+
+                if length % 4 == 1 && !suffix.is_empty() {
+                    assert_eq!(DecodeError::InvalidLength, decode(&input).unwrap_err());
+                } else {
+                    assert_eq!(
+                        DecodeError::InvalidByte(index, invalid_byte),
+                        decode(&input).unwrap_err()
+                    );
+                }
+            }
+        }
+    }
+}
+
+#[test]
+fn decode_imap() {
+    assert_eq!(
+        decode_config(b"+,,+", crate::IMAP_MUTF7),
+        decode_config(b"+//+", crate::STANDARD_NO_PAD)
+    );
+}
+
+#[test]
+fn decode_invalid_trailing_bytes() {
+    // The case of trailing newlines is common enough to warrant a test for a good error
+    // message.
+    assert_eq!(
+        Err(DecodeError::InvalidByte(8, b'\n')),
+        decode(b"Zm9vCg==\n")
+    );
+    // extra padding, however, is still InvalidLength
+    assert_eq!(Err(DecodeError::InvalidLength), decode(b"Zm9vCg==="));
+}
+
+fn config_std_pad() -> Config {
+    Config::new(CharacterSet::Standard, true)
+}
diff -Nru cargo-0.66.0/vendor/base64/tests/encode.rs cargo-0.66.0+ds1/vendor/base64/tests/encode.rs
--- cargo-0.66.0/vendor/base64/tests/encode.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/tests/encode.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,105 @@
+extern crate base64;
+
+use base64::*;
+
+fn compare_encode(expected: &str, target: &[u8]) {
+    assert_eq!(expected, encode(target));
+}
+
+#[test]
+fn encode_rfc4648_0() {
+    compare_encode("", b"");
+}
+
+#[test]
+fn encode_rfc4648_1() {
+    compare_encode("Zg==", b"f");
+}
+
+#[test]
+fn encode_rfc4648_2() {
+    compare_encode("Zm8=", b"fo");
+}
+
+#[test]
+fn encode_rfc4648_3() {
+    compare_encode("Zm9v", b"foo");
+}
+
+#[test]
+fn encode_rfc4648_4() {
+    compare_encode("Zm9vYg==", b"foob");
+}
+
+#[test]
+fn encode_rfc4648_5() {
+    compare_encode("Zm9vYmE=", b"fooba");
+}
+
+#[test]
+fn encode_rfc4648_6() {
+    compare_encode("Zm9vYmFy", b"foobar");
+}
+
+#[test]
+fn encode_all_ascii() {
+    let mut ascii = Vec::<u8>::with_capacity(128);
+
+    for i in 0..128 {
+        ascii.push(i);
+    }
+
+    compare_encode(
+        "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7P\
+         D0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8\
+         =",
+        &ascii,
+    );
+}
+
+#[test]
+fn encode_all_bytes() {
+    let mut bytes = Vec::<u8>::with_capacity(256);
+
+    for i in 0..255 {
+        bytes.push(i);
+    }
+    bytes.push(255); //bug with "overflowing" ranges?
+
+    compare_encode(
+        "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7P\
+         D0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn\
+         +AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6\
+         /wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==",
+        &bytes,
+    );
+}
+
+#[test]
+fn encode_all_bytes_url() {
+    let mut bytes = Vec::<u8>::with_capacity(256);
+
+    for i in 0..255 {
+        bytes.push(i);
+    }
+    bytes.push(255); //bug with "overflowing" ranges?
+
+    assert_eq!(
+        "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0\
+         -P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn\
+         -AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq\
+         -wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy\
+         8_T19vf4-fr7_P3-_w==",
+        encode_config(&bytes, URL_SAFE)
+    );
+}
+
+#[test]
+fn encode_url_safe_without_padding() {
+    let encoded = encode_config(b"alice", URL_SAFE_NO_PAD);
+    assert_eq!(&encoded, "YWxpY2U");
+    assert_eq!(
+        String::from_utf8(decode(&encoded).unwrap()).unwrap(),
+        "alice"
+    );
+}
diff -Nru cargo-0.66.0/vendor/base64/tests/helpers.rs cargo-0.66.0+ds1/vendor/base64/tests/helpers.rs
--- cargo-0.66.0/vendor/base64/tests/helpers.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/tests/helpers.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,14 @@
+extern crate base64;
+
+use base64::*;
+
+pub fn compare_decode(expected: &str, target: &str) {
+    assert_eq!(
+        expected,
+        String::from_utf8(decode(target).unwrap()).unwrap()
+    );
+    assert_eq!(
+        expected,
+        String::from_utf8(decode(target.as_bytes()).unwrap()).unwrap()
+    );
+}
diff -Nru cargo-0.66.0/vendor/base64/tests/tests.rs cargo-0.66.0+ds1/vendor/base64/tests/tests.rs
--- cargo-0.66.0/vendor/base64/tests/tests.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/base64/tests/tests.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,194 @@
+extern crate base64;
+extern crate rand;
+
+use rand::{FromEntropy, Rng};
+
+use base64::*;
+
+mod helpers;
+use self::helpers::*;
+
+// generate random contents of the specified length and test encode/decode roundtrip
+fn roundtrip_random(
+    byte_buf: &mut Vec<u8>,
+    str_buf: &mut String,
+    config: Config,
+    byte_len: usize,
+    approx_values_per_byte: u8,
+    max_rounds: u64,
+) {
+    // let the short ones be short but don't let it get too crazy large
+    let num_rounds = calculate_number_of_rounds(byte_len, approx_values_per_byte, max_rounds);
+    let mut r = rand::rngs::SmallRng::from_entropy();
+    let mut decode_buf = Vec::new();
+
+    for _ in 0..num_rounds {
+        byte_buf.clear();
+        str_buf.clear();
+        decode_buf.clear();
+        while byte_buf.len() < byte_len {
+            byte_buf.push(r.gen::<u8>());
+        }
+
+        encode_config_buf(&byte_buf, config, str_buf);
+        decode_config_buf(&str_buf, config, &mut decode_buf).unwrap();
+
+        assert_eq!(byte_buf, &decode_buf);
+    }
+}
+
+fn calculate_number_of_rounds(byte_len: usize, approx_values_per_byte: u8, max: u64) -> u64 {
+    // don't overflow
+    let mut prod = approx_values_per_byte as u64;
+
+    for _ in 0..byte_len {
+        if prod > max {
+            return max;
+        }
+
+        prod = prod.saturating_mul(prod);
+    }
+
+    prod
+}
+
+fn no_pad_config() -> Config {
+    Config::new(CharacterSet::Standard, false)
+}
+
+#[test]
+fn roundtrip_random_short_standard() {
+    let mut byte_buf: Vec<u8> = Vec::new();
+    let mut str_buf = String::new();
+
+    for input_len in 0..40 {
+        roundtrip_random(&mut byte_buf, &mut str_buf, STANDARD, input_len, 4, 10000);
+    }
+}
+
+#[test]
+fn roundtrip_random_with_fast_loop_standard() {
+    let mut byte_buf: Vec<u8> = Vec::new();
+    let mut str_buf = String::new();
+
+    for input_len in 40..100 {
+        roundtrip_random(&mut byte_buf, &mut str_buf, STANDARD, input_len, 4, 1000);
+    }
+}
+
+#[test]
+fn roundtrip_random_short_no_padding() {
+    let mut byte_buf: Vec<u8> = Vec::new();
+    let mut str_buf = String::new();
+
+    for input_len in 0..40 {
+        roundtrip_random(
+            &mut byte_buf,
+            &mut str_buf,
+            no_pad_config(),
+            input_len,
+            4,
+            10000,
+        );
+    }
+}
+
+#[test]
+fn roundtrip_random_no_padding() {
+    let mut byte_buf: Vec<u8> = Vec::new();
+    let mut str_buf = String::new();
+
+    for input_len in 40..100 {
+        roundtrip_random(
+            &mut byte_buf,
+            &mut str_buf,
+            no_pad_config(),
+            input_len,
+            4,
+            1000,
+        );
+    }
+}
+
+#[test]
+fn roundtrip_decode_trailing_10_bytes() {
+    // This is a special case because we decode 8 byte blocks of input at a time as much as we can,
+    // ideally unrolled to 32 bytes at a time, in stages 1 and 2. Since we also write a u64's worth
+    // of bytes (8) to the output, we always write 2 garbage bytes that then will be overwritten by
+    // the NEXT block. However, if the next block only contains 2 bytes, it will decode to 1 byte,
+    // and therefore be too short to cover up the trailing 2 garbage bytes. Thus, we have stage 3
+    // to handle that case.
+
+    for num_quads in 0..25 {
+        let mut s: String = std::iter::repeat("ABCD").take(num_quads).collect();
+        s.push_str("EFGHIJKLZg");
+
+        let decoded = decode(&s).unwrap();
+        assert_eq!(num_quads * 3 + 7, decoded.len());
+
+        assert_eq!(s, encode_config(&decoded, STANDARD_NO_PAD));
+    }
+}
+
+#[test]
+fn display_wrapper_matches_normal_encode() {
+    let mut bytes = Vec::<u8>::with_capacity(256);
+
+    for i in 0..255 {
+        bytes.push(i);
+    }
+    bytes.push(255);
+
+    assert_eq!(
+        encode(&bytes),
+        format!(
+            "{}",
+            base64::display::Base64Display::with_config(&bytes, STANDARD)
+        )
+    );
+}
+
+#[test]
+fn because_we_can() {
+    compare_decode("alice", "YWxpY2U=");
+    compare_decode("alice", &encode(b"alice"));
+    compare_decode("alice", &encode(&decode(&encode(b"alice")).unwrap()));
+}
+
+#[test]
+fn encode_config_slice_can_use_inline_buffer() {
+    let mut buf: [u8; 22] = [0; 22];
+    let mut larger_buf: [u8; 24] = [0; 24];
+    let mut input: [u8; 16] = [0; 16];
+
+    let mut rng = rand::rngs::SmallRng::from_entropy();
+    for elt in &mut input {
+        *elt = rng.gen();
+    }
+
+    assert_eq!(22, encode_config_slice(&input, STANDARD_NO_PAD, &mut buf));
+    let decoded = decode_config(&buf, STANDARD_NO_PAD).unwrap();
+
+    assert_eq!(decoded, input);
+
+    // let's try it again with padding
+
+    assert_eq!(24, encode_config_slice(&input, STANDARD, &mut larger_buf));
+    let decoded = decode_config(&buf, STANDARD).unwrap();
+
+    assert_eq!(decoded, input);
+}
+
+#[test]
+#[should_panic(expected = "index 24 out of range for slice of length 22")]
+fn encode_config_slice_panics_when_buffer_too_small() {
+    let mut buf: [u8; 22] = [0; 22];
+    let mut input: [u8; 16] = [0; 16];
+
+    let mut rng = rand::rngs::SmallRng::from_entropy();
+    for elt in &mut input {
+        *elt = rng.gen();
+    }
+
+    encode_config_slice(&input, STANDARD, &mut buf);
+}
diff -Nru cargo-0.66.0/vendor/block-buffer/.cargo-checksum.json cargo-0.66.0+ds1/vendor/block-buffer/.cargo-checksum.json
--- cargo-0.66.0/vendor/block-buffer/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/block-buffer/Cargo.toml cargo-0.66.0+ds1/vendor/block-buffer/Cargo.toml
--- cargo-0.66.0/vendor/block-buffer/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,32 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "block-buffer"
+version = "0.10.3"
+authors = ["RustCrypto Developers"]
+description = "Buffer type for block processing of data"
+documentation = "https://docs.rs/block-buffer"
+readme = "README.md"
+keywords = [
+    "block",
+    "buffer",
+]
+categories = [
+    "cryptography",
+    "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/RustCrypto/utils"
+
+[dependencies.generic-array]
+version = "0.14"
diff -Nru cargo-0.66.0/vendor/block-buffer/CHANGELOG.md cargo-0.66.0+ds1/vendor/block-buffer/CHANGELOG.md
--- cargo-0.66.0/vendor/block-buffer/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,47 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.10.3 (2022-09-04)
+### Added
+- `try_new` method ([#799])
+
+[#799]: https://github.com/RustCrypto/utils/pull/799
+
+## 0.10.2 (2021-02-08)
+### Fixed
+- Eliminate unreachable panic in `LazyBuffer::digest_blocks` ([#731])
+
+[#731]: https://github.com/RustCrypto/utils/pull/731
+
+## 0.10.1 (2021-02-05)
+### Fixed
+- Use `as_mut_ptr` to get a pointer for mutation in the `set_data` method ([#728])
+
+[#728]: https://github.com/RustCrypto/utils/pull/728
+
+## 0.10.0 (2020-12-07) [YANKED]
+### Changed
+- Significant reduction of number of unreachable panics. ([#671])
+- Added buffer kind type parameter to `BlockBuffer`, respective marker types, and type aliases. ([#671])
+- Various `BlockBuffer` method changes. ([#671])
+
+### Removed
+- `pad_with` method and dependency on `block-padding`. ([#671])
+
+[#671]: https://github.com/RustCrypto/utils/pull/671
+
+## 0.10.0 (2020-12-08)
+### Changed
+- Rename `input_block(s)` methods to `digest_block(s)`. ([#113])
+- Upgrade the `block-padding` dependency to v0.3. ([#113])
+
+### Added
+- `par_xor_data`, `xor_data`, and `set_data` methods. ([#113])
+
+### Removed
+- The `input_lazy` method. ([#113])
+
+[#113]: https://github.com/RustCrypto/utils/pull/113
diff -Nru cargo-0.66.0/vendor/block-buffer/LICENSE-APACHE cargo-0.66.0+ds1/vendor/block-buffer/LICENSE-APACHE
--- cargo-0.66.0/vendor/block-buffer/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/block-buffer/LICENSE-MIT cargo-0.66.0+ds1/vendor/block-buffer/LICENSE-MIT
--- cargo-0.66.0/vendor/block-buffer/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+Copyright (c) 2018-2019 The RustCrypto Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/block-buffer/README.md cargo-0.66.0+ds1/vendor/block-buffer/README.md
--- cargo-0.66.0/vendor/block-buffer/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,40 @@
+# [RustCrypto]: Block Buffer
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+[![Build Status][build-image]][build-link]
+
+Buffer type for block processing of data with minimized amount of unreachable panics.
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/block-buffer.svg
+[crate-link]: https://crates.io/crates/block-buffer
+[docs-image]: https://docs.rs/block-buffer/badge.svg
+[docs-link]: https://docs.rs/block-buffer/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils
+[build-image]: https://github.com/RustCrypto/utils/workflows/block-buffer/badge.svg?branch=master&event=push
+[build-link]: https://github.com/RustCrypto/utils/actions/workflows/block-buffer.yml
+
+[//]: # (general links)
+
+[RustCrypto]: https://github.com/rustcrypto
diff -Nru cargo-0.66.0/vendor/block-buffer/src/lib.rs cargo-0.66.0+ds1/vendor/block-buffer/src/lib.rs
--- cargo-0.66.0/vendor/block-buffer/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,344 @@
+//! Fixed size buffer for block processing of data.
+#![no_std]
+#![doc(
+    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+#![warn(missing_docs, rust_2018_idioms)]
+
+pub use generic_array;
+
+use core::{fmt, marker::PhantomData, slice};
+use generic_array::{
+    typenum::{IsLess, Le, NonZero, U256},
+    ArrayLength, GenericArray,
+};
+
+mod sealed;
+
+/// Block on which `BlockBuffer` operates.
+pub type Block<BlockSize> = GenericArray<u8, BlockSize>;
+
+/// Trait for buffer kinds.
+pub trait BufferKind: sealed::Sealed {}
+
+/// Eager block buffer kind, which guarantees that buffer position
+/// always lies in the range of `0..BlockSize`.
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Eager {}
+
+/// Lazy block buffer kind, which guarantees that buffer position
+/// always lies in the range of `0..=BlockSize`.
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Lazy {}
+
+impl BufferKind for Eager {}
+impl BufferKind for Lazy {}
+
+/// Eager block buffer.
+pub type EagerBuffer<B> = BlockBuffer<B, Eager>;
+/// Lazy block buffer.
+pub type LazyBuffer<B> = BlockBuffer<B, Lazy>;
+
+/// Block buffer error.
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub struct Error;
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        f.write_str("Block buffer error")
+    }
+}
+
+/// Buffer for block processing of data.
+#[derive(Debug)]
+pub struct BlockBuffer<BlockSize, Kind>
+where
+    BlockSize: ArrayLength<u8> + IsLess<U256>,
+    Le<BlockSize, U256>: NonZero,
+    Kind: BufferKind,
+{
+    buffer: Block<BlockSize>,
+    pos: u8,
+    _pd: PhantomData<Kind>,
+}
+
+impl<BlockSize, Kind> Default for BlockBuffer<BlockSize, Kind>
+where
+    BlockSize: ArrayLength<u8> + IsLess<U256>,
+    Le<BlockSize, U256>: NonZero,
+    Kind: BufferKind,
+{
+    fn default() -> Self {
+        Self {
+            buffer: Default::default(),
+            pos: 0,
+            _pd: PhantomData,
+        }
+    }
+}
+
+impl<BlockSize, Kind> Clone for BlockBuffer<BlockSize, Kind>
+where
+    BlockSize: ArrayLength<u8> + IsLess<U256>,
+    Le<BlockSize, U256>: NonZero,
+    Kind: BufferKind,
+{
+    fn clone(&self) -> Self {
+        Self {
+            buffer: self.buffer.clone(),
+            pos: self.pos,
+            _pd: PhantomData,
+        }
+    }
+}
+
+impl<BlockSize, Kind> BlockBuffer<BlockSize, Kind>
+where
+    BlockSize: ArrayLength<u8> + IsLess<U256>,
+    Le<BlockSize, U256>: NonZero,
+    Kind: BufferKind,
+{
+    /// Create new buffer from slice.
+    ///
+    /// # Panics
+    /// If slice length is not valid for used buffer kind.
+    #[inline(always)]
+    pub fn new(buf: &[u8]) -> Self {
+        Self::try_new(buf).unwrap()
+    }
+
+    /// Create new buffer from slice.
+    ///
+    /// Returns an error if slice length is not valid for used buffer kind.
+    #[inline(always)]
+    pub fn try_new(buf: &[u8]) -> Result<Self, Error> {
+        let pos = buf.len();
+        if !Kind::invariant(pos, BlockSize::USIZE) {
+            return Err(Error);
+        }
+        let mut buffer = Block::<BlockSize>::default();
+        buffer[..pos].copy_from_slice(buf);
+        Ok(Self {
+            buffer,
+            pos: pos as u8,
+            _pd: PhantomData,
+        })
+    }
+
+    /// Digest data in `input` in blocks of size `BlockSize` using
+    /// the `compress` function, which accepts slice of blocks.
+    #[inline]
+    pub fn digest_blocks(
+        &mut self,
+        mut input: &[u8],
+        mut compress: impl FnMut(&[Block<BlockSize>]),
+    ) {
+        let pos = self.get_pos();
+        // using `self.remaining()` for some reason
+        // prevents panic elimination
+        let rem = self.size() - pos;
+        let n = input.len();
+        // Note that checking condition `pos + n < BlockSize` is
+        // equivalent to checking `n < rem`, where `rem` is equal
+        // to `BlockSize - pos`. Using the latter allows us to work
+        // around compiler accounting for possible overflow of
+        // `pos + n` which results in it inserting unreachable
+        // panic branches. Using `unreachable_unchecked` in `get_pos`
+        // we convince compiler that `BlockSize - pos` never underflows.
+        if Kind::invariant(n, rem) {
+            // double slicing allows to remove panic branches
+            self.buffer[pos..][..n].copy_from_slice(input);
+            self.set_pos_unchecked(pos + n);
+            return;
+        }
+        if pos != 0 {
+            let (left, right) = input.split_at(rem);
+            input = right;
+            self.buffer[pos..].copy_from_slice(left);
+            compress(slice::from_ref(&self.buffer));
+        }
+
+        let (blocks, leftover) = Kind::split_blocks(input);
+        if !blocks.is_empty() {
+            compress(blocks);
+        }
+
+        let n = leftover.len();
+        self.buffer[..n].copy_from_slice(leftover);
+        self.set_pos_unchecked(n);
+    }
+
+    /// Reset buffer by setting cursor position to zero.
+    #[inline(always)]
+    pub fn reset(&mut self) {
+        self.set_pos_unchecked(0);
+    }
+
+    /// Pad remaining data with zeros and return resulting block.
+    #[inline(always)]
+    pub fn pad_with_zeros(&mut self) -> &mut Block<BlockSize> {
+        let pos = self.get_pos();
+        self.buffer[pos..].iter_mut().for_each(|b| *b = 0);
+        self.set_pos_unchecked(0);
+        &mut self.buffer
+    }
+
+    /// Return current cursor position.
+    #[inline(always)]
+    pub fn get_pos(&self) -> usize {
+        let pos = self.pos as usize;
+        if !Kind::invariant(pos, BlockSize::USIZE) {
+            debug_assert!(false);
+            // SAFETY: `pos` never breaks the invariant
+            unsafe {
+                core::hint::unreachable_unchecked();
+            }
+        }
+        pos
+    }
+
+    /// Return slice of data stored inside the buffer.
+    #[inline(always)]
+    pub fn get_data(&self) -> &[u8] {
+        &self.buffer[..self.get_pos()]
+    }
+
+    /// Set buffer content and cursor position.
+    ///
+    /// # Panics
+    /// If `pos` is bigger or equal to block size.
+    #[inline]
+    pub fn set(&mut self, buf: Block<BlockSize>, pos: usize) {
+        assert!(Kind::invariant(pos, BlockSize::USIZE));
+        self.buffer = buf;
+        self.set_pos_unchecked(pos);
+    }
+
+    /// Return size of the internall buffer in bytes.
+    #[inline(always)]
+    pub fn size(&self) -> usize {
+        BlockSize::USIZE
+    }
+
+    /// Return number of remaining bytes in the internall buffer.
+    #[inline(always)]
+    pub fn remaining(&self) -> usize {
+        self.size() - self.get_pos()
+    }
+
+    #[inline(always)]
+    fn set_pos_unchecked(&mut self, pos: usize) {
+        debug_assert!(Kind::invariant(pos, BlockSize::USIZE));
+        self.pos = pos as u8;
+    }
+}
+
+impl<BlockSize> BlockBuffer<BlockSize, Eager>
+where
+    BlockSize: ArrayLength<u8> + IsLess<U256>,
+    Le<BlockSize, U256>: NonZero,
+{
+    /// Set `data` to generated blocks.
+    #[inline]
+    pub fn set_data(
+        &mut self,
+        mut data: &mut [u8],
+        mut process_blocks: impl FnMut(&mut [Block<BlockSize>]),
+    ) {
+        let pos = self.get_pos();
+        let r = self.remaining();
+        let n = data.len();
+        if pos != 0 {
+            if n < r {
+                // double slicing allows to remove panic branches
+                data.copy_from_slice(&self.buffer[pos..][..n]);
+                self.set_pos_unchecked(pos + n);
+                return;
+            }
+            let (left, right) = data.split_at_mut(r);
+            data = right;
+            left.copy_from_slice(&self.buffer[pos..]);
+        }
+
+        let (blocks, leftover) = to_blocks_mut(data);
+        process_blocks(blocks);
+
+        let n = leftover.len();
+        if n != 0 {
+            let mut block = Default::default();
+            process_blocks(slice::from_mut(&mut block));
+            leftover.copy_from_slice(&block[..n]);
+            self.buffer = block;
+        }
+        self.set_pos_unchecked(n);
+    }
+
+    /// Compress remaining data after padding it with `delim`, zeros and
+    /// the `suffix` bytes. If there is not enough unused space, `compress`
+    /// will be called twice.
+    ///
+    /// # Panics
+    /// If suffix length is bigger than block size.
+    #[inline(always)]
+    pub fn digest_pad(
+        &mut self,
+        delim: u8,
+        suffix: &[u8],
+        mut compress: impl FnMut(&Block<BlockSize>),
+    ) {
+        if suffix.len() > BlockSize::USIZE {
+            panic!("suffix is too long");
+        }
+        let pos = self.get_pos();
+        self.buffer[pos] = delim;
+        for b in &mut self.buffer[pos + 1..] {
+            *b = 0;
+        }
+
+        let n = self.size() - suffix.len();
+        if self.size() - pos - 1 < suffix.len() {
+            compress(&self.buffer);
+            let mut block = Block::<BlockSize>::default();
+            block[n..].copy_from_slice(suffix);
+            compress(&block);
+        } else {
+            self.buffer[n..].copy_from_slice(suffix);
+            compress(&self.buffer);
+        }
+        self.set_pos_unchecked(0)
+    }
+
+    /// Pad message with 0x80, zeros and 64-bit message length using
+    /// big-endian byte order.
+    #[inline]
+    pub fn len64_padding_be(&mut self, data_len: u64, compress: impl FnMut(&Block<BlockSize>)) {
+        self.digest_pad(0x80, &data_len.to_be_bytes(), compress);
+    }
+
+    /// Pad message with 0x80, zeros and 64-bit message length using
+    /// little-endian byte order.
+    #[inline]
+    pub fn len64_padding_le(&mut self, data_len: u64, compress: impl FnMut(&Block<BlockSize>)) {
+        self.digest_pad(0x80, &data_len.to_le_bytes(), compress);
+    }
+
+    /// Pad message with 0x80, zeros and 128-bit message length using
+    /// big-endian byte order.
+    #[inline]
+    pub fn len128_padding_be(&mut self, data_len: u128, compress: impl FnMut(&Block<BlockSize>)) {
+        self.digest_pad(0x80, &data_len.to_be_bytes(), compress);
+    }
+}
+
+/// Split message into mutable slice of parallel blocks, blocks, and leftover bytes.
+#[inline(always)]
+fn to_blocks_mut<N: ArrayLength<u8>>(data: &mut [u8]) -> (&mut [Block<N>], &mut [u8]) {
+    let nb = data.len() / N::USIZE;
+    let (left, right) = data.split_at_mut(nb * N::USIZE);
+    let p = left.as_mut_ptr() as *mut Block<N>;
+    // SAFETY: we guarantee that `blocks` does not point outside of `data`, and `p` is valid for
+    // mutation
+    let blocks = unsafe { slice::from_raw_parts_mut(p, nb) };
+    (blocks, right)
+}
diff -Nru cargo-0.66.0/vendor/block-buffer/src/sealed.rs cargo-0.66.0+ds1/vendor/block-buffer/src/sealed.rs
--- cargo-0.66.0/vendor/block-buffer/src/sealed.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/src/sealed.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,67 @@
+use super::{ArrayLength, Block};
+use core::slice;
+
+/// Sealed trait for buffer kinds.
+pub trait Sealed {
+    /// Invariant guaranteed by a buffer kind, i.e. with correct
+    /// buffer code this function always returns true.
+    fn invariant(pos: usize, block_size: usize) -> bool;
+
+    /// Split input data into slice fo blocks and tail.
+    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]);
+}
+
+impl Sealed for super::Eager {
+    #[inline(always)]
+    fn invariant(pos: usize, block_size: usize) -> bool {
+        pos < block_size
+    }
+
+    #[inline(always)]
+    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) {
+        let nb = data.len() / N::USIZE;
+        let blocks_len = nb * N::USIZE;
+        let tail_len = data.len() - blocks_len;
+        // SAFETY: we guarantee that created slices do not point
+        // outside of `data`
+        unsafe {
+            let blocks_ptr = data.as_ptr() as *const Block<N>;
+            let tail_ptr = data.as_ptr().add(blocks_len);
+            (
+                slice::from_raw_parts(blocks_ptr, nb),
+                slice::from_raw_parts(tail_ptr, tail_len),
+            )
+        }
+    }
+}
+
+impl Sealed for super::Lazy {
+    #[inline(always)]
+    fn invariant(pos: usize, block_size: usize) -> bool {
+        pos <= block_size
+    }
+
+    #[inline(always)]
+    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) {
+        if data.is_empty() {
+            return (&[], &[]);
+        }
+        let (nb, tail_len) = if data.len() % N::USIZE == 0 {
+            (data.len() / N::USIZE - 1, N::USIZE)
+        } else {
+            let nb = data.len() / N::USIZE;
+            (nb, data.len() - nb * N::USIZE)
+        };
+        let blocks_len = nb * N::USIZE;
+        // SAFETY: we guarantee that created slices do not point
+        // outside of `data`
+        unsafe {
+            let blocks_ptr = data.as_ptr() as *const Block<N>;
+            let tail_ptr = data.as_ptr().add(blocks_len);
+            (
+                slice::from_raw_parts(blocks_ptr, nb),
+                slice::from_raw_parts(tail_ptr, tail_len),
+            )
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/block-buffer/tests/mod.rs cargo-0.66.0+ds1/vendor/block-buffer/tests/mod.rs
--- cargo-0.66.0/vendor/block-buffer/tests/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/block-buffer/tests/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,196 @@
+use block_buffer::{
+    generic_array::typenum::{U10, U16, U24, U4, U8},
+    Block, EagerBuffer, LazyBuffer,
+};
+
+#[test]
+fn test_eager_digest_pad() {
+    let mut buf = EagerBuffer::<U4>::default();
+    let inputs = [
+        &b"01234567"[..],
+        &b"89"[..],
+        &b"abcdefghij"[..],
+        &b"klmnopqrs"[..],
+        &b"tuv"[..],
+        &b"wx"[..],
+    ];
+    let exp_blocks = [
+        (0, &[b"0123", b"4567"][..]),
+        (2, &[b"89ab"][..]),
+        (2, &[b"cdef", b"ghij"][..]),
+        (3, &[b"klmn", b"opqr"][..]),
+        (4, &[b"stuv"][..]),
+    ];
+    let exp_poses = [0, 2, 0, 1, 0, 2];
+
+    let mut n = 0;
+    for (i, input) in inputs.iter().enumerate() {
+        buf.digest_blocks(input, |b| {
+            let (j, exp) = exp_blocks[n];
+            n += 1;
+            assert_eq!(i, j);
+            assert_eq!(b.len(), exp.len());
+            assert!(b.iter().zip(exp.iter()).all(|v| v.0[..] == v.1[..]));
+        });
+        assert_eq!(exp_poses[i], buf.get_pos());
+    }
+    assert_eq!(buf.pad_with_zeros()[..], b"wx\0\0"[..]);
+    assert_eq!(buf.get_pos(), 0);
+}
+
+#[test]
+fn test_lazy_digest_pad() {
+    let mut buf = LazyBuffer::<U4>::default();
+    let inputs = [
+        &b"01234567"[..],
+        &b"89"[..],
+        &b"abcdefghij"[..],
+        &b"klmnopqrs"[..],
+    ];
+    let expected = [
+        (0, &[b"0123"][..]),
+        (1, &[b"4567"][..]),
+        (2, &[b"89ab"][..]),
+        (2, &[b"cdef"][..]),
+        (3, &[b"ghij"][..]),
+        (3, &[b"klmn", b"opqr"][..]),
+    ];
+    let exp_poses = [4, 2, 4, 1];
+
+    let mut n = 0;
+    for (i, input) in inputs.iter().enumerate() {
+        buf.digest_blocks(input, |b| {
+            let (j, exp) = expected[n];
+            n += 1;
+            assert_eq!(i, j);
+            assert_eq!(b.len(), exp.len());
+            assert!(b.iter().zip(exp.iter()).all(|v| v.0[..] == v.1[..]));
+        });
+        assert_eq!(exp_poses[i], buf.get_pos());
+    }
+    assert_eq!(buf.pad_with_zeros()[..], b"s\0\0\0"[..]);
+    assert_eq!(buf.get_pos(), 0);
+}
+
+#[test]
+fn test_eager_set_data() {
+    let mut buf = EagerBuffer::<U4>::default();
+
+    let mut n = 0u8;
+    let mut gen = |blocks: &mut [Block<U4>]| {
+        for block in blocks {
+            block.iter_mut().for_each(|b| *b = n);
+            n += 1;
+        }
+    };
+
+    let mut out = [0u8; 6];
+    buf.set_data(&mut out, &mut gen);
+    assert_eq!(out, [0, 0, 0, 0, 1, 1]);
+    assert_eq!(buf.get_pos(), 2);
+
+    let mut out = [0u8; 3];
+    buf.set_data(&mut out, &mut gen);
+    assert_eq!(out, [1, 1, 2]);
+    assert_eq!(buf.get_pos(), 1);
+
+    let mut out = [0u8; 3];
+    buf.set_data(&mut out, &mut gen);
+    assert_eq!(out, [2, 2, 2]);
+    assert_eq!(n, 3);
+    assert_eq!(buf.get_pos(), 0);
+}
+
+#[test]
+#[rustfmt::skip]
+fn test_eager_paddings() {
+    let mut buf_be = EagerBuffer::<U8>::new(&[0x42]);
+    let mut buf_le = buf_be.clone();
+    let mut out_be = Vec::<u8>::new();
+    let mut out_le = Vec::<u8>::new();
+    let len = 0x0001_0203_0405_0607;
+    buf_be.len64_padding_be(len, |block| out_be.extend(block));
+    buf_le.len64_padding_le(len, |block| out_le.extend(block));
+
+    assert_eq!(
+        out_be,
+        [
+            0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        ],
+    );
+    assert_eq!(
+        out_le,
+        [
+            0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+        ],
+    );
+
+    let mut buf_be = EagerBuffer::<U10>::new(&[0x42]);
+    let mut buf_le = buf_be.clone();
+    let mut out_be = Vec::<u8>::new();
+    let mut out_le = Vec::<u8>::new();
+    buf_be.len64_padding_be(len, |block| out_be.extend(block));
+    buf_le.len64_padding_le(len, |block| out_le.extend(block));
+
+    assert_eq!(
+        out_be,
+        [0x42, 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
+    );
+    assert_eq!(
+        out_le,
+        [0x42, 0x80, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00],
+    );
+
+    let mut buf = EagerBuffer::<U16>::new(&[0x42]);
+    let mut out = Vec::<u8>::new();
+    let len = 0x0001_0203_0405_0607_0809_0a0b_0c0d_0e0f;
+    buf.len128_padding_be(len, |block| out.extend(block));
+    assert_eq!(
+        out,
+        [
+            0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+        ],
+    );
+
+    let mut buf = EagerBuffer::<U24>::new(&[0x42]);
+    let mut out = Vec::<u8>::new();
+    let len = 0x0001_0203_0405_0607_0809_0a0b_0c0d_0e0f;
+    buf.len128_padding_be(len, |block| out.extend(block));
+    assert_eq!(
+        out,
+        [
+            0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+        ],
+    );
+
+    let mut buf = EagerBuffer::<U4>::new(&[0x42]);
+    let mut out = Vec::<u8>::new();
+    buf.digest_pad(0xff, &[0x10, 0x11, 0x12], |block| out.extend(block));
+    assert_eq!(
+        out,
+        [0x42, 0xff, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12],
+    );
+
+    let mut buf = EagerBuffer::<U4>::new(&[0x42]);
+    let mut out = Vec::<u8>::new();
+    buf.digest_pad(0xff, &[0x10, 0x11], |block| out.extend(block));
+    assert_eq!(
+        out,
+        [0x42, 0xff, 0x10, 0x11],
+    );
+}
+
+#[test]
+fn test_try_new() {
+    assert!(EagerBuffer::<U4>::try_new(&[0; 3]).is_ok());
+    assert!(EagerBuffer::<U4>::try_new(&[0; 4]).is_err());
+    assert!(LazyBuffer::<U4>::try_new(&[0; 4]).is_ok());
+    assert!(LazyBuffer::<U4>::try_new(&[0; 5]).is_err());
+}
diff -Nru cargo-0.66.0/vendor/cpufeatures/.cargo-checksum.json cargo-0.66.0+ds1/vendor/cpufeatures/.cargo-checksum.json
--- cargo-0.66.0/vendor/cpufeatures/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/cpufeatures/Cargo.toml cargo-0.66.0+ds1/vendor/cpufeatures/Cargo.toml
--- cargo-0.66.0/vendor/cpufeatures/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,38 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "cpufeatures"
+version = "0.2.5"
+authors = ["RustCrypto Developers"]
+description = """
+Lightweight runtime CPU feature detection for x86/x86_64 and aarch64 with
+no_std support and support for mobile targets including Android and iOS
+"""
+documentation = "https://docs.rs/cpufeatures"
+readme = "README.md"
+keywords = [
+    "cpuid",
+    "target-feature",
+]
+categories = ["no-std"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/RustCrypto/utils"
+
+[target.aarch64-apple-darwin.dependencies.libc]
+version = "0.2.95"
+
+[target.aarch64-linux-android.dependencies.libc]
+version = "0.2.95"
+
+[target."cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))".dependencies.libc]
+version = "0.2.95"
diff -Nru cargo-0.66.0/vendor/cpufeatures/CHANGELOG.md cargo-0.66.0+ds1/vendor/cpufeatures/CHANGELOG.md
--- cargo-0.66.0/vendor/cpufeatures/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,93 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.2.5 (2022-09-04)
+### Fixed
+- Add workaround for [CPUID bug] in `std` ([#800])
+
+[CPUID bug]: https://github.com/rust-lang/rust/issues/101346
+[#800]: https://github.com/RustCrypto/utils/pull/800
+
+## 0.2.4 (2022-08-22)
+- Re-release v0.2.3 without any changes to fix [#795] ([#796])
+
+[#795]: https://github.com/RustCrypto/utils/issues/795
+[#796]: https://github.com/RustCrypto/utils/pull/796
+
+## 0.2.3 (2022-08-18)
+### Changed
+- Update `libc` version to v0.2.95 ([#789])
+- Disable all target features under MIRI ([#779])
+- Check AVX availability when detecting AVX2 and FMA ([#792])
+
+[#779]: https://github.com/RustCrypto/utils/pull/779
+[#789]: https://github.com/RustCrypto/utils/pull/789
+[#792]: https://github.com/RustCrypto/utils/pull/792
+
+## 0.2.2 (2022-03-18)
+### Added
+- Support for Android on `aarch64` ([#752])
+
+### Removed
+- Vestigial code around `crypto` target feature ([#600])
+
+[#600]: https://github.com/RustCrypto/utils/pull/600
+[#752]: https://github.com/RustCrypto/utils/pull/752
+
+## 0.2.1 (2021-08-26)
+### Changed
+- Revert [#583] "Use from_bytes_with_nul for string check" ([#597])
+
+[#583]: https://github.com/RustCrypto/utils/pull/583
+[#597]: https://github.com/RustCrypto/utils/pull/597
+
+## 0.2.0 (2021-08-26) [YANKED]
+### Removed
+- AArch64 `crypto` target feature ([#594])
+
+[#594]: https://github.com/RustCrypto/utils/pull/594
+
+## 0.1.5 (2021-06-21)
+### Added
+- iOS support ([#435], [#501])
+
+### Changed
+- Map `aarch64` HWCAPs to target features; add `crypto` ([#456])
+
+[#435]: https://github.com/RustCrypto/utils/pull/435
+[#456]: https://github.com/RustCrypto/utils/pull/456
+[#501]: https://github.com/RustCrypto/utils/pull/501
+
+## 0.1.4 (2021-05-14)
+### Added
+- Support compiling on non-Linux/macOS aarch64 targets ([#408])
+
+[#408]: https://github.com/RustCrypto/utils/pull/408
+
+## 0.1.3 (2021-05-13)
+### Removed
+- `neon` on `aarch64` targets: already enabled by default ([#406])
+
+[#406]: https://github.com/RustCrypto/utils/pull/406
+
+## 0.1.2 (2021-05-13) [YANKED]
+### Added
+- `neon` feature detection on `aarch64` targets ([#403])
+
+### Fixed
+- Support for `musl`-based targets ([#403])
+
+[#403]: https://github.com/RustCrypto/utils/pull/403
+
+## 0.1.1 (2021-05-06)
+### Added
+- `aarch64` support for Linux and macOS/M4 targets ([#393])
+
+[#393]: https://github.com/RustCrypto/utils/pull/393
+
+## 0.1.0 (2021-04-29)
+- Initial release
diff -Nru cargo-0.66.0/vendor/cpufeatures/debian/patches/dont-fail-build-on-unsupported-architectures.patch cargo-0.66.0+ds1/vendor/cpufeatures/debian/patches/dont-fail-build-on-unsupported-architectures.patch
--- cargo-0.66.0/vendor/cpufeatures/debian/patches/dont-fail-build-on-unsupported-architectures.patch	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/debian/patches/dont-fail-build-on-unsupported-architectures.patch	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,16 @@
+Description:  Don't fail build on unsupported architectures.
+Author: Peter Michael Green <plugwash at debian.org>
+
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -71,8 +71,8 @@
+ #[cfg(miri)]
+ mod miri;
+ 
+-#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
+-compile_error!("This crate works only on `aarch64`, `x86`, and `x86-64` targets.");
++//#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
++//compile_error!("This crate works only on `aarch64`, `x86`, and `x86-64` targets.");
+ 
+ /// Create module with CPU feature detection code.
+ #[macro_export]
diff -Nru cargo-0.66.0/vendor/cpufeatures/debian/patches/series cargo-0.66.0+ds1/vendor/cpufeatures/debian/patches/series
--- cargo-0.66.0/vendor/cpufeatures/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/debian/patches/series	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+dont-fail-build-on-unsupported-architectures.patch
diff -Nru cargo-0.66.0/vendor/cpufeatures/LICENSE-APACHE cargo-0.66.0+ds1/vendor/cpufeatures/LICENSE-APACHE
--- cargo-0.66.0/vendor/cpufeatures/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/cpufeatures/LICENSE-MIT cargo-0.66.0+ds1/vendor/cpufeatures/LICENSE-MIT
--- cargo-0.66.0/vendor/cpufeatures/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+Copyright (c) 2020 The RustCrypto Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/cpufeatures/README.md cargo-0.66.0+ds1/vendor/cpufeatures/README.md
--- cargo-0.66.0/vendor/cpufeatures/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,90 @@
+# [RustCrypto]: CPU Feature Detection
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+[![Build Status][build-image]][build-link]
+
+Lightweight and efficient runtime CPU feature detection for `aarch64` and
+`x86`/`x86_64` targets.
+
+Supports `no_std` as well as mobile targets including iOS and Android,
+providing an alternative to the `std`-dependent `is_x86_feature_detected!`
+macro.
+
+[Documentation][docs-link]
+
+## Supported architectures
+
+### `aarch64`: Android, iOS, Linux, and macOS/M4 only
+
+Note: ARM64 does not support OS-independent feature detection, so support must
+be implemented on an OS-by-OS basis.
+
+Target features:
+
+- `aes`
+- `sha2`
+- `sha3`
+
+Note: please open a GitHub Issue to request support for additional features.
+
+### `x86`/`x86_64`: OS independent and `no_std`-friendly
+
+Target features:
+
+- `adx`
+- `aes`
+- `avx`
+- `avx2`
+- `bmi1`
+- `bmi2`
+- `fma`
+- `mmx`
+- `pclmulqdq`
+- `popcnt`
+- `rdrand`
+- `rdseed`
+- `sgx`
+- `sha`
+- `sse`
+- `sse2`
+- `sse3`
+- `sse4.1`
+- `sse4.2`
+- `ssse3`
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/cpufeatures.svg
+[crate-link]: https://crates.io/crates/cpufeatures
+[docs-image]: https://docs.rs/cpufeatures/badge.svg
+[docs-link]: https://docs.rs/cpufeatures/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.40+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils
+[build-image]: https://github.com/RustCrypto/utils/workflows/cpufeatures/badge.svg?branch=master&event=push
+[build-link]: https://github.com/RustCrypto/utils/actions/workflows/cpufeatures.yml
+
+[//]: # (general links)
+
+[RustCrypto]: https://github.com/rustcrypto
+[RustCrypto/utils#378]: https://github.com/RustCrypto/utils/issues/378
diff -Nru cargo-0.66.0/vendor/cpufeatures/src/aarch64.rs cargo-0.66.0+ds1/vendor/cpufeatures/src/aarch64.rs
--- cargo-0.66.0/vendor/cpufeatures/src/aarch64.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/src/aarch64.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,182 @@
+//! ARM64 CPU feature detection support.
+//!
+//! Unfortunately ARM instructions to detect CPU features cannot be called from
+//! unprivileged userspace code, so this implementation relies on OS-specific
+//! APIs for feature detection.
+
+// Evaluate the given `$body` expression any of the supplied target features
+// are not enabled. Otherwise returns true.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __unless_target_features {
+    ($($tf:tt),+ => $body:expr ) => {
+        {
+            #[cfg(not(all($(target_feature=$tf,)*)))]
+            $body
+
+            #[cfg(all($(target_feature=$tf,)*))]
+            true
+        }
+    };
+}
+
+// Linux runtime detection of target CPU features using `getauxval`.
+#[cfg(any(target_os = "linux", target_os = "android"))]
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __detect_target_features {
+    ($($tf:tt),+) => {{
+        let hwcaps = $crate::aarch64::getauxval_hwcap();
+        $($crate::check!(hwcaps, $tf) & )+ true
+    }};
+}
+
+/// Linux helper function for calling `getauxval` to get `AT_HWCAP`.
+#[cfg(any(target_os = "linux", target_os = "android"))]
+pub fn getauxval_hwcap() -> u64 {
+    unsafe { libc::getauxval(libc::AT_HWCAP) }
+}
+
+// MacOS runtime detection of target CPU features using `sysctlbyname`.
+#[cfg(target_os = "macos")]
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __detect_target_features {
+    ($($tf:tt),+) => {{
+        $($crate::check!($tf) & )+ true
+    }};
+}
+
+// Linux `expand_check_macro`
+#[cfg(any(target_os = "linux", target_os = "android"))]
+macro_rules! __expand_check_macro {
+    ($(($name:tt, $hwcap:ident)),* $(,)?) => {
+        #[macro_export]
+        #[doc(hidden)]
+        macro_rules! check {
+            $(
+                ($hwcaps:expr, $name) => {
+                    (($hwcaps & $crate::aarch64::hwcaps::$hwcap) != 0)
+                };
+            )*
+        }
+    };
+}
+
+// Linux `expand_check_macro`
+#[cfg(any(target_os = "linux", target_os = "android"))]
+__expand_check_macro! {
+    ("aes",    AES),    // Enable AES support.
+    ("sha2",   SHA2),   // Enable SHA1 and SHA256 support.
+    ("sha3",   SHA3),   // Enable SHA512 and SHA3 support.
+}
+
+/// Linux hardware capabilities mapped to target features.
+///
+/// Note that LLVM target features are coarser grained than what Linux supports
+/// and imply more capabilities under each feature. This module attempts to
+/// provide that mapping accordingly.
+///
+/// See this issue for more info: <https://github.com/RustCrypto/utils/issues/395>
+#[cfg(any(target_os = "linux", target_os = "android"))]
+pub mod hwcaps {
+    use libc::c_ulong;
+
+    pub const AES: c_ulong = libc::HWCAP_AES | libc::HWCAP_PMULL;
+    pub const SHA2: c_ulong = libc::HWCAP_SHA2;
+    pub const SHA3: c_ulong = libc::HWCAP_SHA3 | libc::HWCAP_SHA512;
+}
+
+// macOS `check!` macro.
+//
+// NOTE: several of these instructions (e.g. `aes`, `sha2`) can be assumed to
+// be present on all Apple ARM64 hardware.
+//
+// Newer CPU instructions now have nodes within sysctl's `hw.optional`
+// namespace, however the ones that do not can safely be assumed to be
+// present on all Apple ARM64 devices, now and for the foreseeable future.
+//
+// See discussion on this issue for more information:
+// <https://github.com/RustCrypto/utils/issues/378>
+#[cfg(target_os = "macos")]
+#[macro_export]
+#[doc(hidden)]
+macro_rules! check {
+    ("aes") => {
+        true
+    };
+    ("sha2") => {
+        true
+    };
+    ("sha3") => {
+        unsafe {
+            // `sha3` target feature implies SHA-512 as well
+            $crate::aarch64::sysctlbyname(b"hw.optional.armv8_2_sha512\0")
+                && $crate::aarch64::sysctlbyname(b"hw.optional.armv8_2_sha3\0")
+        }
+    };
+}
+
+/// macOS helper function for calling `sysctlbyname`.
+#[cfg(target_os = "macos")]
+pub unsafe fn sysctlbyname(name: &[u8]) -> bool {
+    assert_eq!(
+        name.last().cloned(),
+        Some(0),
+        "name is not NUL terminated: {:?}",
+        name
+    );
+
+    let mut value: u32 = 0;
+    let mut size = core::mem::size_of::<u32>();
+
+    let rc = libc::sysctlbyname(
+        name.as_ptr() as *const i8,
+        &mut value as *mut _ as *mut libc::c_void,
+        &mut size,
+        core::ptr::null_mut(),
+        0,
+    );
+
+    assert_eq!(size, 4, "unexpected sysctlbyname(3) result size");
+    assert_eq!(rc, 0, "sysctlbyname returned error code: {}", rc);
+    value != 0
+}
+
+// iOS `check!` macro.
+//
+// Unfortunately iOS does not provide access to the `sysctl(3)` API which means
+// we can only return static values for CPU features which  can be assumed to
+// be present on all Apple ARM64 hardware.
+//
+// See discussion on this issue for more information:
+// <https://github.com/RustCrypto/utils/issues/378>
+#[cfg(target_os = "ios")]
+#[macro_export]
+#[doc(hidden)]
+macro_rules! check {
+    ("aes") => {
+        true
+    };
+    ("sha2") => {
+        true
+    };
+    ("sha3") => {
+        false
+    };
+}
+
+// On other targets, runtime CPU feature detection is unavailable
+#[cfg(not(any(
+    target_os = "ios",
+    target_os = "linux",
+    target_os = "android",
+    target_os = "macos"
+)))]
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __detect_target_features {
+    ($($tf:tt),+) => {
+        false
+    };
+}
diff -Nru cargo-0.66.0/vendor/cpufeatures/src/lib.rs cargo-0.66.0+ds1/vendor/cpufeatures/src/lib.rs
--- cargo-0.66.0/vendor/cpufeatures/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,140 @@
+//! This crate provides macros for runtime CPU feature detection. It's intended
+//! as a stopgap until Rust [RFC 2725] adding first-class target feature detection
+//! macros to `libcore` is implemented.
+//!
+//! Supported target architectures:
+//! - `aarch64`: Linux and macOS/M4 only (ARM64 does not support OS-independent feature detection)
+//!   - Target features: `aes`, `sha2`, `sha3`
+//! - `x86`/`x86_64`: OS independent and `no_std`-friendly
+//!   - Target features: `adx`, `aes`, `avx`, `avx2`, `bmi1`, `bmi2`, `fma`,
+//!     `mmx`, `pclmulqdq`, `popcnt`, `rdrand`, `rdseed`, `sgx`, `sha`, `sse`,
+//!     `sse2`, `sse3`, `sse4.1`, `sse4.2`, `ssse3`
+//!
+//! If you would like detection support for a target feature which is not on
+//! this list, please [open a GitHub issue][gh].
+//!
+//! # Example
+//! ```
+//! # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+//! # {
+//! // This macro creates `cpuid_aes_sha` module
+//! cpufeatures::new!(cpuid_aes_sha, "aes", "sha");
+//!
+//! // `token` is a Zero Sized Type (ZST) value, which guarantees
+//! // that underlying static storage got properly initialized,
+//! // which allows to omit initialization branch
+//! let token: cpuid_aes_sha::InitToken = cpuid_aes_sha::init();
+//!
+//! if token.get() {
+//!     println!("CPU supports both SHA and AES extensions");
+//! } else {
+//!     println!("SHA and AES extensions are not supported");
+//! }
+//!
+//! // If stored value needed only once you can get stored value
+//! // omitting the token
+//! let val = cpuid_aes_sha::get();
+//! assert_eq!(val, token.get());
+//!
+//! // Additionally you can get both token and value
+//! let (token, val) = cpuid_aes_sha::init_get();
+//! assert_eq!(val, token.get());
+//! # }
+//! ```
+//!
+//! Note that if all tested target features are enabled via compiler options
+//! (e.g. by using `RUSTFLAGS`), the `get` method will always return `true`
+//! and `init` will not use CPUID instruction. Such behavior allows
+//! compiler to completely eliminate fallback code.
+//!
+//! After first call macro caches result and returns it in subsequent
+//! calls, thus runtime overhead for them is minimal.
+//!
+//! [RFC 2725]: https://github.com/rust-lang/rfcs/pull/2725
+//! [gh]: https://github.com/RustCrypto/utils/issues/new?title=cpufeatures:%20requesting%20support%20for%20CHANGEME%20target%20feature
+
+#![no_std]
+#![doc(
+    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+
+#[cfg(not(miri))]
+#[cfg(all(target_arch = "aarch64"))]
+#[doc(hidden)]
+pub mod aarch64;
+
+#[cfg(not(miri))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+mod x86;
+
+#[cfg(miri)]
+mod miri;
+
+//#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
+//compile_error!("This crate works only on `aarch64`, `x86`, and `x86-64` targets.");
+
+/// Create module with CPU feature detection code.
+#[macro_export]
+macro_rules! new {
+    ($mod_name:ident, $($tf:tt),+ $(,)?) => {
+        mod $mod_name {
+            use core::sync::atomic::{AtomicU8, Ordering::Relaxed};
+
+            const UNINIT: u8 = u8::max_value();
+            static STORAGE: AtomicU8 = AtomicU8::new(UNINIT);
+
+            /// Initialization token
+            #[derive(Copy, Clone, Debug)]
+            pub struct InitToken(());
+
+            impl InitToken {
+                /// Get initialized value
+                #[inline(always)]
+                pub fn get(&self) -> bool {
+                    $crate::__unless_target_features! {
+                        $($tf),+ => {
+                            STORAGE.load(Relaxed) == 1
+                        }
+                    }
+                }
+            }
+
+            /// Initialize underlying storage if needed and get
+            /// stored value and initialization token.
+            #[inline]
+            pub fn init_get() -> (InitToken, bool) {
+                let res = $crate::__unless_target_features! {
+                    $($tf),+ => {
+                        // Relaxed ordering is fine, as we only have a single atomic variable.
+                        let val = STORAGE.load(Relaxed);
+
+                        if val == UNINIT {
+                            let res = $crate::__detect_target_features!($($tf),+);
+                            STORAGE.store(res as u8, Relaxed);
+                            res
+                        } else {
+                            val == 1
+                        }
+                    }
+                };
+
+                (InitToken(()), res)
+            }
+
+            /// Initialize underlying storage if needed and get
+            /// initialization token.
+            #[inline]
+            pub fn init() -> InitToken {
+                init_get().0
+            }
+
+            /// Initialize underlying storage if needed and get
+            /// stored value.
+            #[inline]
+            pub fn get() -> bool {
+                init_get().1
+            }
+        }
+    };
+}
diff -Nru cargo-0.66.0/vendor/cpufeatures/src/miri.rs cargo-0.66.0+ds1/vendor/cpufeatures/src/miri.rs
--- cargo-0.66.0/vendor/cpufeatures/src/miri.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/src/miri.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,20 @@
+//! Minimal miri support.
+//!
+//! Miri is an interpreter, and though it tries to emulate the target CPU
+//! it does not support any target features.
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __unless_target_features {
+    ($($tf:tt),+ => $body:expr ) => {
+        false
+    };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __detect_target_features {
+    ($($tf:tt),+) => {
+        false
+    };
+}
diff -Nru cargo-0.66.0/vendor/cpufeatures/src/x86.rs cargo-0.66.0+ds1/vendor/cpufeatures/src/x86.rs
--- cargo-0.66.0/vendor/cpufeatures/src/x86.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/src/x86.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,105 @@
+//! x86/x86-64 CPU feature detection support.
+//!
+//! Portable, `no_std`-friendly implementation that relies on the x86 `CPUID`
+//! instruction for feature detection.
+
+// Evaluate the given `$body` expression any of the supplied target features
+// are not enabled. Otherwise returns true.
+//
+// The `$body` expression is not evaluated on SGX targets, and returns false
+// on these targets unless *all* supplied target features are enabled.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __unless_target_features {
+    ($($tf:tt),+ => $body:expr ) => {{
+        #[cfg(not(all($(target_feature=$tf,)*)))]
+        {
+            #[cfg(not(target_env = "sgx"))]
+            $body
+
+            // CPUID is not available on SGX targets
+            #[cfg(target_env = "sgx")]
+            false
+        }
+
+        #[cfg(all($(target_feature=$tf,)*))]
+        true
+    }};
+}
+
+// Use CPUID to detect the presence of all supplied target features.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __detect_target_features {
+    ($($tf:tt),+) => {{
+        #[cfg(target_arch = "x86")]
+        use core::arch::x86::{__cpuid, __cpuid_count, CpuidResult};
+        #[cfg(target_arch = "x86_64")]
+        use core::arch::x86_64::{__cpuid, __cpuid_count, CpuidResult};
+
+        // These wrappers are workarounds around
+        // https://github.com/rust-lang/rust/issues/101346
+        //
+        // DO NOT remove it until MSRV is bumped to a version
+        // with the issue fix (at least 1.64).
+        #[inline(never)]
+        unsafe fn cpuid(leaf: u32) -> CpuidResult {
+            __cpuid(leaf)
+        }
+
+        #[inline(never)]
+        unsafe fn cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
+            __cpuid_count(leaf, sub_leaf)
+        }
+
+        let cr = unsafe {
+            [cpuid(1), cpuid_count(7, 0)]
+        };
+
+        $($crate::check!(cr, $tf) & )+ true
+    }};
+}
+
+macro_rules! __expand_check_macro {
+    ($(($name:tt $(, $i:expr, $reg:ident, $offset:expr)*)),* $(,)?) => {
+        #[macro_export]
+        #[doc(hidden)]
+        macro_rules! check {
+            $(
+                ($cr:expr, $name) => {
+                    true
+                    $(
+                        & ($cr[$i].$reg & (1 << $offset) != 0)
+                    )*
+                };
+            )*
+        }
+    };
+}
+
+// Note that according to the [Intel manual][0] AVX2 and FMA require
+// that we check availability of AVX before using them.
+//
+// [0]: https://www.intel.com/content/dam/develop/external/us/en/documents/36945
+__expand_check_macro! {
+    ("mmx", 0, edx, 23),
+    ("sse", 0, edx, 25),
+    ("sse2", 0, edx, 26),
+    ("sse3", 0, ecx, 0),
+    ("pclmulqdq", 0, ecx, 1),
+    ("ssse3", 0, ecx, 9),
+    ("fma", 0, ecx, 28, 0, ecx, 12),
+    ("sse4.1", 0, ecx, 19),
+    ("sse4.2", 0, ecx, 20),
+    ("popcnt", 0, ecx, 23),
+    ("aes", 0, ecx, 25),
+    ("avx", 0, ecx, 28),
+    ("rdrand", 0, ecx, 30),
+    ("sgx", 1, ebx, 2),
+    ("bmi1", 1, ebx, 3),
+    ("avx2", 0, ecx, 28, 1, ebx, 5),
+    ("bmi2", 1, ebx, 8),
+    ("rdseed", 1, ebx, 18),
+    ("adx", 1, ebx, 19),
+    ("sha", 1, ebx, 29),
+}
diff -Nru cargo-0.66.0/vendor/cpufeatures/tests/aarch64.rs cargo-0.66.0+ds1/vendor/cpufeatures/tests/aarch64.rs
--- cargo-0.66.0/vendor/cpufeatures/tests/aarch64.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/tests/aarch64.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,17 @@
+//! ARM64 tests
+
+#![cfg(target_arch = "aarch64")]
+
+cpufeatures::new!(armcaps, "aes", "sha2", "sha3");
+
+#[test]
+fn init() {
+    let token: armcaps::InitToken = armcaps::init();
+    assert_eq!(token.get(), armcaps::get());
+}
+
+#[test]
+fn init_get() {
+    let (token, val) = armcaps::init_get();
+    assert_eq!(val, token.get());
+}
diff -Nru cargo-0.66.0/vendor/cpufeatures/tests/x86.rs cargo-0.66.0+ds1/vendor/cpufeatures/tests/x86.rs
--- cargo-0.66.0/vendor/cpufeatures/tests/x86.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/cpufeatures/tests/x86.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,17 @@
+//! x86/x86_64 tests
+
+#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+
+cpufeatures::new!(cpuid, "aes", "sha");
+
+#[test]
+fn init() {
+    let token: cpuid::InitToken = cpuid::init();
+    assert_eq!(token.get(), cpuid::get());
+}
+
+#[test]
+fn init_get() {
+    let (token, val) = cpuid::init_get();
+    assert_eq!(val, token.get());
+}
diff -Nru cargo-0.66.0/vendor/crypto-common/.cargo-checksum.json cargo-0.66.0+ds1/vendor/crypto-common/.cargo-checksum.json
--- cargo-0.66.0/vendor/crypto-common/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/crypto-common/Cargo.toml cargo-0.66.0+ds1/vendor/crypto-common/Cargo.toml
--- cargo-0.66.0/vendor/crypto-common/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,51 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "crypto-common"
+version = "0.1.6"
+authors = ["RustCrypto Developers"]
+description = "Common cryptographic traits"
+documentation = "https://docs.rs/crypto-common"
+readme = "README.md"
+keywords = [
+    "crypto",
+    "traits",
+]
+categories = [
+    "cryptography",
+    "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/RustCrypto/traits"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+    "--cfg",
+    "docsrs",
+]
+
+[dependencies.generic-array]
+version = "0.14.4"
+features = ["more_lengths"]
+
+[dependencies.rand_core]
+version = "0.6"
+optional = true
+
+[dependencies.typenum]
+version = "1.14"
+
+[features]
+getrandom = ["rand_core/getrandom"]
+std = []
diff -Nru cargo-0.66.0/vendor/crypto-common/CHANGELOG.md cargo-0.66.0+ds1/vendor/crypto-common/CHANGELOG.md
--- cargo-0.66.0/vendor/crypto-common/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,47 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.1.6 (2022-07-16)
+### Added
+- Move `ParBlocks`/`ParBlocksSizeUser` from `cipher` crate ([#1052])
+
+[#1052]: https://github.com/RustCrypto/traits/pull/1052
+
+## 0.1.5 (2022-07-09)
+### Fixed
+- Support on-label MSRV ([#1049])
+
+[#1049]: https://github.com/RustCrypto/traits/pull/1049
+
+## 0.1.4 (2022-07-02)
+### Added
+- `getrandom` feature ([#1034])
+
+[#1034]: https://github.com/RustCrypto/traits/pull/1034
+
+## 0.1.3 (2022-02-16)
+### Fixed
+- Minimal versions build ([#940])
+
+[#940]: https://github.com/RustCrypto/traits/pull/940
+
+## 0.1.2 (2022-02-10)
+### Added
+- Re-export `generic-array` and `typenum`. Enable `more_lengths` feature on
+`generic-array`.  Add `key_size`, `iv_size`, `block_size`, and `output_size`
+helper methods. ([#849])
+
+[#849]: https://github.com/RustCrypto/traits/pull/849
+
+## 0.1.1 (2021-12-14)
+### Added
+- `rand_core` re-export and proper exposure of key/IV generation methods on docs.rs ([#847])
+
+[#847]: https://github.com/RustCrypto/traits/pull/847
+
+## 0.1.0 (2021-12-07)
+- Initial release
diff -Nru cargo-0.66.0/vendor/crypto-common/LICENSE-APACHE cargo-0.66.0+ds1/vendor/crypto-common/LICENSE-APACHE
--- cargo-0.66.0/vendor/crypto-common/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/crypto-common/LICENSE-MIT cargo-0.66.0+ds1/vendor/crypto-common/LICENSE-MIT
--- cargo-0.66.0/vendor/crypto-common/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+Copyright (c) 2021 RustCrypto Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/crypto-common/README.md cargo-0.66.0+ds1/vendor/crypto-common/README.md
--- cargo-0.66.0/vendor/crypto-common/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,53 @@
+# RustCrypto: Common Cryptographic Traits
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+[![Build Status][build-image]][build-link]
+
+Common traits used by cryptographic algorithms. Users should generally use
+higher-level trait crates instead of this one.
+
+[Documentation][docs-link]
+
+## Minimum Supported Rust Version
+
+Rust **1.41** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be
+done with a minor version bump.
+
+## SemVer Policy
+
+- All on-by-default features of this library are covered by SemVer
+- MSRV is considered exempt from SemVer as noted above
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/crypto-common.svg
+[crate-link]: https://crates.io/crates/crypto-common
+[docs-image]: https://docs.rs/crypto-common/badge.svg
+[docs-link]: https://docs.rs/crypto-common/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes
+[build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push
+[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-common
diff -Nru cargo-0.66.0/vendor/crypto-common/src/lib.rs cargo-0.66.0+ds1/vendor/crypto-common/src/lib.rs
--- cargo-0.66.0/vendor/crypto-common/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/crypto-common/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,311 @@
+//! Common cryptographic traits.
+
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![doc(
+    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+#![forbid(unsafe_code)]
+#![warn(missing_docs, rust_2018_idioms)]
+
+#[cfg(feature = "std")]
+extern crate std;
+
+#[cfg(feature = "rand_core")]
+pub use rand_core;
+
+pub use generic_array;
+pub use generic_array::typenum;
+
+use core::fmt;
+use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
+#[cfg(feature = "rand_core")]
+use rand_core::{CryptoRng, RngCore};
+
+/// Block on which [`BlockSizeUser`] implementors operate.
+pub type Block<B> = GenericArray<u8, <B as BlockSizeUser>::BlockSize>;
+
+/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate.
+pub type ParBlocks<T> = GenericArray<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
+
+/// Output array of [`OutputSizeUser`] implementors.
+pub type Output<T> = GenericArray<u8, <T as OutputSizeUser>::OutputSize>;
+
+/// Key used by [`KeySizeUser`] implementors.
+pub type Key<B> = GenericArray<u8, <B as KeySizeUser>::KeySize>;
+
+/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
+pub type Iv<B> = GenericArray<u8, <B as IvSizeUser>::IvSize>;
+
+/// Types which process data in blocks.
+pub trait BlockSizeUser {
+    /// Size of the block in bytes.
+    type BlockSize: ArrayLength<u8> + 'static;
+
+    /// Return block size in bytes.
+    fn block_size() -> usize {
+        Self::BlockSize::USIZE
+    }
+}
+
+impl<T: BlockSizeUser> BlockSizeUser for &T {
+    type BlockSize = T::BlockSize;
+}
+
+impl<T: BlockSizeUser> BlockSizeUser for &mut T {
+    type BlockSize = T::BlockSize;
+}
+
+/// Types which can process blocks in parallel.
+pub trait ParBlocksSizeUser: BlockSizeUser {
+    /// Number of blocks which can be processed in parallel.
+    type ParBlocksSize: ArrayLength<Block<Self>>;
+}
+
+/// Types which return data with the given size.
+pub trait OutputSizeUser {
+    /// Size of the output in bytes.
+    type OutputSize: ArrayLength<u8> + 'static;
+
+    /// Return output size in bytes.
+    fn output_size() -> usize {
+        Self::OutputSize::USIZE
+    }
+}
+
+/// Types which use key for initialization.
+///
+/// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`].
+pub trait KeySizeUser {
+    /// Key size in bytes.
+    type KeySize: ArrayLength<u8> + 'static;
+
+    /// Return key size in bytes.
+    fn key_size() -> usize {
+        Self::KeySize::USIZE
+    }
+}
+
+/// Types which use initialization vector (nonce) for initialization.
+///
+/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`].
+pub trait IvSizeUser {
+    /// Initialization vector size in bytes.
+    type IvSize: ArrayLength<u8> + 'static;
+
+    /// Return IV size in bytes.
+    fn iv_size() -> usize {
+        Self::IvSize::USIZE
+    }
+}
+
+/// Types which use another type for initialization.
+///
+/// Generally it's used indirectly via [`InnerInit`] or [`InnerIvInit`].
+pub trait InnerUser {
+    /// Inner type.
+    type Inner;
+}
+
+/// Resettable types.
+pub trait Reset {
+    /// Reset state to its initial value.
+    fn reset(&mut self);
+}
+
+/// Trait which stores algorithm name constant, used in `Debug` implementations.
+pub trait AlgorithmName {
+    /// Write algorithm name into `f`.
+    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
+}
+
+/// Types which can be initialized from key.
+pub trait KeyInit: KeySizeUser + Sized {
+    /// Create new value from fixed size key.
+    fn new(key: &Key<Self>) -> Self;
+
+    /// Create new value from variable size key.
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+        if key.len() != Self::KeySize::to_usize() {
+            Err(InvalidLength)
+        } else {
+            Ok(Self::new(Key::<Self>::from_slice(key)))
+        }
+    }
+
+    /// Generate random key using the provided [`CryptoRng`].
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    #[inline]
+    fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key<Self> {
+        let mut key = Key::<Self>::default();
+        rng.fill_bytes(&mut key);
+        key
+    }
+}
+
+/// Types which can be initialized from key and initialization vector (nonce).
+pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
+    /// Create new value from fixed length key and nonce.
+    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
+
+    /// Create new value from variable length key and nonce.
+    #[inline]
+    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
+        let key_len = Self::KeySize::USIZE;
+        let iv_len = Self::IvSize::USIZE;
+        if key.len() != key_len || iv.len() != iv_len {
+            Err(InvalidLength)
+        } else {
+            Ok(Self::new(
+                Key::<Self>::from_slice(key),
+                Iv::<Self>::from_slice(iv),
+            ))
+        }
+    }
+
+    /// Generate random key using the provided [`CryptoRng`].
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    #[inline]
+    fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key<Self> {
+        let mut key = Key::<Self>::default();
+        rng.fill_bytes(&mut key);
+        key
+    }
+
+    /// Generate random IV using the provided [`CryptoRng`].
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    #[inline]
+    fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv<Self> {
+        let mut iv = Iv::<Self>::default();
+        rng.fill_bytes(&mut iv);
+        iv
+    }
+
+    /// Generate random key and nonce using the provided [`CryptoRng`].
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    #[inline]
+    fn generate_key_iv(mut rng: impl CryptoRng + RngCore) -> (Key<Self>, Iv<Self>) {
+        (Self::generate_key(&mut rng), Self::generate_iv(&mut rng))
+    }
+}
+
+/// Types which can be initialized from another type (usually block ciphers).
+///
+/// Usually used for initializing types from block ciphers.
+pub trait InnerInit: InnerUser + Sized {
+    /// Initialize value from the `inner`.
+    fn inner_init(inner: Self::Inner) -> Self;
+}
+
+/// Types which can be initialized from another type and additional initialization
+/// vector/nonce.
+///
+/// Usually used for initializing types from block ciphers.
+pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
+    /// Initialize value using `inner` and `iv` array.
+    fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
+
+    /// Initialize value using `inner` and `iv` slice.
+    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
+        if iv.len() != Self::IvSize::to_usize() {
+            Err(InvalidLength)
+        } else {
+            Ok(Self::inner_iv_init(inner, Iv::<Self>::from_slice(iv)))
+        }
+    }
+
+    /// Generate random IV using the provided [`CryptoRng`].
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    #[inline]
+    fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv<Self> {
+        let mut iv = Iv::<Self>::default();
+        rng.fill_bytes(&mut iv);
+        iv
+    }
+}
+
+impl<T> KeySizeUser for T
+where
+    T: InnerUser,
+    T::Inner: KeySizeUser,
+{
+    type KeySize = <T::Inner as KeySizeUser>::KeySize;
+}
+
+impl<T> KeyIvInit for T
+where
+    T: InnerIvInit,
+    T::Inner: KeyInit,
+{
+    #[inline]
+    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
+        Self::inner_iv_init(T::Inner::new(key), iv)
+    }
+
+    #[inline]
+    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
+        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
+    }
+}
+
+impl<T> KeyInit for T
+where
+    T: InnerInit,
+    T::Inner: KeyInit,
+{
+    #[inline]
+    fn new(key: &Key<Self>) -> Self {
+        Self::inner_init(T::Inner::new(key))
+    }
+
+    #[inline]
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+        T::Inner::new_from_slice(key)
+            .map_err(|_| InvalidLength)
+            .map(Self::inner_init)
+    }
+}
+
+// Unfortunately this blanket impl is impossible without mutually
+// exclusive traits, see: https://github.com/rust-lang/rfcs/issues/1053
+// or at the very least without: https://github.com/rust-lang/rust/issues/20400
+/*
+impl<T> KeyIvInit for T
+where
+    T: InnerInit,
+    T::Inner: KeyIvInit,
+{
+    #[inline]
+    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
+        Self::inner_init(T::Inner::new(key, iv))
+    }
+
+    #[inline]
+    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
+        T::Inner::new_from_slice(key)
+            .map_err(|_| InvalidLength)
+            .map(Self::inner_init)
+    }
+}
+*/
+
+/// The error type returned when key and/or IV used in the [`KeyInit`],
+/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
+/// an invalid length.
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub struct InvalidLength;
+
+impl fmt::Display for InvalidLength {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        f.write_str("Invalid Length")
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for InvalidLength {}
diff -Nru cargo-0.66.0/vendor/digest/.cargo-checksum.json cargo-0.66.0+ds1/vendor/digest/.cargo-checksum.json
--- cargo-0.66.0/vendor/digest/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/digest/Cargo.toml cargo-0.66.0+ds1/vendor/digest/Cargo.toml
--- cargo-0.66.0/vendor/digest/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,70 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "digest"
+version = "0.10.6"
+authors = ["RustCrypto Developers"]
+description = "Traits for cryptographic hash functions and message authentication codes"
+documentation = "https://docs.rs/digest"
+readme = "README.md"
+keywords = [
+    "digest",
+    "crypto",
+    "hash",
+]
+categories = [
+    "cryptography",
+    "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/RustCrypto/traits"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+    "--cfg",
+    "docsrs",
+]
+
+[dependencies.blobby]
+version = "0.3"
+optional = true
+
+[dependencies.block-buffer]
+version = "0.10"
+optional = true
+
+#[dependencies.const-oid]
+#version = "0.9"
+#optional = true
+
+[dependencies.crypto-common]
+version = "0.1.3"
+
+[dependencies.subtle]
+version = "=2.4"
+optional = true
+default-features = false
+
+[features]
+alloc = []
+core-api = ["block-buffer"]
+default = ["core-api"]
+dev = ["blobby"]
+mac = ["subtle"]
+#oid = ["const-oid"]
+rand_core = ["crypto-common/rand_core"]
+std = [
+    "alloc",
+    "crypto-common/std",
+]
diff -Nru cargo-0.66.0/vendor/digest/CHANGELOG.md cargo-0.66.0+ds1/vendor/digest/CHANGELOG.md
--- cargo-0.66.0/vendor/digest/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,131 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.10.6 (2022-11-17)
+### Added
+- `Mac::verify_reset` and `Mac::verify_slice_reset` methods ([#1154])
+
+[#1154]: https://github.com/RustCrypto/traits/pull/1154
+
+## 0.10.5 (2022-09-16)
+### Fixed 
+- MSRV build ([#1117])
+
+[#1117]: https://github.com/RustCrypto/traits/pull/1117
+
+## 0.10.4 (2022-09-16)
+### Added
+- Feature-gated implementation of the `const_oid::AssociatedOid` trait
+for the core wrappers. ([#1098])
+
+[#1098]: https://github.com/RustCrypto/traits/pull/1098
+
+## 0.10.3 (2022-02-16)
+### Fixed
+- Minimal versions build ([#940])
+
+[#940]: https://github.com/RustCrypto/traits/pull/940
+
+## 0.10.2 (2022-02-10)
+### Changed
+- Relax bounds on the `Mac` trait ([#849])
+
+[#849]: https://github.com/RustCrypto/traits/pull/849
+
+## 0.10.1 (2021-12-14) [YANKED]
+### Added
+- `Update::chain` and `Digest::new_with_prefix` methods. ([#846])
+- `Mac::generate_key` method. ([#847])
+
+### Fixed
+- Doc cfg attribute for `CtOutput` and `MacError`. ([#842])
+- Expose `KeyInit::generate_key` method in docs. ([#847])
+
+[#842]: https://github.com/RustCrypto/traits/pull/842
+[#846]: https://github.com/RustCrypto/traits/pull/846
+[#847]: https://github.com/RustCrypto/traits/pull/847
+
+## 0.10.0 (2021-12-07) [YANKED]
+### Changed
+- Dirty traits are removed and instead block-level traits are introduced.
+Variable output traits reworked and now support both run and compile time selection of output size. ([#380], [#819])
+- The `crypto-mac` traits are reworked and merged in. ([#819])
+
+[#819]: https://github.com/RustCrypto/traits/pull/819
+[#380]: https://github.com/RustCrypto/traits/pull/380
+
+## 0.9.0 (2020-06-09)
+### Added
+- `ExtendableOutputDirty` and `VariableOutputDirty` traits ([#183])
+- `FixedOutputDirty` trait + `finalize_into*` ([#180])
+- `XofReader::read_boxed` method ([#178], [#181], [#182])
+- `alloc` feature ([#163])
+- Re-export `typenum::consts` as `consts` ([#123])
+- `Output` type alias ([#115])
+
+### Changed
+- Rename `*result*` methods to `finalize` ala IUF ([#161])
+- Use `impl AsRef<[u8]>` instead of generic params on methods ([#112])
+- Rename `Input::input` to `Update::update` ala IUF ([#111])
+- Upgrade to Rust 2018 edition ([#109])
+- Bump `generic-array` to v0.14 ([#95])
+
+[#183]: https://github.com/RustCrypto/traits/pull/183
+[#181]: https://github.com/RustCrypto/traits/pull/181
+[#182]: https://github.com/RustCrypto/traits/pull/182
+[#180]: https://github.com/RustCrypto/traits/pull/180
+[#178]: https://github.com/RustCrypto/traits/pull/178
+[#163]: https://github.com/RustCrypto/traits/pull/163
+[#161]: https://github.com/RustCrypto/traits/pull/161
+[#123]: https://github.com/RustCrypto/traits/pull/123
+[#115]: https://github.com/RustCrypto/traits/pull/115
+[#111]: https://github.com/RustCrypto/traits/pull/111
+[#112]: https://github.com/RustCrypto/traits/pull/112
+[#109]: https://github.com/RustCrypto/traits/pull/109
+[#95]: https://github.com/RustCrypto/traits/pull/95
+
+## 0.8.1 (2019-06-30)
+
+## 0.8.0 (2018-10-01)
+
+## 0.7.6 (2018-09-21)
+
+## 0.7.5 (2018-07-13)
+
+## 0.7.4 (2018-06-21)
+
+## 0.7.3 (2018-06-20)
+
+## 0.7.2 (2017-11-17)
+
+## 0.7.1 (2017-11-15)
+
+## 0.7.0 (2017-11-14)
+
+## 0.6.2 (2017-07-24)
+
+## 0.6.1 (2017-06-18)
+
+## 0.6.0 (2017-06-12)
+
+## 0.5.2 (2017-05-02)
+
+## 0.5.1 (2017-05-02)
+
+## 0.5.0 (2017-04-06)
+
+## 0.4.0 (2016-12-24)
+
+## 0.3.1 (2016-12-16)
+
+## 0.3.0 (2016-11-17)
+
+## 0.2.1 (2016-10-14)
+
+## 0.2.0 (2016-10-14)
+
+## 0.1.0 (2016-10-06)
diff -Nru cargo-0.66.0/vendor/digest/debian/patches/disable-const-oid.diff cargo-0.66.0+ds1/vendor/digest/debian/patches/disable-const-oid.diff
--- cargo-0.66.0/vendor/digest/debian/patches/disable-const-oid.diff	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/debian/patches/disable-const-oid.diff	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+Index: digest/Cargo.toml
+===================================================================
+--- digest.orig/Cargo.toml
++++ digest/Cargo.toml
+@@ -33,9 +33,9 @@ optional = true
+ version = "0.10"
+ optional = true
+ 
+-[dependencies.const-oid]
+-version = "0.9"
+-optional = true
++#[dependencies.const-oid]
++#version = "0.9"
++#optional = true
+ 
+ [dependencies.crypto-common]
+ version = "0.1.3"
+@@ -51,6 +51,6 @@ core-api = ["block-buffer"]
+ default = ["core-api"]
+ dev = ["blobby"]
+ mac = ["subtle"]
+-oid = ["const-oid"]
++#oid = ["const-oid"]
+ rand_core = ["crypto-common/rand_core"]
+ std = ["alloc", "crypto-common/std"]
diff -Nru cargo-0.66.0/vendor/digest/debian/patches/series cargo-0.66.0+ds1/vendor/digest/debian/patches/series
--- cargo-0.66.0/vendor/digest/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/debian/patches/series	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+disable-const-oid.diff
diff -Nru cargo-0.66.0/vendor/digest/LICENSE-APACHE cargo-0.66.0+ds1/vendor/digest/LICENSE-APACHE
--- cargo-0.66.0/vendor/digest/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/digest/LICENSE-MIT cargo-0.66.0+ds1/vendor/digest/LICENSE-MIT
--- cargo-0.66.0/vendor/digest/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+Copyright (c) 2017 Artyom Pavlov
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/digest/README.md cargo-0.66.0+ds1/vendor/digest/README.md
--- cargo-0.66.0/vendor/digest/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,164 @@
+# RustCrypto: Digest Algorithm Traits
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+[![Build Status][build-image]][build-link]
+
+Traits which describe functionality of [cryptographic hash functions][0], a.k.a.
+digest algorithms.
+
+See [RustCrypto/hashes][1] for implementations which use this trait.
+
+[Documentation][docs-link]
+
+## Minimum Supported Rust Version
+
+Rust **1.41** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be
+done with a minor version bump.
+
+## SemVer Policy
+
+- All on-by-default features of this library are covered by SemVer
+- MSRV is considered exempt from SemVer as noted above
+
+## Usage
+
+Let us demonstrate how to use crates in this repository using Sha256 as an
+example.
+
+First add the `sha2` crate to your `Cargo.toml`:
+
+```toml
+[dependencies]
+sha2 = "0.10"
+```
+
+`sha2` and other crates re-export `digest` crate and `Digest` trait for
+convenience, so you don't have to add `digest` crate as an explicit dependency.
+
+Now you can write the following code:
+
+```rust
+use sha2::{Sha256, Digest};
+
+let mut hasher = Sha256::new();
+let data = b"Hello world!";
+hasher.update(data);
+// `input` can be called repeatedly and is generic over `AsRef<[u8]>`
+hasher.update("String data");
+// Note that calling `finalize()` consumes hasher
+let hash = hasher.finalize();
+println!("Result: {:x}", hash);
+```
+
+In this example `hash` has type [`GenericArray<u8, U64>`][2], which is a generic
+alternative to `[u8; 64]`.
+
+Alternatively you can use chained approach, which is equivalent to the previous
+example:
+
+```rust
+let hash = Sha256::new()
+    .chain_update(b"Hello world!")
+    .chain_update("String data")
+    .finalize();
+
+println!("Result: {:x}", hash);
+```
+
+If the whole message is available you also can use convenience `digest` method:
+
+```rust
+let hash = Sha256::digest(b"my message");
+println!("Result: {:x}", hash);
+```
+
+### Hashing `Read`-able objects
+
+If you want to hash data from [`Read`][3] trait (e.g. from file) you can rely on
+implementation of [`Write`][4] trait (requires enabled-by-default `std` feature):
+
+```rust
+use sha2::{Sha256, Digest};
+use std::{fs, io};
+
+let mut file = fs::File::open(&path)?;
+let mut hasher = Sha256::new();
+let n = io::copy(&mut file, &mut hasher)?;
+let hash = hasher.finalize();
+
+println!("Path: {}", path);
+println!("Bytes processed: {}", n);
+println!("Hash value: {:x}", hash);
+```
+
+### Generic code
+
+You can write generic code over `Digest` (or other traits from `digest` crate)
+trait which will work over different hash functions:
+
+```rust
+use digest::Digest;
+
+// Toy example, do not use it in practice!
+// Instead use crates from: https://github.com/RustCrypto/password-hashing
+fn hash_password<D: Digest>(password: &str, salt: &str, output: &mut [u8]) {
+    let mut hasher = D::new();
+    hasher.update(password.as_bytes());
+    hasher.update(b"$");
+    hasher.update(salt.as_bytes());
+    output.copy_from_slice(hasher.finalize().as_slice())
+}
+
+let mut buf1 = [0u8; 32];
+let mut buf2 = [0u8; 64];
+
+hash_password::<sha2::Sha256>("my_password", "abcd", &mut buf1);
+hash_password::<sha2::Sha512>("my_password", "abcd", &mut buf2);
+```
+
+If you want to use hash functions with trait objects, use `digest::DynDigest`
+trait.
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/digest.svg
+[crate-link]: https://crates.io/crates/digest
+[docs-image]: https://docs.rs/digest/badge.svg
+[docs-link]: https://docs.rs/digest/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes
+[build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push
+[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Adigest
+
+[//]: # (general links)
+
+[0]: https://en.wikipedia.org/wiki/Cryptographic_hash_function
+[1]: https://github.com/RustCrypto/hashes
+[2]: https://docs.rs/generic-array
+[3]: https://doc.rust-lang.org/std/io/trait.Read.html
+[4]: https://doc.rust-lang.org/std/io/trait.Write.html
+[5]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
+[6]: https://github.com/RustCrypto/MACs
diff -Nru cargo-0.66.0/vendor/digest/src/core_api/ct_variable.rs cargo-0.66.0+ds1/vendor/digest/src/core_api/ct_variable.rs
--- cargo-0.66.0/vendor/digest/src/core_api/ct_variable.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/core_api/ct_variable.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,204 @@
+use super::{
+    AlgorithmName, Buffer, BufferKindUser, FixedOutputCore, Reset, TruncSide, UpdateCore,
+    VariableOutputCore,
+};
+use crate::HashMarker;
+#[cfg(feature = "mac")]
+use crate::MacMarker;
+#[cfg(feature = "oid")]
+use const_oid::{AssociatedOid, ObjectIdentifier};
+use core::{fmt, marker::PhantomData};
+use crypto_common::{
+    generic_array::{ArrayLength, GenericArray},
+    typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, U256},
+    Block, BlockSizeUser, OutputSizeUser,
+};
+
+/// Dummy type used with [`CtVariableCoreWrapper`] in cases when
+/// resulting hash does not have a known OID.
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
+pub struct NoOid;
+
+/// Wrapper around [`VariableOutputCore`] which selects output size
+/// at compile time.
+#[derive(Clone)]
+pub struct CtVariableCoreWrapper<T, OutSize, O = NoOid>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    inner: T,
+    _out: PhantomData<(OutSize, O)>,
+}
+
+impl<T, OutSize, O> HashMarker for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore + HashMarker,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+#[cfg(feature = "mac")]
+impl<T, OutSize, O> MacMarker for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore + MacMarker,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+impl<T, OutSize, O> BlockSizeUser for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type BlockSize = T::BlockSize;
+}
+
+impl<T, OutSize, O> UpdateCore for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
+        self.inner.update_blocks(blocks);
+    }
+}
+
+impl<T, OutSize, O> OutputSizeUser for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize> + 'static,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type OutputSize = OutSize;
+}
+
+impl<T, OutSize, O> BufferKindUser for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type BufferKind = T::BufferKind;
+}
+
+impl<T, OutSize, O> FixedOutputCore for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize> + 'static,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn finalize_fixed_core(
+        &mut self,
+        buffer: &mut Buffer<Self>,
+        out: &mut GenericArray<u8, Self::OutputSize>,
+    ) {
+        let mut full_res = Default::default();
+        self.inner.finalize_variable_core(buffer, &mut full_res);
+        let n = out.len();
+        let m = full_res.len() - n;
+        match T::TRUNC_SIDE {
+            TruncSide::Left => out.copy_from_slice(&full_res[..n]),
+            TruncSide::Right => out.copy_from_slice(&full_res[m..]),
+        }
+    }
+}
+
+impl<T, OutSize, O> Default for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn default() -> Self {
+        Self {
+            inner: T::new(OutSize::USIZE).unwrap(),
+            _out: PhantomData,
+        }
+    }
+}
+
+impl<T, OutSize, O> Reset for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn reset(&mut self) {
+        *self = Default::default();
+    }
+}
+
+impl<T, OutSize, O> AlgorithmName for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore + AlgorithmName,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        T::write_alg_name(f)?;
+        f.write_str("_")?;
+        write!(f, "{}", OutSize::USIZE)
+    }
+}
+
+#[cfg(feature = "oid")]
+#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
+impl<T, OutSize, O> AssociatedOid for CtVariableCoreWrapper<T, OutSize, O>
+where
+    T: VariableOutputCore,
+    O: AssociatedOid,
+    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
+    LeEq<OutSize, T::OutputSize>: NonZero,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    const OID: ObjectIdentifier = O::OID;
+}
+
+/// Implement dummy type with hidden docs which is used to "carry" hasher
+/// OID for [`CtVariableCoreWrapper`].
+#[macro_export]
+macro_rules! impl_oid_carrier {
+    ($name:ident, $oid:literal) => {
+        #[doc(hidden)]
+        #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
+        pub struct $name;
+
+        #[cfg(feature = "oid")]
+        impl AssociatedOid for $name {
+            const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid);
+        }
+    };
+}
diff -Nru cargo-0.66.0/vendor/digest/src/core_api/rt_variable.rs cargo-0.66.0+ds1/vendor/digest/src/core_api/rt_variable.rs
--- cargo-0.66.0/vendor/digest/src/core_api/rt_variable.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/core_api/rt_variable.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,166 @@
+use super::{AlgorithmName, TruncSide, UpdateCore, VariableOutputCore};
+#[cfg(feature = "mac")]
+use crate::MacMarker;
+use crate::{HashMarker, InvalidBufferSize};
+use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset};
+use block_buffer::BlockBuffer;
+use core::fmt;
+use crypto_common::typenum::{IsLess, Le, NonZero, Unsigned, U256};
+
+/// Wrapper around [`VariableOutputCore`] which selects output size
+/// at run time.
+#[derive(Clone)]
+pub struct RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    core: T,
+    buffer: BlockBuffer<T::BlockSize, T::BufferKind>,
+    output_size: usize,
+}
+
+impl<T> RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> {
+        let Self {
+            core,
+            buffer,
+            output_size,
+        } = self;
+        if out.len() != *output_size || out.len() > Self::MAX_OUTPUT_SIZE {
+            return Err(InvalidBufferSize);
+        }
+        let mut full_res = Default::default();
+        core.finalize_variable_core(buffer, &mut full_res);
+        let n = out.len();
+        let m = full_res.len() - n;
+        match T::TRUNC_SIDE {
+            TruncSide::Left => out.copy_from_slice(&full_res[..n]),
+            TruncSide::Right => out.copy_from_slice(&full_res[m..]),
+        }
+        Ok(())
+    }
+}
+
+impl<T> HashMarker for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + HashMarker,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+#[cfg(feature = "mac")]
+#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
+impl<T> MacMarker for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + MacMarker,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+impl<T> Reset for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore + Reset,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn reset(&mut self) {
+        self.buffer.reset();
+        self.core.reset();
+    }
+}
+
+impl<T> Update for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn update(&mut self, input: &[u8]) {
+        let Self { core, buffer, .. } = self;
+        buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
+    }
+}
+
+impl<T> VariableOutput for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE;
+
+    fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
+        let buffer = Default::default();
+        T::new(output_size).map(|core| Self {
+            core,
+            buffer,
+            output_size,
+        })
+    }
+
+    fn output_size(&self) -> usize {
+        self.output_size
+    }
+
+    fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> {
+        self.finalize_dirty(out)
+    }
+}
+
+impl<T> VariableOutputReset for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore + Reset,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> {
+        self.finalize_dirty(out)?;
+        self.core.reset();
+        self.buffer.reset();
+        Ok(())
+    }
+}
+
+impl<T> fmt::Debug for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore + AlgorithmName,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        T::write_alg_name(f)?;
+        f.write_str(" { .. }")
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl<T> std::io::Write for RtVariableCoreWrapper<T>
+where
+    T: VariableOutputCore + UpdateCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+        Update::update(self, buf);
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn flush(&mut self) -> std::io::Result<()> {
+        Ok(())
+    }
+}
diff -Nru cargo-0.66.0/vendor/digest/src/core_api/wrapper.rs cargo-0.66.0+ds1/vendor/digest/src/core_api/wrapper.rs
--- cargo-0.66.0/vendor/digest/src/core_api/wrapper.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/core_api/wrapper.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,290 @@
+use super::{
+    AlgorithmName, Buffer, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser,
+    Reset, UpdateCore, XofReaderCoreWrapper,
+};
+use crate::{
+    ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update,
+};
+use block_buffer::BlockBuffer;
+use core::fmt;
+use crypto_common::{
+    typenum::{IsLess, Le, NonZero, U256},
+    BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output,
+};
+
+#[cfg(feature = "mac")]
+use crate::MacMarker;
+#[cfg(feature = "oid")]
+use const_oid::{AssociatedOid, ObjectIdentifier};
+
+/// Wrapper around [`BufferKindUser`].
+///
+/// It handles data buffering and implements the slice-based traits.
+#[derive(Clone, Default)]
+pub struct CoreWrapper<T>
+where
+    T: BufferKindUser,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    core: T,
+    buffer: BlockBuffer<T::BlockSize, T::BufferKind>,
+}
+
+impl<T> HashMarker for CoreWrapper<T>
+where
+    T: BufferKindUser + HashMarker,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+#[cfg(feature = "mac")]
+#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
+impl<T> MacMarker for CoreWrapper<T>
+where
+    T: BufferKindUser + MacMarker,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+// this blanket impl is needed for HMAC
+impl<T> BlockSizeUser for CoreWrapper<T>
+where
+    T: BufferKindUser + HashMarker,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type BlockSize = T::BlockSize;
+}
+
+impl<T> CoreWrapper<T>
+where
+    T: BufferKindUser,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    /// Create new wrapper from `core`.
+    #[inline]
+    pub fn from_core(core: T) -> Self {
+        let buffer = Default::default();
+        Self { core, buffer }
+    }
+
+    /// Decompose wrapper into inner parts.
+    #[inline]
+    pub fn decompose(self) -> (T, Buffer<T>) {
+        let Self { core, buffer } = self;
+        (core, buffer)
+    }
+}
+
+impl<T> KeySizeUser for CoreWrapper<T>
+where
+    T: BufferKindUser + KeySizeUser,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type KeySize = T::KeySize;
+}
+
+impl<T> KeyInit for CoreWrapper<T>
+where
+    T: BufferKindUser + KeyInit,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn new(key: &Key<Self>) -> Self {
+        Self {
+            core: T::new(key),
+            buffer: Default::default(),
+        }
+    }
+
+    #[inline]
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+        Ok(Self {
+            core: T::new_from_slice(key)?,
+            buffer: Default::default(),
+        })
+    }
+}
+
+impl<T> fmt::Debug for CoreWrapper<T>
+where
+    T: BufferKindUser + AlgorithmName,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        T::write_alg_name(f)?;
+        f.write_str(" { .. }")
+    }
+}
+
+impl<T> Reset for CoreWrapper<T>
+where
+    T: BufferKindUser + Reset,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn reset(&mut self) {
+        self.core.reset();
+        self.buffer.reset();
+    }
+}
+
+impl<T> Update for CoreWrapper<T>
+where
+    T: BufferKindUser + UpdateCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn update(&mut self, input: &[u8]) {
+        let Self { core, buffer } = self;
+        buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
+    }
+}
+
+impl<T> OutputSizeUser for CoreWrapper<T>
+where
+    T: BufferKindUser + OutputSizeUser,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type OutputSize = T::OutputSize;
+}
+
+impl<T> FixedOutput for CoreWrapper<T>
+where
+    T: FixedOutputCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn finalize_into(mut self, out: &mut Output<Self>) {
+        let Self { core, buffer } = &mut self;
+        core.finalize_fixed_core(buffer, out);
+    }
+}
+
+impl<T> FixedOutputReset for CoreWrapper<T>
+where
+    T: FixedOutputCore + Reset,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
+        let Self { core, buffer } = self;
+        core.finalize_fixed_core(buffer, out);
+        core.reset();
+        buffer.reset();
+    }
+}
+
+impl<T> ExtendableOutput for CoreWrapper<T>
+where
+    T: ExtendableOutputCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+    <T::ReaderCore as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<T::ReaderCore as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    type Reader = XofReaderCoreWrapper<T::ReaderCore>;
+
+    #[inline]
+    fn finalize_xof(self) -> Self::Reader {
+        let (mut core, mut buffer) = self.decompose();
+        let core = core.finalize_xof_core(&mut buffer);
+        let buffer = Default::default();
+        Self::Reader { core, buffer }
+    }
+}
+
+impl<T> ExtendableOutputReset for CoreWrapper<T>
+where
+    T: ExtendableOutputCore + Reset,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+    <T::ReaderCore as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<T::ReaderCore as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn finalize_xof_reset(&mut self) -> Self::Reader {
+        let Self { core, buffer } = self;
+        let reader_core = core.finalize_xof_core(buffer);
+        core.reset();
+        buffer.reset();
+        let buffer = Default::default();
+        Self::Reader {
+            core: reader_core,
+            buffer,
+        }
+    }
+}
+
+#[cfg(feature = "oid")]
+#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
+impl<T> AssociatedOid for CoreWrapper<T>
+where
+    T: BufferKindUser + AssociatedOid,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    const OID: ObjectIdentifier = T::OID;
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl<T> std::io::Write for CoreWrapper<T>
+where
+    T: BufferKindUser + UpdateCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+        Update::update(self, buf);
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn flush(&mut self) -> std::io::Result<()> {
+        Ok(())
+    }
+}
+
+/// A proxy trait to a core type implemented by [`CoreWrapper`]
+// TODO: replace with an inherent associated type on stabilization:
+// https://github.com/rust-lang/rust/issues/8995
+pub trait CoreProxy: sealed::Sealed {
+    /// Type wrapped by [`CoreWrapper`].
+    type Core;
+}
+
+mod sealed {
+    pub trait Sealed {}
+}
+
+impl<T> sealed::Sealed for CoreWrapper<T>
+where
+    T: BufferKindUser,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+}
+
+impl<T> CoreProxy for CoreWrapper<T>
+where
+    T: BufferKindUser,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    type Core = T;
+}
diff -Nru cargo-0.66.0/vendor/digest/src/core_api/xof_reader.rs cargo-0.66.0+ds1/vendor/digest/src/core_api/xof_reader.rs
--- cargo-0.66.0/vendor/digest/src/core_api/xof_reader.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/core_api/xof_reader.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,63 @@
+use super::{AlgorithmName, XofReaderCore};
+use crate::XofReader;
+use block_buffer::EagerBuffer;
+use core::fmt;
+use crypto_common::typenum::{IsLess, Le, NonZero, U256};
+
+/// Wrapper around [`XofReaderCore`] implementations.
+///
+/// It handles data buffering and implements the mid-level traits.
+#[derive(Clone, Default)]
+pub struct XofReaderCoreWrapper<T>
+where
+    T: XofReaderCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    pub(super) core: T,
+    pub(super) buffer: EagerBuffer<T::BlockSize>,
+}
+
+impl<T> fmt::Debug for XofReaderCoreWrapper<T>
+where
+    T: XofReaderCore + AlgorithmName,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        T::write_alg_name(f)?;
+        f.write_str(" { .. }")
+    }
+}
+
+impl<T> XofReader for XofReaderCoreWrapper<T>
+where
+    T: XofReaderCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn read(&mut self, buffer: &mut [u8]) {
+        let Self { core, buffer: buf } = self;
+        buf.set_data(buffer, |blocks| {
+            for block in blocks {
+                *block = core.read_block();
+            }
+        });
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl<T> std::io::Read for XofReaderCoreWrapper<T>
+where
+    T: XofReaderCore,
+    T::BlockSize: IsLess<U256>,
+    Le<T::BlockSize, U256>: NonZero,
+{
+    #[inline]
+    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+        XofReader::read(self, buf);
+        Ok(buf.len())
+    }
+}
diff -Nru cargo-0.66.0/vendor/digest/src/core_api.rs cargo-0.66.0+ds1/vendor/digest/src/core_api.rs
--- cargo-0.66.0/vendor/digest/src/core_api.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/core_api.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,119 @@
+//! Low-level traits operating on blocks and wrappers around them.
+//!
+//! Usage of traits in this module in user code is discouraged. Instead use
+//! core algorithm wrapped by the wrapper types, which implement the
+//! higher-level traits.
+use crate::InvalidOutputSize;
+
+pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset};
+
+use block_buffer::{BlockBuffer, BufferKind};
+use crypto_common::{
+    typenum::{IsLess, Le, NonZero, U256},
+    Output,
+};
+
+mod ct_variable;
+mod rt_variable;
+mod wrapper;
+mod xof_reader;
+
+pub use ct_variable::CtVariableCoreWrapper;
+pub use rt_variable::RtVariableCoreWrapper;
+pub use wrapper::{CoreProxy, CoreWrapper};
+pub use xof_reader::XofReaderCoreWrapper;
+
+/// Buffer type used by type which implements [`BufferKindUser`].
+pub type Buffer<S> =
+    BlockBuffer<<S as BlockSizeUser>::BlockSize, <S as BufferKindUser>::BufferKind>;
+
+/// Types which consume data in blocks.
+pub trait UpdateCore: BlockSizeUser {
+    /// Update state using the provided data blocks.
+    fn update_blocks(&mut self, blocks: &[Block<Self>]);
+}
+
+/// Types which use [`BlockBuffer`] functionality.
+pub trait BufferKindUser: BlockSizeUser {
+    /// Block buffer kind over which type operates.
+    type BufferKind: BufferKind;
+}
+
+/// Core trait for hash functions with fixed output size.
+pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser
+where
+    Self::BlockSize: IsLess<U256>,
+    Le<Self::BlockSize, U256>: NonZero,
+{
+    /// Finalize state using remaining data stored in the provided block buffer,
+    /// write result into provided array and leave `self` in a dirty state.
+    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
+}
+
+/// Core trait for hash functions with extendable (XOF) output size.
+pub trait ExtendableOutputCore: UpdateCore + BufferKindUser
+where
+    Self::BlockSize: IsLess<U256>,
+    Le<Self::BlockSize, U256>: NonZero,
+{
+    /// XOF reader core state.
+    type ReaderCore: XofReaderCore;
+
+    /// Retrieve XOF reader using remaining data stored in the block buffer
+    /// and leave hasher in a dirty state.
+    fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore;
+}
+
+/// Core reader trait for extendable-output function (XOF) result.
+pub trait XofReaderCore: BlockSizeUser {
+    /// Read next XOF block.
+    fn read_block(&mut self) -> Block<Self>;
+}
+
+/// Core trait for hash functions with variable output size.
+///
+/// Maximum output size is equal to [`OutputSizeUser::OutputSize`].
+/// Users are expected to truncate result returned by the
+/// [`finalize_variable_core`] to `output_size` passed to the [`new`] method
+/// during construction. Truncation side is defined by the [`TRUNC_SIDE`]
+/// associated constant.
+///
+/// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core
+/// [`new`]: VariableOutputCore::new
+/// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
+pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized
+where
+    Self::BlockSize: IsLess<U256>,
+    Le<Self::BlockSize, U256>: NonZero,
+{
+    /// Side which should be used in a truncated result.
+    const TRUNC_SIDE: TruncSide;
+
+    /// Initialize hasher state for given output size.
+    ///
+    /// Returns [`InvalidOutputSize`] if `output_size` is not valid for
+    /// the algorithm, e.g. if it's bigger than the [`OutputSize`]
+    /// associated type.
+    ///
+    /// [`OutputSize`]: OutputSizeUser::OutputSize
+    fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
+
+    /// Finalize hasher and write full hashing result into the `out` buffer.
+    ///
+    /// The result must be truncated to `output_size` used during hasher
+    /// construction. Truncation side is defined by the [`TRUNC_SIDE`]
+    /// associated constant.
+    ///
+    /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
+    fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
+}
+
+/// Type which used for defining truncation side in the [`VariableOutputCore`]
+/// trait.
+#[derive(Copy, Clone, Debug)]
+pub enum TruncSide {
+    /// Truncate left side, i.e. `&out[..n]`.
+    Left,
+    /// Truncate right side, i.e. `&out[m..]`.
+    Right,
+}
diff -Nru cargo-0.66.0/vendor/digest/src/dev/fixed.rs cargo-0.66.0+ds1/vendor/digest/src/dev/fixed.rs
--- cargo-0.66.0/vendor/digest/src/dev/fixed.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/dev/fixed.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,65 @@
+use crate::{Digest, FixedOutput, FixedOutputReset, HashMarker, Update};
+use core::fmt::Debug;
+
+/// Fixed-output resettable digest test via the `Digest` trait
+pub fn fixed_reset_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
+where
+    D: FixedOutputReset + Debug + Clone + Default + Update + HashMarker,
+{
+    let mut hasher = D::new();
+    // Test that it works when accepting the message all at once
+    hasher.update(input);
+    let mut hasher2 = hasher.clone();
+    if hasher.finalize()[..] != output[..] {
+        return Some("whole message");
+    }
+
+    // Test if reset works correctly
+    hasher2.reset();
+    hasher2.update(input);
+    if hasher2.finalize_reset()[..] != output[..] {
+        return Some("whole message after reset");
+    }
+
+    // Test that it works when accepting the message in chunks
+    for n in 1..core::cmp::min(17, input.len()) {
+        let mut hasher = D::new();
+        for chunk in input.chunks(n) {
+            hasher.update(chunk);
+            hasher2.update(chunk);
+        }
+        if hasher.finalize()[..] != output[..] {
+            return Some("message in chunks");
+        }
+        if hasher2.finalize_reset()[..] != output[..] {
+            return Some("message in chunks");
+        }
+    }
+
+    None
+}
+
+/// Variable-output resettable digest test
+pub fn fixed_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
+where
+    D: FixedOutput + Default + Debug + Clone,
+{
+    let mut hasher = D::default();
+    // Test that it works when accepting the message all at once
+    hasher.update(input);
+    if hasher.finalize_fixed()[..] != output[..] {
+        return Some("whole message");
+    }
+
+    // Test that it works when accepting the message in chunks
+    for n in 1..core::cmp::min(17, input.len()) {
+        let mut hasher = D::default();
+        for chunk in input.chunks(n) {
+            hasher.update(chunk);
+        }
+        if hasher.finalize_fixed()[..] != output[..] {
+            return Some("message in chunks");
+        }
+    }
+    None
+}
diff -Nru cargo-0.66.0/vendor/digest/src/dev/mac.rs cargo-0.66.0+ds1/vendor/digest/src/dev/mac.rs
--- cargo-0.66.0/vendor/digest/src/dev/mac.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/dev/mac.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,159 @@
+/// Define MAC test
+#[macro_export]
+#[cfg(feature = "mac")]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "dev", feature = "mac"))))]
+macro_rules! new_mac_test {
+    ($name:ident, $test_name:expr, $mac:ty $(,)?) => {
+        digest::new_mac_test!($name, $test_name, $mac, "");
+    };
+    ($name:ident, $test_name:expr, $mac:ty, trunc_left $(,)?) => {
+        digest::new_mac_test!($name, $test_name, $mac, "left");
+    };
+    ($name:ident, $test_name:expr, $mac:ty, trunc_right $(,)?) => {
+        digest::new_mac_test!($name, $test_name, $mac, "right");
+    };
+    ($name:ident, $test_name:expr, $mac:ty, $trunc:expr $(,)?) => {
+        #[test]
+        fn $name() {
+            use core::cmp::min;
+            use digest::dev::blobby::Blob3Iterator;
+            use digest::Mac;
+
+            fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> {
+                let mac0 = <$mac as Mac>::new_from_slice(key).unwrap();
+
+                let mut mac = mac0.clone();
+                mac.update(input);
+                let result = mac.finalize().into_bytes();
+                let n = tag.len();
+                let result_bytes = match $trunc {
+                    "left" => &result[..n],
+                    "right" => &result[result.len() - n..],
+                    _ => &result[..],
+                };
+                if result_bytes != tag {
+                    return Some("whole message");
+                }
+
+                // test reading different chunk sizes
+                for chunk_size in 1..min(64, input.len()) {
+                    let mut mac = mac0.clone();
+                    for chunk in input.chunks(chunk_size) {
+                        mac.update(chunk);
+                    }
+                    let res = match $trunc {
+                        "left" => mac.verify_truncated_left(tag),
+                        "right" => mac.verify_truncated_right(tag),
+                        _ => mac.verify_slice(tag),
+                    };
+                    if res.is_err() {
+                        return Some("chunked message");
+                    }
+                }
+
+                None
+            }
+
+            let data = include_bytes!(concat!("data/", $test_name, ".blb"));
+
+            for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() {
+                let [key, input, tag] = row.unwrap();
+                if let Some(desc) = run_test(key, input, tag) {
+                    panic!(
+                        "\n\
+                         Failed test ?{}: {}\n\
+                         key:\t{:?}\n\
+                         input:\t{:?}\n\
+                         tag:\t{:?}\n",
+                        i, desc, key, input, tag,
+                    );
+                }
+            }
+        }
+    };
+}
+
+/// Define resettable MAC test
+#[macro_export]
+#[cfg(feature = "mac")]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "dev", feature = "mac"))))]
+macro_rules! new_resettable_mac_test {
+    ($name:ident, $test_name:expr, $mac:ty $(,)?) => {
+        digest::new_resettable_mac_test!($name, $test_name, $mac, "");
+    };
+    ($name:ident, $test_name:expr, $mac:ty, trunc_left $(,)?) => {
+        digest::new_resettable_mac_test!($name, $test_name, $mac, "left");
+    };
+    ($name:ident, $test_name:expr, $mac:ty, trunc_right $(,)?) => {
+        digest::new_resettable_mac_test!($name, $test_name, $mac, "right");
+    };
+    ($name:ident, $test_name:expr, $mac:ty, $trunc:expr $(,)?) => {
+        #[test]
+        fn $name() {
+            use core::cmp::min;
+            use digest::dev::blobby::Blob3Iterator;
+            use digest::Mac;
+
+            fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> {
+                let mac0 = <$mac as Mac>::new_from_slice(key).unwrap();
+
+                let mut mac = mac0.clone();
+                mac.update(input);
+                let result = mac.finalize_reset().into_bytes();
+                let n = tag.len();
+                let result_bytes = match $trunc {
+                    "left" => &result[..n],
+                    "right" => &result[result.len() - n..],
+                    _ => &result[..],
+                };
+                if result_bytes != tag {
+                    return Some("whole message");
+                }
+
+                // test if reset worked correctly
+                mac.update(input);
+                let res = match $trunc {
+                    "left" => mac.verify_truncated_left(tag),
+                    "right" => mac.verify_truncated_right(tag),
+                    _ => mac.verify_slice(tag),
+                };
+                if res.is_err() {
+                    return Some("after reset");
+                }
+
+                // test reading different chunk sizes
+                for chunk_size in 1..min(64, input.len()) {
+                    let mut mac = mac0.clone();
+                    for chunk in input.chunks(chunk_size) {
+                        mac.update(chunk);
+                    }
+                    let res = match $trunc {
+                        "left" => mac.verify_truncated_left(tag),
+                        "right" => mac.verify_truncated_right(tag),
+                        _ => mac.verify_slice(tag),
+                    };
+                    if res.is_err() {
+                        return Some("chunked message");
+                    }
+                }
+                None
+            }
+
+            let data = include_bytes!(concat!("data/", $test_name, ".blb"));
+
+            for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() {
+                let [key, input, tag] = row.unwrap();
+                if let Some(desc) = run_test(key, input, tag) {
+                    panic!(
+                        "\n\
+                         Failed test ?{}: {}\n\
+                         key:\t{:?}\n\
+                         input:\t{:?}\n\
+                         tag:\t{:?}\n",
+                        i, desc, key, input, tag,
+                    );
+                }
+            }
+        }
+    };
+}
diff -Nru cargo-0.66.0/vendor/digest/src/dev/rng.rs cargo-0.66.0+ds1/vendor/digest/src/dev/rng.rs
--- cargo-0.66.0/vendor/digest/src/dev/rng.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/dev/rng.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,38 @@
+//! Xorshift RNG used for tests. Based on the `rand_xorshift` crate.
+use core::num::Wrapping;
+
+/// Initial RNG state used in tests.
+// chosen by fair dice roll. guaranteed to be random.
+pub(crate) const RNG: XorShiftRng = XorShiftRng {
+    x: Wrapping(0x0787_3B4A),
+    y: Wrapping(0xFAAB_8FFE),
+    z: Wrapping(0x1745_980F),
+    w: Wrapping(0xB0AD_B4F3),
+};
+
+/// Xorshift RNG instance/
+pub(crate) struct XorShiftRng {
+    x: Wrapping<u32>,
+    y: Wrapping<u32>,
+    z: Wrapping<u32>,
+    w: Wrapping<u32>,
+}
+
+impl XorShiftRng {
+    pub(crate) fn fill(&mut self, buf: &mut [u8; 1024]) {
+        for chunk in buf.chunks_exact_mut(4) {
+            chunk.copy_from_slice(&self.next_u32().to_le_bytes());
+        }
+    }
+
+    fn next_u32(&mut self) -> u32 {
+        let x = self.x;
+        let t = x ^ (x << 11);
+        self.x = self.y;
+        self.y = self.z;
+        self.z = self.w;
+        let w = self.w;
+        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
+        self.w.0
+    }
+}
diff -Nru cargo-0.66.0/vendor/digest/src/dev/variable.rs cargo-0.66.0+ds1/vendor/digest/src/dev/variable.rs
--- cargo-0.66.0/vendor/digest/src/dev/variable.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/dev/variable.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,82 @@
+use crate::{VariableOutput, VariableOutputReset};
+use core::fmt::Debug;
+
+/// Variable-output resettable digest test
+pub fn variable_reset_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
+where
+    D: VariableOutputReset + Debug + Clone,
+{
+    let mut hasher = D::new(output.len()).unwrap();
+    let mut buf = [0u8; 128];
+    let buf = &mut buf[..output.len()];
+    // Test that it works when accepting the message all at once
+    hasher.update(input);
+    let mut hasher2 = hasher.clone();
+    hasher.finalize_variable(buf).unwrap();
+    if buf != output {
+        return Some("whole message");
+    }
+    buf.iter_mut().for_each(|b| *b = 0);
+
+    // Test if reset works correctly
+    hasher2.reset();
+    hasher2.update(input);
+    hasher2.finalize_variable_reset(buf).unwrap();
+    if buf != output {
+        return Some("whole message after reset");
+    }
+    buf.iter_mut().for_each(|b| *b = 0);
+
+    // Test that it works when accepting the message in chunks
+    for n in 1..core::cmp::min(17, input.len()) {
+        let mut hasher = D::new(output.len()).unwrap();
+        for chunk in input.chunks(n) {
+            hasher.update(chunk);
+            hasher2.update(chunk);
+        }
+        hasher.finalize_variable(buf).unwrap();
+        if buf != output {
+            return Some("message in chunks");
+        }
+        buf.iter_mut().for_each(|b| *b = 0);
+
+        hasher2.finalize_variable_reset(buf).unwrap();
+        if buf != output {
+            return Some("message in chunks");
+        }
+        buf.iter_mut().for_each(|b| *b = 0);
+    }
+
+    None
+}
+
+/// Variable-output resettable digest test
+pub fn variable_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
+where
+    D: VariableOutput + Debug + Clone,
+{
+    let mut hasher = D::new(output.len()).unwrap();
+    let mut buf = [0u8; 128];
+    let buf = &mut buf[..output.len()];
+    // Test that it works when accepting the message all at once
+    hasher.update(input);
+    hasher.finalize_variable(buf).unwrap();
+    if buf != output {
+        return Some("whole message");
+    }
+    buf.iter_mut().for_each(|b| *b = 0);
+
+    // Test that it works when accepting the message in chunks
+    for n in 1..core::cmp::min(17, input.len()) {
+        let mut hasher = D::new(output.len()).unwrap();
+        for chunk in input.chunks(n) {
+            hasher.update(chunk);
+        }
+        hasher.finalize_variable(buf).unwrap();
+        if buf != output {
+            return Some("message in chunks");
+        }
+        buf.iter_mut().for_each(|b| *b = 0);
+    }
+    None
+}
diff -Nru cargo-0.66.0/vendor/digest/src/dev/xof.rs cargo-0.66.0+ds1/vendor/digest/src/dev/xof.rs
--- cargo-0.66.0/vendor/digest/src/dev/xof.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/dev/xof.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,51 @@
+use crate::ExtendableOutputReset;
+use core::fmt::Debug;
+
+/// Resettable XOF test
+pub fn xof_reset_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
+where
+    D: ExtendableOutputReset + Default + Debug + Clone,
+{
+    let mut hasher = D::default();
+    let mut buf = [0u8; 1024];
+    let buf = &mut buf[..output.len()];
+    // Test that it works when accepting the message all at once
+    hasher.update(input);
+    let mut hasher2 = hasher.clone();
+    hasher.finalize_xof_into(buf);
+    if buf != output {
+        return Some("whole message");
+    }
+    buf.iter_mut().for_each(|b| *b = 0);
+
+    // Test if reset works correctly
+    hasher2.reset();
+    hasher2.update(input);
+    hasher2.finalize_xof_reset_into(buf);
+    if buf != output {
+        return Some("whole message after reset");
+    }
+    buf.iter_mut().for_each(|b| *b = 0);
+
+    // Test that it works when accepting the message in chunks
+    for n in 1..core::cmp::min(17, input.len()) {
+        let mut hasher = D::default();
+        for chunk in input.chunks(n) {
+            hasher.update(chunk);
+            hasher2.update(chunk);
+        }
+        hasher.finalize_xof_into(buf);
+        if buf != output {
+            return Some("message in chunks");
+        }
+        buf.iter_mut().for_each(|b| *b = 0);
+
+        hasher2.finalize_xof_reset_into(buf);
+        if buf != output {
+            return Some("message in chunks");
+        }
+        buf.iter_mut().for_each(|b| *b = 0);
+    }
+
+    None
+}
diff -Nru cargo-0.66.0/vendor/digest/src/dev.rs cargo-0.66.0+ds1/vendor/digest/src/dev.rs
--- cargo-0.66.0/vendor/digest/src/dev.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/dev.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,78 @@
+//! Development-related functionality
+
+pub use blobby;
+
+mod fixed;
+mod mac;
+mod rng;
+mod variable;
+mod xof;
+
+pub use fixed::*;
+pub use mac::*;
+pub use variable::*;
+pub use xof::*;
+
+/// Define hash function test
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+macro_rules! new_test {
+    ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident $(,)?) => {
+        #[test]
+        fn $name() {
+            use digest::dev::blobby::Blob2Iterator;
+            let data = include_bytes!(concat!("data/", $test_name, ".blb"));
+
+            for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() {
+                let [input, output] = row.unwrap();
+                if let Some(desc) = $test_func::<$hasher>(input, output) {
+                    panic!(
+                        "\n\
+                         Failed test ?{}: {}\n\
+                         input:\t{:?}\n\
+                         output:\t{:?}\n",
+                        i, desc, input, output,
+                    );
+                }
+            }
+        }
+    };
+}
+
+/// Define [`Update`][crate::Update] impl benchmark
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+macro_rules! bench_update {
+    (
+        $init:expr;
+        $($name:ident $bs:expr;)*
+    ) => {
+        $(
+            #[bench]
+            fn $name(b: &mut Bencher) {
+                let mut d = $init;
+                let data = [0; $bs];
+
+                b.iter(|| {
+                    digest::Update::update(&mut d, &data[..]);
+                });
+
+                b.bytes = $bs;
+            }
+        )*
+    };
+}
+
+/// Feed ~1 MiB of pseudorandom data to an updatable state.
+pub fn feed_rand_16mib<D: crate::Update>(d: &mut D) {
+    let buf = &mut [0u8; 1024];
+    let mut rng = rng::RNG;
+    let n = 16 * (1 << 20) / buf.len();
+    for _ in 0..n {
+        rng.fill(buf);
+        d.update(buf);
+        // additional byte, so size of fed data
+        // will not be multiple of block size
+        d.update(&[42]);
+    }
+}
diff -Nru cargo-0.66.0/vendor/digest/src/digest.rs cargo-0.66.0+ds1/vendor/digest/src/digest.rs
--- cargo-0.66.0/vendor/digest/src/digest.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/digest.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,236 @@
+use super::{FixedOutput, FixedOutputReset, InvalidBufferSize, Reset, Update};
+use crypto_common::{typenum::Unsigned, Output, OutputSizeUser};
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+
+/// Marker trait for cryptographic hash functions.
+pub trait HashMarker {}
+
+/// Convenience wrapper trait covering functionality of cryptographic hash
+/// functions with fixed output size.
+///
+/// This trait wraps [`Update`], [`FixedOutput`], [`Default`], and
+/// [`HashMarker`] traits and provides additional convenience methods.
+pub trait Digest: OutputSizeUser {
+    /// Create new hasher instance.
+    fn new() -> Self;
+
+    /// Create new hasher instance which has processed the provided data.
+    fn new_with_prefix(data: impl AsRef<[u8]>) -> Self;
+
+    /// Process data, updating the internal state.
+    fn update(&mut self, data: impl AsRef<[u8]>);
+
+    /// Process input data in a chained manner.
+    #[must_use]
+    fn chain_update(self, data: impl AsRef<[u8]>) -> Self;
+
+    /// Retrieve result and consume hasher instance.
+    fn finalize(self) -> Output<Self>;
+
+    /// Write result into provided array and consume the hasher instance.
+    fn finalize_into(self, out: &mut Output<Self>);
+
+    /// Retrieve result and reset hasher instance.
+    fn finalize_reset(&mut self) -> Output<Self>
+    where
+        Self: FixedOutputReset;
+
+    /// Write result into provided array and reset the hasher instance.
+    fn finalize_into_reset(&mut self, out: &mut Output<Self>)
+    where
+        Self: FixedOutputReset;
+
+    /// Reset hasher instance to its initial state.
+    fn reset(&mut self)
+    where
+        Self: Reset;
+
+    /// Get output size of the hasher
+    fn output_size() -> usize;
+
+    /// Compute hash of `data`.
+    fn digest(data: impl AsRef<[u8]>) -> Output<Self>;
+}
+
+impl<D: FixedOutput + Default + Update + HashMarker> Digest for D {
+    #[inline]
+    fn new() -> Self {
+        Self::default()
+    }
+
+    #[inline]
+    fn new_with_prefix(data: impl AsRef<[u8]>) -> Self
+    where
+        Self: Default + Sized,
+    {
+        let mut h = Self::default();
+        h.update(data.as_ref());
+        h
+    }
+
+    #[inline]
+    fn update(&mut self, data: impl AsRef<[u8]>) {
+        Update::update(self, data.as_ref());
+    }
+
+    #[inline]
+    fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self {
+        Update::update(&mut self, data.as_ref());
+        self
+    }
+
+    #[inline]
+    fn finalize(self) -> Output<Self> {
+        FixedOutput::finalize_fixed(self)
+    }
+
+    #[inline]
+    fn finalize_into(self, out: &mut Output<Self>) {
+        FixedOutput::finalize_into(self, out);
+    }
+
+    #[inline]
+    fn finalize_reset(&mut self) -> Output<Self>
+    where
+        Self: FixedOutputReset,
+    {
+        FixedOutputReset::finalize_fixed_reset(self)
+    }
+
+    #[inline]
+    fn finalize_into_reset(&mut self, out: &mut Output<Self>)
+    where
+        Self: FixedOutputReset,
+    {
+        FixedOutputReset::finalize_into_reset(self, out);
+    }
+
+    #[inline]
+    fn reset(&mut self)
+    where
+        Self: Reset,
+    {
+        Reset::reset(self)
+    }
+
+    #[inline]
+    fn output_size() -> usize {
+        Self::OutputSize::to_usize()
+    }
+
+    #[inline]
+    fn digest(data: impl AsRef<[u8]>) -> Output<Self> {
+        let mut hasher = Self::default();
+        hasher.update(data.as_ref());
+        hasher.finalize()
+    }
+}
+
+/// Modification of the [`Digest`] trait suitable for trait objects.
+pub trait DynDigest {
+    /// Digest input data.
+    ///
+    /// This method can be called repeatedly for use with streaming messages.
+    fn update(&mut self, data: &[u8]);
+
+    /// Retrieve result and reset hasher instance
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn finalize_reset(&mut self) -> Box<[u8]> {
+        let mut result = vec![0; self.output_size()];
+        self.finalize_into_reset(&mut result).unwrap();
+        result.into_boxed_slice()
+    }
+
+    /// Retrieve result and consume boxed hasher instance
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    #[allow(clippy::boxed_local)]
+    fn finalize(mut self: Box<Self>) -> Box<[u8]> {
+        let mut result = vec![0; self.output_size()];
+        self.finalize_into_reset(&mut result).unwrap();
+        result.into_boxed_slice()
+    }
+
+    /// Write result into provided array and consume the hasher instance.
+    ///
+    /// Returns error if buffer length is not equal to `output_size`.
+    fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize>;
+
+    /// Write result into provided array and reset the hasher instance.
+    ///
+    /// Returns error if buffer length is not equal to `output_size`.
+    fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
+
+    /// Reset hasher instance to its initial state.
+    fn reset(&mut self);
+
+    /// Get output size of the hasher
+    fn output_size(&self) -> usize;
+
+    /// Clone hasher state into a boxed trait object
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn box_clone(&self) -> Box<dyn DynDigest>;
+}
+
+impl<D: Update + FixedOutputReset + Reset + Clone + 'static> DynDigest for D {
+    fn update(&mut self, data: &[u8]) {
+        Update::update(self, data);
+    }
+
+    #[cfg(feature = "alloc")]
+    fn finalize_reset(&mut self) -> Box<[u8]> {
+        FixedOutputReset::finalize_fixed_reset(self)
+            .to_vec()
+            .into_boxed_slice()
+    }
+
+    #[cfg(feature = "alloc")]
+    fn finalize(self: Box<Self>) -> Box<[u8]> {
+        FixedOutput::finalize_fixed(*self)
+            .to_vec()
+            .into_boxed_slice()
+    }
+
+    fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> {
+        if buf.len() == self.output_size() {
+            FixedOutput::finalize_into(self, Output::<Self>::from_mut_slice(buf));
+            Ok(())
+        } else {
+            Err(InvalidBufferSize)
+        }
+    }
+
+    fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> {
+        if buf.len() == self.output_size() {
+            FixedOutputReset::finalize_into_reset(self, Output::<Self>::from_mut_slice(buf));
+            Ok(())
+        } else {
+            Err(InvalidBufferSize)
+        }
+    }
+
+    fn reset(&mut self) {
+        Reset::reset(self);
+    }
+
+    fn output_size(&self) -> usize {
+        <Self as OutputSizeUser>::OutputSize::to_usize()
+    }
+
+    #[cfg(feature = "alloc")]
+    fn box_clone(&self) -> Box<dyn DynDigest> {
+        Box::new(self.clone())
+    }
+}
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl Clone for Box<dyn DynDigest> {
+    fn clone(&self) -> Self {
+        self.box_clone()
+    }
+}
diff -Nru cargo-0.66.0/vendor/digest/src/lib.rs cargo-0.66.0+ds1/vendor/digest/src/lib.rs
--- cargo-0.66.0/vendor/digest/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,301 @@
+//! This crate provides traits which describe functionality of cryptographic hash
+//! functions and Message Authentication algorithms.
+//!
+//! Traits in this repository are organized into the following levels:
+//!
+//! - **High-level convenience traits**: [`Digest`], [`DynDigest`], [`Mac`].
+//!   Wrappers around lower-level traits for most common use-cases. Users should
+//!   usually prefer using these traits.
+//! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`FixedOutputReset`],
+//!   [`ExtendableOutput`], [`ExtendableOutputReset`], [`XofReader`],
+//!   [`VariableOutput`], [`Reset`], [`KeyInit`], and [`InnerInit`]. These
+//!   traits atomically describe available functionality of an algorithm.
+//! - **Marker traits**: [`HashMarker`], [`MacMarker`]. Used to distinguish
+//!   different algorithm classes.
+//! - **Low-level traits** defined in the [`core_api`] module. These traits
+//!   operate at a block-level and do not contain any built-in buffering.
+//!   They are intended to be implemented by low-level algorithm providers only.
+//!   Usually they should not be used in application-level code.
+//!
+//! Additionally hash functions implement traits from the standard library:
+//! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is
+//! feature-gated behind `std` feature, which is usually enabled by default
+//! by hash implementation crates.
+
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![forbid(unsafe_code)]
+#![doc(
+    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+#![warn(missing_docs, rust_2018_idioms)]
+
+#[cfg(feature = "alloc")]
+#[macro_use]
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+#[cfg(feature = "rand_core")]
+#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+pub use crypto_common::rand_core;
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+
+#[cfg(feature = "dev")]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+pub mod dev;
+
+#[cfg(feature = "core-api")]
+#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))]
+pub mod core_api;
+mod digest;
+#[cfg(feature = "mac")]
+mod mac;
+
+#[cfg(feature = "core-api")]
+#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))]
+pub use block_buffer;
+#[cfg(feature = "oid")]
+#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
+pub use const_oid;
+pub use crypto_common;
+
+pub use crate::digest::{Digest, DynDigest, HashMarker};
+pub use crypto_common::{generic_array, typenum, typenum::consts, Output, OutputSizeUser, Reset};
+#[cfg(feature = "mac")]
+pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit};
+#[cfg(feature = "mac")]
+pub use mac::{CtOutput, Mac, MacError, MacMarker};
+
+use core::fmt;
+
+/// Types which consume data with byte granularity.
+pub trait Update {
+    /// Update state using the provided data.
+    fn update(&mut self, data: &[u8]);
+
+    /// Digest input data in a chained manner.
+    #[must_use]
+    fn chain(mut self, data: impl AsRef<[u8]>) -> Self
+    where
+        Self: Sized,
+    {
+        self.update(data.as_ref());
+        self
+    }
+}
+
+/// Trait for hash functions with fixed-size output.
+pub trait FixedOutput: Update + OutputSizeUser + Sized {
+    /// Consume value and write result into provided array.
+    fn finalize_into(self, out: &mut Output<Self>);
+
+    /// Retrieve result and consume the hasher instance.
+    #[inline]
+    fn finalize_fixed(self) -> Output<Self> {
+        let mut out = Default::default();
+        self.finalize_into(&mut out);
+        out
+    }
+}
+
+/// Trait for hash functions with fixed-size output able to reset themselves.
+pub trait FixedOutputReset: FixedOutput + Reset {
+    /// Write result into provided array and reset the hasher state.
+    fn finalize_into_reset(&mut self, out: &mut Output<Self>);
+
+    /// Retrieve result and reset the hasher state.
+    #[inline]
+    fn finalize_fixed_reset(&mut self) -> Output<Self> {
+        let mut out = Default::default();
+        self.finalize_into_reset(&mut out);
+        out
+    }
+}
+
+/// Trait for reader types which are used to extract extendable output
+/// from a XOF (extendable-output function) result.
+pub trait XofReader {
+    /// Read output into the `buffer`. Can be called an unlimited number of times.
+    fn read(&mut self, buffer: &mut [u8]);
+
+    /// Read output into a boxed slice of the specified size.
+    ///
+    /// Can be called an unlimited number of times in combination with `read`.
+    ///
+    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
+    /// they have size of 2 and 3 words respectively.
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn read_boxed(&mut self, n: usize) -> Box<[u8]> {
+        let mut buf = vec![0u8; n].into_boxed_slice();
+        self.read(&mut buf);
+        buf
+    }
+}
+
+/// Trait for hash functions with extendable-output (XOF).
+pub trait ExtendableOutput: Sized + Update {
+    /// Reader
+    type Reader: XofReader;
+
+    /// Retrieve XOF reader and consume hasher instance.
+    fn finalize_xof(self) -> Self::Reader;
+
+    /// Finalize XOF and write result into `out`.
+    fn finalize_xof_into(self, out: &mut [u8]) {
+        self.finalize_xof().read(out);
+    }
+
+    /// Compute hash of `data` and write it into `output`.
+    fn digest_xof(input: impl AsRef<[u8]>, output: &mut [u8])
+    where
+        Self: Default,
+    {
+        let mut hasher = Self::default();
+        hasher.update(input.as_ref());
+        hasher.finalize_xof().read(output);
+    }
+
+    /// Retrieve result into a boxed slice of the specified size and consume
+    /// the hasher.
+    ///
+    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
+    /// they have size of 2 and 3 words respectively.
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn finalize_boxed(self, output_size: usize) -> Box<[u8]> {
+        let mut buf = vec![0u8; output_size].into_boxed_slice();
+        self.finalize_xof().read(&mut buf);
+        buf
+    }
+}
+
+/// Trait for hash functions with extendable-output (XOF) able to reset themselves.
+pub trait ExtendableOutputReset: ExtendableOutput + Reset {
+    /// Retrieve XOF reader and reset hasher instance state.
+    fn finalize_xof_reset(&mut self) -> Self::Reader;
+
+    /// Finalize XOF, write result into `out`, and reset the hasher state.
+    fn finalize_xof_reset_into(&mut self, out: &mut [u8]) {
+        self.finalize_xof_reset().read(out);
+    }
+
+    /// Retrieve result into a boxed slice of the specified size and reset
+    /// the hasher state.
+    ///
+    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
+    /// they have size of 2 and 3 words respectively.
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn finalize_boxed_reset(&mut self, output_size: usize) -> Box<[u8]> {
+        let mut buf = vec![0u8; output_size].into_boxed_slice();
+        self.finalize_xof_reset().read(&mut buf);
+        buf
+    }
+}
+
+/// Trait for hash functions with variable-size output.
+pub trait VariableOutput: Sized + Update {
+    /// Maximum size of output hash.
+    const MAX_OUTPUT_SIZE: usize;
+
+    /// Create new hasher instance with the given output size.
+    ///
+    /// It will return `Err(InvalidOutputSize)` in case if hasher can not return
+    /// hash of the specified output size.
+    fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
+
+    /// Get output size of the hasher instance provided to the `new` method
+    fn output_size(&self) -> usize;
+
+    /// Write result into the output buffer.
+    ///
+    /// Returns `Err(InvalidOutputSize)` if `out` size is not equal to
+    /// `self.output_size()`.
+    fn finalize_variable(self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
+
+    /// Compute hash of `data` and write it to `output`.
+    ///
+    /// Length of the output hash is determined by `output`. If `output` is
+    /// bigger than `Self::MAX_OUTPUT_SIZE`, this method returns
+    /// `InvalidOutputSize`.
+    fn digest_variable(
+        input: impl AsRef<[u8]>,
+        output: &mut [u8],
+    ) -> Result<(), InvalidOutputSize> {
+        let mut hasher = Self::new(output.len())?;
+        hasher.update(input.as_ref());
+        hasher
+            .finalize_variable(output)
+            .map_err(|_| InvalidOutputSize)
+    }
+
+    /// Retrieve result into a boxed slice and consume hasher.
+    ///
+    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
+    /// they have size of 2 and 3 words respectively.
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn finalize_boxed(self) -> Box<[u8]> {
+        let n = self.output_size();
+        let mut buf = vec![0u8; n].into_boxed_slice();
+        self.finalize_variable(&mut buf)
+            .expect("buf length is equal to output_size");
+        buf
+    }
+}
+
+/// Trait for hash functions with variable-size output able to reset themselves.
+pub trait VariableOutputReset: VariableOutput + Reset {
+    /// Write result into the output buffer and reset the hasher state.
+    ///
+    /// Returns `Err(InvalidOutputSize)` if `out` size is not equal to
+    /// `self.output_size()`.
+    fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
+
+    /// Retrieve result into a boxed slice and reset the hasher state.
+    ///
+    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
+    /// they have size of 2 and 3 words respectively.
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    fn finalize_boxed_reset(&mut self) -> Box<[u8]> {
+        let n = self.output_size();
+        let mut buf = vec![0u8; n].into_boxed_slice();
+        self.finalize_variable_reset(&mut buf)
+            .expect("buf length is equal to output_size");
+        buf
+    }
+}
+
+/// The error type used in variable hash traits.
+#[derive(Clone, Copy, Debug, Default)]
+pub struct InvalidOutputSize;
+
+impl fmt::Display for InvalidOutputSize {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("invalid output size")
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl std::error::Error for InvalidOutputSize {}
+
+/// Buffer length is not equal to hash output size.
+#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
+pub struct InvalidBufferSize;
+
+impl fmt::Display for InvalidBufferSize {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("invalid buffer length")
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for InvalidBufferSize {}
diff -Nru cargo-0.66.0/vendor/digest/src/mac.rs cargo-0.66.0+ds1/vendor/digest/src/mac.rs
--- cargo-0.66.0/vendor/digest/src/mac.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/digest/src/mac.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,305 @@
+use crate::{FixedOutput, FixedOutputReset, Update};
+use crypto_common::{InvalidLength, Key, KeyInit, Output, OutputSizeUser, Reset};
+
+#[cfg(feature = "rand_core")]
+use crate::rand_core::{CryptoRng, RngCore};
+use core::fmt;
+use crypto_common::typenum::Unsigned;
+use subtle::{Choice, ConstantTimeEq};
+
+/// Marker trait for Message Authentication algorithms.
+#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
+pub trait MacMarker {}
+
+/// Convenience wrapper trait covering functionality of Message Authentication algorithms.
+///
+/// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`]
+/// traits and provides additional convenience methods.
+#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
+pub trait Mac: OutputSizeUser + Sized {
+    /// Create new value from fixed size key.
+    fn new(key: &Key<Self>) -> Self
+    where
+        Self: KeyInit;
+
+    /// Generate random key using the provided [`CryptoRng`].
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    fn generate_key(rng: impl CryptoRng + RngCore) -> Key<Self>
+    where
+        Self: KeyInit;
+
+    /// Create new value from variable size key.
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength>
+    where
+        Self: KeyInit;
+
+    /// Update state using the provided data.
+    fn update(&mut self, data: &[u8]);
+
+    /// Process input data in a chained manner.
+    #[must_use]
+    fn chain_update(self, data: impl AsRef<[u8]>) -> Self;
+
+    /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and consume
+    /// [`Mac`] instance.
+    fn finalize(self) -> CtOutput<Self>;
+
+    /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and reset
+    /// [`Mac`] instance.
+    fn finalize_reset(&mut self) -> CtOutput<Self>
+    where
+        Self: FixedOutputReset;
+
+    /// Reset MAC instance to its initial state.
+    fn reset(&mut self)
+    where
+        Self: Reset;
+
+    /// Check if tag/code value is correct for the processed input.
+    fn verify(self, tag: &Output<Self>) -> Result<(), MacError>;
+
+    /// Check if tag/code value is correct for the processed input and reset
+    /// [`Mac`] instance.
+    fn verify_reset(&mut self, tag: &Output<Self>) -> Result<(), MacError>
+    where
+        Self: FixedOutputReset;
+
+    /// Check truncated tag correctness using all bytes
+    /// of calculated tag.
+    ///
+    /// Returns `Error` if `tag` is not valid or not equal in length
+    /// to MAC's output.
+    fn verify_slice(self, tag: &[u8]) -> Result<(), MacError>;
+
+    /// Check truncated tag correctness using all bytes
+    /// of calculated tag and reset [`Mac`] instance.
+    ///
+    /// Returns `Error` if `tag` is not valid or not equal in length
+    /// to MAC's output.
+    fn verify_slice_reset(&mut self, tag: &[u8]) -> Result<(), MacError>
+    where
+        Self: FixedOutputReset;
+
+    /// Check truncated tag correctness using left side bytes
+    /// (i.e. `tag[..n]`) of calculated tag.
+    ///
+    /// Returns `Error` if `tag` is not valid or empty.
+    fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError>;
+
+    /// Check truncated tag correctness using right side bytes
+    /// (i.e. `tag[n..]`) of calculated tag.
+    ///
+    /// Returns `Error` if `tag` is not valid or empty.
+    fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError>;
+}
+
+impl<T: Update + FixedOutput + MacMarker> Mac for T {
+    #[inline(always)]
+    fn new(key: &Key<Self>) -> Self
+    where
+        Self: KeyInit,
+    {
+        KeyInit::new(key)
+    }
+
+    #[inline(always)]
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength>
+    where
+        Self: KeyInit,
+    {
+        KeyInit::new_from_slice(key)
+    }
+
+    #[inline]
+    fn update(&mut self, data: &[u8]) {
+        Update::update(self, data);
+    }
+
+    #[inline]
+    fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self {
+        Update::update(&mut self, data.as_ref());
+        self
+    }
+
+    #[inline]
+    fn finalize(self) -> CtOutput<Self> {
+        CtOutput::new(self.finalize_fixed())
+    }
+
+    #[inline(always)]
+    fn finalize_reset(&mut self) -> CtOutput<Self>
+    where
+        Self: FixedOutputReset,
+    {
+        CtOutput::new(self.finalize_fixed_reset())
+    }
+
+    #[inline]
+    fn reset(&mut self)
+    where
+        Self: Reset,
+    {
+        Reset::reset(self)
+    }
+
+    #[inline]
+    fn verify(self, tag: &Output<Self>) -> Result<(), MacError> {
+        if self.finalize() == tag.into() {
+            Ok(())
+        } else {
+            Err(MacError)
+        }
+    }
+
+    #[inline]
+    fn verify_reset(&mut self, tag: &Output<Self>) -> Result<(), MacError>
+    where
+        Self: FixedOutputReset,
+    {
+        if self.finalize_reset() == tag.into() {
+            Ok(())
+        } else {
+            Err(MacError)
+        }
+    }
+
+    #[inline]
+    fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> {
+        let n = tag.len();
+        if n != Self::OutputSize::USIZE {
+            return Err(MacError);
+        }
+        let choice = self.finalize_fixed().ct_eq(tag);
+        if choice.into() {
+            Ok(())
+        } else {
+            Err(MacError)
+        }
+    }
+
+    #[inline]
+    fn verify_slice_reset(&mut self, tag: &[u8]) -> Result<(), MacError>
+    where
+        Self: FixedOutputReset,
+    {
+        let n = tag.len();
+        if n != Self::OutputSize::USIZE {
+            return Err(MacError);
+        }
+        let choice = self.finalize_fixed_reset().ct_eq(tag);
+        if choice.into() {
+            Ok(())
+        } else {
+            Err(MacError)
+        }
+    }
+
+    fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> {
+        let n = tag.len();
+        if n == 0 || n > Self::OutputSize::USIZE {
+            return Err(MacError);
+        }
+        let choice = self.finalize_fixed()[..n].ct_eq(tag);
+
+        if choice.into() {
+            Ok(())
+        } else {
+            Err(MacError)
+        }
+    }
+
+    fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError> {
+        let n = tag.len();
+        if n == 0 || n > Self::OutputSize::USIZE {
+            return Err(MacError);
+        }
+        let m = Self::OutputSize::USIZE - n;
+        let choice = self.finalize_fixed()[m..].ct_eq(tag);
+
+        if choice.into() {
+            Ok(())
+        } else {
+            Err(MacError)
+        }
+    }
+
+    #[cfg(feature = "rand_core")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+    #[inline]
+    fn generate_key(rng: impl CryptoRng + RngCore) -> Key<Self>
+    where
+        Self: KeyInit,
+    {
+        <T as KeyInit>::generate_key(rng)
+    }
+}
+
+/// Fixed size output value which provides a safe [`Eq`] implementation that
+/// runs in constant time.
+///
+/// It is useful for implementing Message Authentication Codes (MACs).
+#[derive(Clone)]
+#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
+pub struct CtOutput<T: OutputSizeUser> {
+    bytes: Output<T>,
+}
+
+impl<T: OutputSizeUser> CtOutput<T> {
+    /// Create a new [`CtOutput`] value.
+    #[inline(always)]
+    pub fn new(bytes: Output<T>) -> Self {
+        Self { bytes }
+    }
+
+    /// Get the inner [`Output`] array this type wraps.
+    #[inline(always)]
+    pub fn into_bytes(self) -> Output<T> {
+        self.bytes
+    }
+}
+
+impl<T: OutputSizeUser> From<Output<T>> for CtOutput<T> {
+    #[inline(always)]
+    fn from(bytes: Output<T>) -> Self {
+        Self { bytes }
+    }
+}
+
+impl<'a, T: OutputSizeUser> From<&'a Output<T>> for CtOutput<T> {
+    #[inline(always)]
+    fn from(bytes: &'a Output<T>) -> Self {
+        bytes.clone().into()
+    }
+}
+
+impl<T: OutputSizeUser> ConstantTimeEq for CtOutput<T> {
+    #[inline(always)]
+    fn ct_eq(&self, other: &Self) -> Choice {
+        self.bytes.ct_eq(&other.bytes)
+    }
+}
+
+impl<T: OutputSizeUser> PartialEq for CtOutput<T> {
+    #[inline(always)]
+    fn eq(&self, x: &CtOutput<T>) -> bool {
+        self.ct_eq(x).into()
+    }
+}
+
+impl<T: OutputSizeUser> Eq for CtOutput<T> {}
+
+/// Error type for when the [`Output`] of a [`Mac`]
+/// is not equal to the expected value.
+#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
+#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
+pub struct MacError;
+
+impl fmt::Display for MacError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("MAC tag mismatch")
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for MacError {}
diff -Nru cargo-0.66.0/vendor/generic-array/build.rs cargo-0.66.0+ds1/vendor/generic-array/build.rs
--- cargo-0.66.0/vendor/generic-array/build.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/build.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,5 @@
+fn main() {
+    if version_check::is_min_version("1.41.0").unwrap_or(false) {
+        println!("cargo:rustc-cfg=relaxed_coherence");
+    }
+}
diff -Nru cargo-0.66.0/vendor/generic-array/.cargo-checksum.json cargo-0.66.0+ds1/vendor/generic-array/.cargo-checksum.json
--- cargo-0.66.0/vendor/generic-array/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/generic-array/Cargo.toml cargo-0.66.0+ds1/vendor/generic-array/Cargo.toml
--- cargo-0.66.0/vendor/generic-array/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,75 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+name = "generic-array"
+version = "0.14.6"
+authors = [
+    "Bart?omiej Kami?ski <fizyk20 at gmail.com>",
+    "Aaron Trent <novacrazy at gmail.com>",
+]
+include = [
+    "src/**/*",
+    "LICENSE",
+    "README.md",
+    "CHANGELOG.md",
+    "build.rs",
+]
+description = "Generic types implementing functionality of arrays"
+documentation = "http://fizyk20.github.io/generic-array/generic_array/"
+readme = "README.md"
+keywords = [
+    "generic",
+    "array",
+]
+categories = [
+    "data-structures",
+    "no-std",
+]
+license = "MIT"
+repository = "https://github.com/fizyk20/generic-array.git"
+
+[package.metadata.docs.rs]
+features = [
+    "serde",
+    "zeroize",
+]
+
+[lib]
+name = "generic_array"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+default-features = false
+
+[dependencies.typenum]
+version = "1.12"
+
+[dependencies.zeroize]
+version = "1"
+optional = true
+default-features = false
+
+[dev-dependencies.bincode]
+version = "1.0"
+
+[dev-dependencies.serde_json]
+version = "1.0"
+
+[build-dependencies.version_check]
+version = "0.9"
+
+[features]
+more_lengths = []
+
+[badges.travis-ci]
+repository = "fizyk20/generic-array"
diff -Nru cargo-0.66.0/vendor/generic-array/CHANGELOG.md cargo-0.66.0+ds1/vendor/generic-array/CHANGELOG.md
--- cargo-0.66.0/vendor/generic-array/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,98 @@
+* **`0.14.6`**
+    * Add an optional `Zeroize` impl for `GenericArray` (#126 and #112)
+    * Cleanup some unsafe (#125) and typos (#114)
+    * Use `include` in `Cargo.toml` to reduce package size
+
+* **`0.14.5`**
+    * Fix unsoundness behavior in `GenericArrayIter::clone` ([#120](https://github.com/fizyk20/generic-array/pull/120))
+
+* **`0.14.4`**
+    * Update `typenum` to `1.12.0`
+    * Make `Drop` a no-op when the inner type does not require `Drop` (using `core::mem::needs_drop`)
+
+* **`0.14.3`**
+    * Improve behavior of `GenericArray::from_exact_iter` to assume `ExactIterator`s can lie.
+    * Fix alignment of zero-length `GenericArray`s
+    * Implement `From<&[T; N]> for &GenericArray<T, N>` and its mutable variant
+
+* **`0.14.2`**
+    * Lower MSRV to `1.36.0` without `From<[T; N]>` implementations.
+
+* **`0.14.1`**
+    * Fix element conversions in `arr!` macro.
+
+* **`0.14.0`**
+    * Replace `Into` implementations with the more general `From`.
+        * Requires minumum Rust version of 1.41.0
+    * Fix unsoundness in `arr!` macro.
+    * Fix meta variable misuse
+    * Fix Undefined Behavior across the crate by switching to `MaybeUninit`
+    * Improve some documentation and doctests
+    * Add `AsRef<[T; N]>` and `AsMut<[T; N]>` impls to `GenericArray<T, N>`
+    * Add `Split` impl for `&GenericArray` and `&mut GenericArray`
+
+* **`0.13.2`**
+    * Add feature `more_lengths`, which adds more `From`/`Into` implementations for arrays of various lengths.
+
+* **`0.13.1`**
+    * Mark `GenericArray` as `#[repr(transparent)]`
+    * Implement `Into<[T; N]>` for `GenericArray<T, N>` up to N=32
+
+* **`0.13.0`**
+    * Allow `arr!` to be imported with use syntax.
+        * Requires minumum Rust version of 1.30.1
+
+* **`0.12.2`**
+    * Implement `FusedIterator` for `GenericArrayIter`
+
+* **`0.12.1`**
+    * Use internal iteration where possible and provide more efficient internal iteration methods.
+
+* **`0.12.0`**
+    * Allow trailing commas in `arr!` macro.
+    * **BREAKING**: Serialize `GenericArray` using `serde` tuples, instead of variable-length sequences. This may not be compatible with old serialized data.
+
+* **`0.11.0`**
+    * **BREAKING** Redesign `GenericSequence` with an emphasis on use in generic type parameters.
+    * Add `MappedGenericSequence` and `FunctionalSequence`
+        * Implements optimized `map`, `zip` and `fold` for `GenericArray`, `&GenericArray` and `&mut GenericArray`
+    * **BREAKING** Remove `map_ref`, `zip_ref` and `map_slice`
+        * `map_slice` is now equivalent to `GenericArray::from_iter(slice.iter().map(...))`
+* **`0.10.0`**
+    * Add `GenericSequence`, `Lengthen`, `Shorten`, `Split` and `Concat` traits.
+    * Redefine `transmute` to avert errors.
+* **`0.9.0`**
+    * Rewrite construction methods to be well-defined in panic situations, correctly dropping elements.
+    * `NoDrop` crate replaced by `ManuallyDrop` as it became stable in Rust core.
+    * Add optimized `map`/`map_ref` and `zip`/`zip_ref` methods to `GenericArray`
+* **`0.8.0`**
+    * Implement `AsRef`, `AsMut`, `Borrow`, `BorrowMut`, `Hash` for `GenericArray`
+    * Update `serde` to `1.0`
+    * Update `typenum`
+    * Make macro `arr!` non-cloning
+    * Implement `From<[T; N]>` up to `N=32`
+    * Fix #45
+* **`0.7.0`**
+    * Upgrade `serde` to `0.9`
+    * Make `serde` with `no_std`
+    * Implement `PartialOrd`/`Ord` for `GenericArray`
+* **`0.6.0`**
+    * Fixed #30
+    * Implement `Default` for `GenericArray`
+    * Implement `LowerHex` and `UpperHex` for `GenericArray<u8, N>`
+    * Use `precision` formatting field in hex representation
+    * Add `as_slice`, `as_mut_slice`
+    * Remove `GenericArray::new` in favor of `Default` trait
+    * Add `from_slice` and `from_mut_slice`
+    * `no_std` and `core` for crate.
+* **`0.5.0`**
+    * Update `serde`
+    * remove `no_std` feature, fixed #19
+* **`0.4.0`**
+    * Re-export `typenum`
+* **`0.3.0`**
+    * Implement `IntoIter` for `GenericArray`
+    * Add `map` method
+    * Add optional `serde` (de)serialization support feature.
+* **`< 0.3.0`**
+    * Initial implementation in late 2015
diff -Nru cargo-0.66.0/vendor/generic-array/LICENSE cargo-0.66.0+ds1/vendor/generic-array/LICENSE
--- cargo-0.66.0/vendor/generic-array/LICENSE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/LICENSE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Bart?omiej Kami?ski
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/generic-array/README.md cargo-0.66.0+ds1/vendor/generic-array/README.md
--- cargo-0.66.0/vendor/generic-array/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,62 @@
+[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)](https://crates.io/crates/generic-array)
+[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)](https://travis-ci.org/fizyk20/generic-array)
+# generic-array
+
+This crate implements generic array types for Rust.
+
+**Requires minumum Rust version of 1.36.0, or 1.41.0 for `From<[T; N]>` implementations**
+
+[Documentation](http://fizyk20.github.io/generic-array/generic_array/)
+
+## Usage
+
+The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work:
+
+```rust
+struct Foo<N> {
+	data: [i32; N]
+}
+```
+
+**generic-array** defines a new trait `ArrayLength<T>` and a struct `GenericArray<T, N: ArrayLength<T>>`, which let the above be implemented as:
+
+```rust
+struct Foo<N: ArrayLength<i32>> {
+	data: GenericArray<i32, N>
+}
+```
+
+The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](http://fizyk20.github.io/generic-array/typenum/uint/index.html) from [typenum](http://fizyk20.github.io/generic-array/typenum/index.html) crate:
+
+```rust
+use generic_array::typenum::U5;
+
+struct Foo<N: ArrayLength<i32>> {
+    data: GenericArray<i32, N>
+}
+
+fn main() {
+    let foo = Foo::<U5>{data: GenericArray::default()};
+}
+```
+
+For example, `GenericArray<T, U5>` would work almost like `[T; 5]`:
+
+```rust
+use generic_array::typenum::U5;
+
+struct Foo<T, N: ArrayLength<T>> {
+    data: GenericArray<T, N>
+}
+
+fn main() {
+    let foo = Foo::<i32, U5>{data: GenericArray::default()};
+}
+```
+
+In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below:
+
+```rust
+let array = arr![u32; 1, 2, 3];
+assert_eq!(array[2], 3);
+```
diff -Nru cargo-0.66.0/vendor/generic-array/src/arr.rs cargo-0.66.0+ds1/vendor/generic-array/src/arr.rs
--- cargo-0.66.0/vendor/generic-array/src/arr.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/arr.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,125 @@
+//! Implementation for `arr!` macro.
+
+use super::ArrayLength;
+use core::ops::Add;
+use typenum::U1;
+
+/// Helper trait for `arr!` macro
+pub trait AddLength<T, N: ArrayLength<T>>: ArrayLength<T> {
+    /// Resulting length
+    type Output: ArrayLength<T>;
+}
+
+impl<T, N1, N2> AddLength<T, N2> for N1
+where
+    N1: ArrayLength<T> + Add<N2>,
+    N2: ArrayLength<T>,
+    <N1 as Add<N2>>::Output: ArrayLength<T>,
+{
+    type Output = <N1 as Add<N2>>::Output;
+}
+
+/// Helper type for `arr!` macro
+pub type Inc<T, U> = <U as AddLength<T, U1>>::Output;
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! arr_impl {
+    (@replace_expr $e:expr) => { 1 };
+    ($T:ty; $N:ty, [$($x:expr),*], []) => ({
+        const __ARR_LENGTH: usize = 0 $(+ $crate::arr_impl!(@replace_expr $x) )*;
+
+        #[inline(always)]
+        fn __do_transmute<T, N: $crate::ArrayLength<T>>(arr: [T; __ARR_LENGTH]) -> $crate::GenericArray<T, N> {
+            unsafe { $crate::transmute(arr) }
+        }
+
+        let _: [(); <$N as $crate::typenum::Unsigned>::USIZE] = [(); __ARR_LENGTH];
+
+        __do_transmute::<$T, $N>([$($x as $T),*])
+    });
+    ($T:ty; $N:ty, [], [$x1:expr]) => (
+        $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1], [])
+    );
+    ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => (
+        $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1], [$($x),+])
+    );
+    ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => (
+        $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1], [])
+    );
+    ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => (
+        $crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1], [$($x),+])
+    );
+}
+
+/// Macro allowing for easy generation of Generic Arrays.
+/// Example: `let test = arr![u32; 1, 2, 3];`
+#[macro_export]
+macro_rules! arr {
+    ($T:ty; $(,)*) => ({
+        unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) }
+    });
+    ($T:ty; $($x:expr),* $(,)*) => (
+        $crate::arr_impl!($T; $crate::typenum::U0, [], [$($x),*])
+    );
+    ($($x:expr,)+) => (arr![$($x),+]);
+    () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`")
+}
+
+mod doctests_only {
+    ///
+    /// # With ellision
+    ///
+    /// Testing that lifetimes aren't transmuted when they're ellided.
+    ///
+    /// ```compile_fail
+    /// #[macro_use] extern crate generic_array;
+    /// fn main() {
+    ///    fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
+    ///        arr![&A; a][0]
+    ///    }
+    /// }
+    /// ```
+    ///
+    /// ```rust
+    /// #[macro_use] extern crate generic_array;
+    /// fn main() {
+    ///    fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'a A {
+    ///        arr![&A; a][0]
+    ///    }
+    /// }
+    /// ```
+    ///
+    /// # Without ellision
+    ///
+    /// Testing that lifetimes aren't transmuted when they're specified explicitly.
+    ///
+    /// ```compile_fail
+    /// #[macro_use] extern crate generic_array;
+    /// fn main() {
+    ///    fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
+    ///        arr![&'a A; a][0]
+    ///    }
+    /// }
+    /// ```
+    ///
+    /// ```compile_fail
+    /// #[macro_use] extern crate generic_array;
+    /// fn main() {
+    ///    fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
+    ///        arr![&'static A; a][0]
+    ///    }
+    /// }
+    /// ```
+    ///
+    /// ```rust
+    /// #[macro_use] extern crate generic_array;
+    /// fn main() {
+    ///    fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'a A {
+    ///        arr![&'a A; a][0]
+    ///    }
+    /// }
+    /// ```
+    #[allow(dead_code)]
+    pub enum DocTests {}
+}
diff -Nru cargo-0.66.0/vendor/generic-array/src/functional.rs cargo-0.66.0+ds1/vendor/generic-array/src/functional.rs
--- cargo-0.66.0/vendor/generic-array/src/functional.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/functional.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,95 @@
+//! Functional programming with generic sequences
+//!
+//! Please see `tests/generics.rs` for examples of how to best use these in your generic functions.
+
+use super::ArrayLength;
+use core::iter::FromIterator;
+
+use crate::sequence::*;
+
+/// Defines the relationship between one generic sequence and another,
+/// for operations such as `map` and `zip`.
+pub unsafe trait MappedGenericSequence<T, U>: GenericSequence<T>
+where
+    Self::Length: ArrayLength<U>,
+{
+    /// Mapped sequence type
+    type Mapped: GenericSequence<U, Length = Self::Length>;
+}
+
+unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a S
+where
+    &'a S: GenericSequence<T>,
+    S: GenericSequence<T, Length = <&'a S as GenericSequence<T>>::Length>,
+    <S as GenericSequence<T>>::Length: ArrayLength<U>,
+{
+    type Mapped = <S as MappedGenericSequence<T, U>>::Mapped;
+}
+
+unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a mut S
+where
+    &'a mut S: GenericSequence<T>,
+    S: GenericSequence<T, Length = <&'a mut S as GenericSequence<T>>::Length>,
+    <S as GenericSequence<T>>::Length: ArrayLength<U>,
+{
+    type Mapped = <S as MappedGenericSequence<T, U>>::Mapped;
+}
+
+/// Accessor type for a mapped generic sequence
+pub type MappedSequence<S, T, U> =
+    <<S as MappedGenericSequence<T, U>>::Mapped as GenericSequence<U>>::Sequence;
+
+/// Defines functional programming methods for generic sequences
+pub unsafe trait FunctionalSequence<T>: GenericSequence<T> {
+    /// Maps a `GenericSequence` to another `GenericSequence`.
+    ///
+    /// If the mapping function panics, any already initialized elements in the new sequence
+    /// will be dropped, AND any unused elements in the source sequence will also be dropped.
+    fn map<U, F>(self, f: F) -> MappedSequence<Self, T, U>
+    where
+        Self: MappedGenericSequence<T, U>,
+        Self::Length: ArrayLength<U>,
+        F: FnMut(Self::Item) -> U,
+    {
+        FromIterator::from_iter(self.into_iter().map(f))
+    }
+
+    /// Combines two `GenericSequence` instances and iterates through both of them,
+    /// initializing a new `GenericSequence` with the result of the zipped mapping function.
+    ///
+    /// If the mapping function panics, any already initialized elements in the new sequence
+    /// will be dropped, AND any unused elements in the source sequences will also be dropped.
+    #[inline]
+    fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
+    where
+        Self: MappedGenericSequence<T, U>,
+        Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
+        Self::Length: ArrayLength<B> + ArrayLength<U>,
+        Rhs: GenericSequence<B, Length = Self::Length>,
+        F: FnMut(Self::Item, Rhs::Item) -> U,
+    {
+        rhs.inverted_zip2(self, f)
+    }
+
+    /// Folds (or reduces) a sequence of data into a single value.
+    ///
+    /// If the fold function panics, any unused elements will be dropped.
+    fn fold<U, F>(self, init: U, f: F) -> U
+    where
+        F: FnMut(U, Self::Item) -> U,
+    {
+        self.into_iter().fold(init, f)
+    }
+}
+
+unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a S
+where
+    &'a S: GenericSequence<T>,
+{
+}
+
+unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a mut S
+where
+    &'a mut S: GenericSequence<T>,
+{
+}
diff -Nru cargo-0.66.0/vendor/generic-array/src/hex.rs cargo-0.66.0+ds1/vendor/generic-array/src/hex.rs
--- cargo-0.66.0/vendor/generic-array/src/hex.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/hex.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,105 @@
+//! Generic array are commonly used as a return value for hash digests, so
+//! it's a good idea to allow to hexlify them easily. This module implements
+//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
+//!
+//! Example:
+//!
+//! ```rust
+//! # #[macro_use]
+//! # extern crate generic_array;
+//! # extern crate typenum;
+//! # fn main() {
+//! let array = arr![u8; 10, 20, 30];
+//! assert_eq!(format!("{:x}", array), "0a141e");
+//! # }
+//! ```
+//!
+
+use core::{fmt, str, ops::Add, cmp::min};
+
+use typenum::*;
+
+use crate::{ArrayLength, GenericArray};
+
+static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
+static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
+
+impl<T: ArrayLength<u8>> fmt::LowerHex for GenericArray<u8, T>
+where
+    T: Add<T>,
+    <T as Add<T>>::Output: ArrayLength<u8>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
+        let max_hex = (max_digits >> 1) + (max_digits & 1);
+
+        if T::USIZE < 1024 {
+            // For small arrays use a stack allocated
+            // buffer of 2x number of bytes
+            let mut res = GenericArray::<u8, Sum<T, T>>::default();
+
+            self.iter().take(max_hex).enumerate().for_each(|(i, c)| {
+                res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
+                res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
+            });
+
+            f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
+        } else {
+            // For large array use chunks of up to 1024 bytes (2048 hex chars)
+            let mut buf = [0u8; 2048];
+            let mut digits_left = max_digits;
+
+            for chunk in self[..max_hex].chunks(1024) {
+                chunk.iter().enumerate().for_each(|(i, c)| {
+                    buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
+                    buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
+                });
+
+                let n = min(chunk.len() * 2, digits_left);
+                f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
+                digits_left -= n;
+            }
+        }
+        Ok(())
+    }
+}
+
+impl<T: ArrayLength<u8>> fmt::UpperHex for GenericArray<u8, T>
+where
+    T: Add<T>,
+    <T as Add<T>>::Output: ArrayLength<u8>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
+        let max_hex = (max_digits >> 1) + (max_digits & 1);
+
+        if T::USIZE < 1024 {
+            // For small arrays use a stack allocated
+            // buffer of 2x number of bytes
+            let mut res = GenericArray::<u8, Sum<T, T>>::default();
+
+            self.iter().take(max_hex).enumerate().for_each(|(i, c)| {
+                res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
+                res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
+            });
+
+            f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
+        } else {
+            // For large array use chunks of up to 1024 bytes (2048 hex chars)
+            let mut buf = [0u8; 2048];
+            let mut digits_left = max_digits;
+
+            for chunk in self[..max_hex].chunks(1024) {
+                chunk.iter().enumerate().for_each(|(i, c)| {
+                    buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
+                    buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
+                });
+
+                let n = min(chunk.len() * 2, digits_left);
+                f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
+                digits_left -= n;
+            }
+        }
+        Ok(())
+    }
+}
diff -Nru cargo-0.66.0/vendor/generic-array/src/impl_serde.rs cargo-0.66.0+ds1/vendor/generic-array/src/impl_serde.rs
--- cargo-0.66.0/vendor/generic-array/src/impl_serde.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/impl_serde.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,108 @@
+//! Serde serialization/deserialization implementation
+
+use core::fmt;
+use core::marker::PhantomData;
+use serde::de::{self, SeqAccess, Visitor};
+use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer};
+use {ArrayLength, GenericArray};
+
+impl<T, N> Serialize for GenericArray<T, N>
+where
+    T: Serialize,
+    N: ArrayLength<T>,
+{
+    #[inline]
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut tup = serializer.serialize_tuple(N::USIZE)?;
+        for el in self {
+            tup.serialize_element(el)?;
+        }
+
+        tup.end()
+    }
+}
+
+struct GAVisitor<T, N> {
+    _t: PhantomData<T>,
+    _n: PhantomData<N>,
+}
+
+impl<'de, T, N> Visitor<'de> for GAVisitor<T, N>
+where
+    T: Deserialize<'de> + Default,
+    N: ArrayLength<T>,
+{
+    type Value = GenericArray<T, N>;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("struct GenericArray")
+    }
+
+    fn visit_seq<A>(self, mut seq: A) -> Result<GenericArray<T, N>, A::Error>
+    where
+        A: SeqAccess<'de>,
+    {
+        let mut result = GenericArray::default();
+        for i in 0..N::USIZE {
+            result[i] = seq
+                .next_element()?
+                .ok_or_else(|| de::Error::invalid_length(i, &self))?;
+        }
+        Ok(result)
+    }
+}
+
+impl<'de, T, N> Deserialize<'de> for GenericArray<T, N>
+where
+    T: Deserialize<'de> + Default,
+    N: ArrayLength<T>,
+{
+    fn deserialize<D>(deserializer: D) -> Result<GenericArray<T, N>, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let visitor = GAVisitor {
+            _t: PhantomData,
+            _n: PhantomData,
+        };
+        deserializer.deserialize_tuple(N::USIZE, visitor)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use bincode;
+    use typenum;
+
+    #[test]
+    fn test_serialize() {
+        let array = GenericArray::<u8, typenum::U2>::default();
+        let serialized = bincode::serialize(&array);
+        assert!(serialized.is_ok());
+    }
+
+    #[test]
+    fn test_deserialize() {
+        let mut array = GenericArray::<u8, typenum::U2>::default();
+        array[0] = 1;
+        array[1] = 2;
+        let serialized = bincode::serialize(&array).unwrap();
+        let deserialized = bincode::deserialize::<GenericArray<u8, typenum::U2>>(&serialized);
+        assert!(deserialized.is_ok());
+        let array = deserialized.unwrap();
+        assert_eq!(array[0], 1);
+        assert_eq!(array[1], 2);
+    }
+
+    #[test]
+    fn test_serialized_size() {
+        let array = GenericArray::<u8, typenum::U1>::default();
+        let size = bincode::serialized_size(&array).unwrap();
+        assert_eq!(size, 1);
+    }
+
+}
diff -Nru cargo-0.66.0/vendor/generic-array/src/impls.rs cargo-0.66.0+ds1/vendor/generic-array/src/impls.rs
--- cargo-0.66.0/vendor/generic-array/src/impls.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/impls.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,269 @@
+use core::borrow::{Borrow, BorrowMut};
+use core::cmp::Ordering;
+use core::fmt::{self, Debug};
+use core::hash::{Hash, Hasher};
+
+use super::{ArrayLength, GenericArray};
+
+use crate::functional::*;
+use crate::sequence::*;
+
+impl<T: Default, N> Default for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline(always)]
+    fn default() -> Self {
+        Self::generate(|_| T::default())
+    }
+}
+
+impl<T: Clone, N> Clone for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn clone(&self) -> GenericArray<T, N> {
+        self.map(Clone::clone)
+    }
+}
+
+impl<T: Copy, N> Copy for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    N::ArrayType: Copy,
+{
+}
+
+impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn eq(&self, other: &Self) -> bool {
+        **self == **other
+    }
+}
+impl<T: Eq, N> Eq for GenericArray<T, N> where N: ArrayLength<T> {}
+
+impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
+    }
+}
+
+impl<T: Ord, N> Ord for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
+        Ord::cmp(self.as_slice(), other.as_slice())
+    }
+}
+
+impl<T: Debug, N> Debug for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        self[..].fmt(fmt)
+    }
+}
+
+impl<T, N> Borrow<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline(always)]
+    fn borrow(&self) -> &[T] {
+        &self[..]
+    }
+}
+
+impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline(always)]
+    fn borrow_mut(&mut self) -> &mut [T] {
+        &mut self[..]
+    }
+}
+
+impl<T, N> AsRef<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline(always)]
+    fn as_ref(&self) -> &[T] {
+        &self[..]
+    }
+}
+
+impl<T, N> AsMut<[T]> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline(always)]
+    fn as_mut(&mut self) -> &mut [T] {
+        &mut self[..]
+    }
+}
+
+impl<T: Hash, N> Hash for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: Hasher,
+    {
+        Hash::hash(&self[..], state)
+    }
+}
+
+macro_rules! impl_from {
+    ($($n: expr => $ty: ty),*) => {
+        $(
+            impl<T> From<[T; $n]> for GenericArray<T, $ty> {
+                #[inline(always)]
+                fn from(arr: [T; $n]) -> Self {
+                    unsafe { $crate::transmute(arr) }
+                }
+            }
+
+            #[cfg(relaxed_coherence)]
+            impl<T> From<GenericArray<T, $ty>> for [T; $n] {
+                #[inline(always)]
+                fn from(sel: GenericArray<T, $ty>) -> [T; $n] {
+                    unsafe { $crate::transmute(sel) }
+                }
+            }
+
+            impl<'a, T> From<&'a [T; $n]> for &'a GenericArray<T, $ty> {
+                #[inline]
+                fn from(slice: &[T; $n]) -> &GenericArray<T, $ty> {
+                    unsafe { &*(slice.as_ptr() as *const GenericArray<T, $ty>) }
+                }
+            }
+
+            impl<'a, T> From<&'a mut [T; $n]> for &'a mut GenericArray<T, $ty> {
+                #[inline]
+                fn from(slice: &mut [T; $n]) -> &mut GenericArray<T, $ty> {
+                    unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, $ty>) }
+                }
+            }
+
+            #[cfg(not(relaxed_coherence))]
+            impl<T> Into<[T; $n]> for GenericArray<T, $ty> {
+                #[inline(always)]
+                fn into(self) -> [T; $n] {
+                    unsafe { $crate::transmute(self) }
+                }
+            }
+
+            impl<T> AsRef<[T; $n]> for GenericArray<T, $ty> {
+                #[inline]
+                fn as_ref(&self) -> &[T; $n] {
+                    unsafe { $crate::transmute(self) }
+                }
+            }
+
+            impl<T> AsMut<[T; $n]> for GenericArray<T, $ty> {
+                #[inline]
+                fn as_mut(&mut self) -> &mut [T; $n] {
+                    unsafe { $crate::transmute(self) }
+                }
+            }
+        )*
+    }
+}
+
+impl_from! {
+    1  => ::typenum::U1,
+    2  => ::typenum::U2,
+    3  => ::typenum::U3,
+    4  => ::typenum::U4,
+    5  => ::typenum::U5,
+    6  => ::typenum::U6,
+    7  => ::typenum::U7,
+    8  => ::typenum::U8,
+    9  => ::typenum::U9,
+    10 => ::typenum::U10,
+    11 => ::typenum::U11,
+    12 => ::typenum::U12,
+    13 => ::typenum::U13,
+    14 => ::typenum::U14,
+    15 => ::typenum::U15,
+    16 => ::typenum::U16,
+    17 => ::typenum::U17,
+    18 => ::typenum::U18,
+    19 => ::typenum::U19,
+    20 => ::typenum::U20,
+    21 => ::typenum::U21,
+    22 => ::typenum::U22,
+    23 => ::typenum::U23,
+    24 => ::typenum::U24,
+    25 => ::typenum::U25,
+    26 => ::typenum::U26,
+    27 => ::typenum::U27,
+    28 => ::typenum::U28,
+    29 => ::typenum::U29,
+    30 => ::typenum::U30,
+    31 => ::typenum::U31,
+    32 => ::typenum::U32
+}
+
+#[cfg(feature = "more_lengths")]
+impl_from! {
+    33 => ::typenum::U33,
+    34 => ::typenum::U34,
+    35 => ::typenum::U35,
+    36 => ::typenum::U36,
+    37 => ::typenum::U37,
+    38 => ::typenum::U38,
+    39 => ::typenum::U39,
+    40 => ::typenum::U40,
+    41 => ::typenum::U41,
+    42 => ::typenum::U42,
+    43 => ::typenum::U43,
+    44 => ::typenum::U44,
+    45 => ::typenum::U45,
+    46 => ::typenum::U46,
+    47 => ::typenum::U47,
+    48 => ::typenum::U48,
+    49 => ::typenum::U49,
+    50 => ::typenum::U50,
+    51 => ::typenum::U51,
+    52 => ::typenum::U52,
+    53 => ::typenum::U53,
+    54 => ::typenum::U54,
+    55 => ::typenum::U55,
+    56 => ::typenum::U56,
+    57 => ::typenum::U57,
+    58 => ::typenum::U58,
+    59 => ::typenum::U59,
+    60 => ::typenum::U60,
+    61 => ::typenum::U61,
+    62 => ::typenum::U62,
+    63 => ::typenum::U63,
+    64 => ::typenum::U64,
+
+    70 => ::typenum::U70,
+    80 => ::typenum::U80,
+    90 => ::typenum::U90,
+
+    100 => ::typenum::U100,
+    200 => ::typenum::U200,
+    300 => ::typenum::U300,
+    400 => ::typenum::U400,
+    500 => ::typenum::U500,
+
+    128 => ::typenum::U128,
+    256 => ::typenum::U256,
+    512 => ::typenum::U512,
+
+    1000 => ::typenum::U1000,
+    1024 => ::typenum::U1024
+}
diff -Nru cargo-0.66.0/vendor/generic-array/src/impl_zeroize.rs cargo-0.66.0+ds1/vendor/generic-array/src/impl_zeroize.rs
--- cargo-0.66.0/vendor/generic-array/src/impl_zeroize.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/impl_zeroize.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+use {ArrayLength, GenericArray};
+
+use zeroize::Zeroize;
+
+#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
+impl<T: Zeroize, N: ArrayLength<T>> Zeroize for GenericArray<T, N> {
+    fn zeroize(&mut self) {
+        self.as_mut_slice().iter_mut().zeroize()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_zeroize() {
+        let mut array = GenericArray::<u8, typenum::U2>::default();
+        array[0] = 4;
+        array[1] = 9;
+        array.zeroize();
+        assert_eq!(array[0], 0);
+        assert_eq!(array[1], 0);
+    }
+}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/generic-array/src/iter.rs cargo-0.66.0+ds1/vendor/generic-array/src/iter.rs
--- cargo-0.66.0/vendor/generic-array/src/iter.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/iter.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,251 @@
+//! `GenericArray` iterator implementation.
+
+use super::{ArrayLength, GenericArray};
+use core::iter::FusedIterator;
+use core::mem::ManuallyDrop;
+use core::{cmp, fmt, mem, ptr};
+
+/// An iterator that moves out of a `GenericArray`
+pub struct GenericArrayIter<T, N: ArrayLength<T>> {
+    // Invariants: index <= index_back <= N
+    // Only values in array[index..index_back] are alive at any given time.
+    // Values from array[..index] and array[index_back..] are already moved/dropped.
+    array: ManuallyDrop<GenericArray<T, N>>,
+    index: usize,
+    index_back: usize,
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    fn send<I: Send>(_iter: I) {}
+
+    #[test]
+    fn test_send_iter() {
+        send(GenericArray::from([1, 2, 3, 4]).into_iter());
+    }
+}
+
+impl<T, N> GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    /// Returns the remaining items of this iterator as a slice
+    #[inline]
+    pub fn as_slice(&self) -> &[T] {
+        &self.array.as_slice()[self.index..self.index_back]
+    }
+
+    /// Returns the remaining items of this iterator as a mutable slice
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        &mut self.array.as_mut_slice()[self.index..self.index_back]
+    }
+}
+
+impl<T, N> IntoIterator for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type Item = T;
+    type IntoIter = GenericArrayIter<T, N>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        GenericArrayIter {
+            array: ManuallyDrop::new(self),
+            index: 0,
+            index_back: N::USIZE,
+        }
+    }
+}
+
+// Based on work in rust-lang/rust#49000
+impl<T: fmt::Debug, N> fmt::Debug for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("GenericArrayIter")
+            .field(&self.as_slice())
+            .finish()
+    }
+}
+
+impl<T, N> Drop for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline]
+    fn drop(&mut self) {
+        if mem::needs_drop::<T>() {
+            // Drop values that are still alive.
+            for p in self.as_mut_slice() {
+                unsafe {
+                    ptr::drop_in_place(p);
+                }
+            }
+        }
+    }
+}
+
+// Based on work in rust-lang/rust#49000
+impl<T: Clone, N> Clone for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn clone(&self) -> Self {
+        // This places all cloned elements at the start of the new array iterator,
+        // not at their original indices.
+
+        let mut array = unsafe { ptr::read(&self.array) };
+        let mut index_back = 0;
+
+        for (dst, src) in array.as_mut_slice().into_iter().zip(self.as_slice()) {
+            unsafe { ptr::write(dst, src.clone()) };
+            index_back += 1;
+        }
+
+        GenericArrayIter {
+            array,
+            index: 0,
+            index_back,
+        }
+    }
+}
+
+impl<T, N> Iterator for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type Item = T;
+
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        if self.index < self.index_back {
+            let p = unsafe { Some(ptr::read(self.array.get_unchecked(self.index))) };
+
+            self.index += 1;
+
+            p
+        } else {
+            None
+        }
+    }
+
+    fn fold<B, F>(mut self, init: B, mut f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        let ret = unsafe {
+            let GenericArrayIter {
+                ref array,
+                ref mut index,
+                index_back,
+            } = self;
+
+            let remaining = &array[*index..index_back];
+
+            remaining.iter().fold(init, |acc, src| {
+                let value = ptr::read(src);
+
+                *index += 1;
+
+                f(acc, value)
+            })
+        };
+
+        // ensure the drop happens here after iteration
+        drop(self);
+
+        ret
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.len();
+        (len, Some(len))
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.len()
+    }
+
+    fn nth(&mut self, n: usize) -> Option<T> {
+        // First consume values prior to the nth.
+        let ndrop = cmp::min(n, self.len());
+
+        for p in &mut self.array[self.index..self.index + ndrop] {
+            self.index += 1;
+
+            unsafe {
+                ptr::drop_in_place(p);
+            }
+        }
+
+        self.next()
+    }
+
+    #[inline]
+    fn last(mut self) -> Option<T> {
+        // Note, everything else will correctly drop first as `self` leaves scope.
+        self.next_back()
+    }
+}
+
+impl<T, N> DoubleEndedIterator for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn next_back(&mut self) -> Option<T> {
+        if self.index < self.index_back {
+            self.index_back -= 1;
+
+            unsafe { Some(ptr::read(self.array.get_unchecked(self.index_back))) }
+        } else {
+            None
+        }
+    }
+
+    fn rfold<B, F>(mut self, init: B, mut f: F) -> B
+    where
+        F: FnMut(B, Self::Item) -> B,
+    {
+        let ret = unsafe {
+            let GenericArrayIter {
+                ref array,
+                index,
+                ref mut index_back,
+            } = self;
+
+            let remaining = &array[index..*index_back];
+
+            remaining.iter().rfold(init, |acc, src| {
+                let value = ptr::read(src);
+
+                *index_back -= 1;
+
+                f(acc, value)
+            })
+        };
+
+        // ensure the drop happens here after iteration
+        drop(self);
+
+        ret
+    }
+}
+
+impl<T, N> ExactSizeIterator for GenericArrayIter<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn len(&self) -> usize {
+        self.index_back - self.index
+    }
+}
+
+impl<T, N> FusedIterator for GenericArrayIter<T, N> where N: ArrayLength<T> {}
+
+// TODO: Implement `TrustedLen` when stabilized
diff -Nru cargo-0.66.0/vendor/generic-array/src/lib.rs cargo-0.66.0+ds1/vendor/generic-array/src/lib.rs
--- cargo-0.66.0/vendor/generic-array/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,679 @@
+//! This crate implements a structure that can be used as a generic array type.
+//! Core Rust array types `[T; N]` can't be used generically with
+//! respect to `N`, so for example this:
+//!
+//! ```rust{compile_fail}
+//! struct Foo<T, N> {
+//!     data: [T; N]
+//! }
+//! ```
+//!
+//! won't work.
+//!
+//! **generic-array** exports a `GenericArray<T,N>` type, which lets
+//! the above be implemented as:
+//!
+//! ```rust
+//! use generic_array::{ArrayLength, GenericArray};
+//!
+//! struct Foo<T, N: ArrayLength<T>> {
+//!     data: GenericArray<T,N>
+//! }
+//! ```
+//!
+//! The `ArrayLength<T>` trait is implemented by default for
+//! [unsigned integer types](../typenum/uint/index.html) from
+//! [typenum](../typenum/index.html):
+//!
+//! ```rust
+//! # use generic_array::{ArrayLength, GenericArray};
+//! use generic_array::typenum::U5;
+//!
+//! struct Foo<N: ArrayLength<i32>> {
+//!     data: GenericArray<i32, N>
+//! }
+//!
+//! # fn main() {
+//! let foo = Foo::<U5>{data: GenericArray::default()};
+//! # }
+//! ```
+//!
+//! For example, `GenericArray<T, U5>` would work almost like `[T; 5]`:
+//!
+//! ```rust
+//! # use generic_array::{ArrayLength, GenericArray};
+//! use generic_array::typenum::U5;
+//!
+//! struct Foo<T, N: ArrayLength<T>> {
+//!     data: GenericArray<T, N>
+//! }
+//!
+//! # fn main() {
+//! let foo = Foo::<i32, U5>{data: GenericArray::default()};
+//! # }
+//! ```
+//!
+//! For ease of use, an `arr!` macro is provided - example below:
+//!
+//! ```
+//! # #[macro_use]
+//! # extern crate generic_array;
+//! # extern crate typenum;
+//! # fn main() {
+//! let array = arr![u32; 1, 2, 3];
+//! assert_eq!(array[2], 3);
+//! # }
+//! ```
+
+#![deny(missing_docs)]
+#![deny(meta_variable_misuse)]
+#![no_std]
+
+#[cfg(feature = "serde")]
+extern crate serde;
+
+#[cfg(feature = "zeroize")]
+extern crate zeroize;
+
+#[cfg(test)]
+extern crate bincode;
+
+pub extern crate typenum;
+
+mod hex;
+mod impls;
+
+#[cfg(feature = "serde")]
+mod impl_serde;
+
+#[cfg(feature = "zeroize")]
+mod impl_zeroize;
+
+use core::iter::FromIterator;
+use core::marker::PhantomData;
+use core::mem::{MaybeUninit, ManuallyDrop};
+use core::ops::{Deref, DerefMut};
+use core::{mem, ptr, slice};
+use typenum::bit::{B0, B1};
+use typenum::uint::{UInt, UTerm, Unsigned};
+
+#[cfg_attr(test, macro_use)]
+pub mod arr;
+pub mod functional;
+pub mod iter;
+pub mod sequence;
+
+use self::functional::*;
+pub use self::iter::GenericArrayIter;
+use self::sequence::*;
+
+/// Trait making `GenericArray` work, marking types to be used as length of an array
+pub unsafe trait ArrayLength<T>: Unsigned {
+    /// Associated type representing the array type for the number
+    type ArrayType;
+}
+
+unsafe impl<T> ArrayLength<T> for UTerm {
+    #[doc(hidden)]
+    type ArrayType = [T; 0];
+}
+
+/// Internal type used to generate a struct of appropriate size
+#[allow(dead_code)]
+#[repr(C)]
+#[doc(hidden)]
+pub struct GenericArrayImplEven<T, U> {
+    parent1: U,
+    parent2: U,
+    _marker: PhantomData<T>,
+}
+
+impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
+    fn clone(&self) -> GenericArrayImplEven<T, U> {
+        GenericArrayImplEven {
+            parent1: self.parent1.clone(),
+            parent2: self.parent2.clone(),
+            _marker: PhantomData,
+        }
+    }
+}
+
+impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
+
+/// Internal type used to generate a struct of appropriate size
+#[allow(dead_code)]
+#[repr(C)]
+#[doc(hidden)]
+pub struct GenericArrayImplOdd<T, U> {
+    parent1: U,
+    parent2: U,
+    data: T,
+}
+
+impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
+    fn clone(&self) -> GenericArrayImplOdd<T, U> {
+        GenericArrayImplOdd {
+            parent1: self.parent1.clone(),
+            parent2: self.parent2.clone(),
+            data: self.data.clone(),
+        }
+    }
+}
+
+impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
+
+unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
+    #[doc(hidden)]
+    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
+}
+
+unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
+    #[doc(hidden)]
+    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
+}
+
+/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
+#[allow(dead_code)]
+#[repr(transparent)]
+pub struct GenericArray<T, U: ArrayLength<T>> {
+    data: U::ArrayType,
+}
+
+unsafe impl<T: Send, N: ArrayLength<T>> Send for GenericArray<T, N> {}
+unsafe impl<T: Sync, N: ArrayLength<T>> Sync for GenericArray<T, N> {}
+
+impl<T, N> Deref for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type Target = [T];
+
+    #[inline(always)]
+    fn deref(&self) -> &[T] {
+        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
+    }
+}
+
+impl<T, N> DerefMut for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    #[inline(always)]
+    fn deref_mut(&mut self) -> &mut [T] {
+        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
+    }
+}
+
+/// Creates an array one element at a time using a mutable iterator
+/// you can write to with `ptr::write`.
+///
+/// Increment the position while iterating to mark off created elements,
+/// which will be dropped if `into_inner` is not called.
+#[doc(hidden)]
+pub struct ArrayBuilder<T, N: ArrayLength<T>> {
+    array: MaybeUninit<GenericArray<T, N>>,
+    position: usize,
+}
+
+impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
+    #[doc(hidden)]
+    #[inline]
+    pub unsafe fn new() -> ArrayBuilder<T, N> {
+        ArrayBuilder {
+            array: MaybeUninit::uninit(),
+            position: 0,
+        }
+    }
+
+    /// Creates a mutable iterator for writing to the array using `ptr::write`.
+    ///
+    /// Increment the position value given as a mutable reference as you iterate
+    /// to mark how many elements have been created.
+    #[doc(hidden)]
+    #[inline]
+    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
+        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
+    }
+
+    /// When done writing (assuming all elements have been written to),
+    /// get the inner array.
+    #[doc(hidden)]
+    #[inline]
+    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
+        let array = ptr::read(&self.array);
+
+        mem::forget(self);
+
+        array.assume_init()
+    }
+}
+
+impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
+    fn drop(&mut self) {
+        if mem::needs_drop::<T>() {
+            unsafe {
+                for value in &mut (&mut *self.array.as_mut_ptr())[..self.position] {
+                    ptr::drop_in_place(value);
+                }
+            }
+        }
+    }
+}
+
+/// Consumes an array.
+///
+/// Increment the position while iterating and any leftover elements
+/// will be dropped if position does not go to N
+#[doc(hidden)]
+pub struct ArrayConsumer<T, N: ArrayLength<T>> {
+    array: ManuallyDrop<GenericArray<T, N>>,
+    position: usize,
+}
+
+impl<T, N: ArrayLength<T>> ArrayConsumer<T, N> {
+    #[doc(hidden)]
+    #[inline]
+    pub unsafe fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
+        ArrayConsumer {
+            array: ManuallyDrop::new(array),
+            position: 0,
+        }
+    }
+
+    /// Creates an iterator and mutable reference to the internal position
+    /// to keep track of consumed elements.
+    ///
+    /// Increment the position as you iterate to mark off consumed elements
+    #[doc(hidden)]
+    #[inline]
+    pub unsafe fn iter_position(&mut self) -> (slice::Iter<T>, &mut usize) {
+        (self.array.iter(), &mut self.position)
+    }
+}
+
+impl<T, N: ArrayLength<T>> Drop for ArrayConsumer<T, N> {
+    fn drop(&mut self) {
+        if mem::needs_drop::<T>() {
+            for value in &mut self.array[self.position..N::USIZE] {
+                unsafe {
+                    ptr::drop_in_place(value);
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T: 'a, N> IntoIterator for &'a GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type IntoIter = slice::Iter<'a, T>;
+    type Item = &'a T;
+
+    fn into_iter(self: &'a GenericArray<T, N>) -> Self::IntoIter {
+        self.as_slice().iter()
+    }
+}
+
+impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    type IntoIter = slice::IterMut<'a, T>;
+    type Item = &'a mut T;
+
+    fn into_iter(self: &'a mut GenericArray<T, N>) -> Self::IntoIter {
+        self.as_mut_slice().iter_mut()
+    }
+}
+
+impl<T, N> FromIterator<T> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    fn from_iter<I>(iter: I) -> GenericArray<T, N>
+    where
+        I: IntoIterator<Item = T>,
+    {
+        unsafe {
+            let mut destination = ArrayBuilder::new();
+
+            {
+                let (destination_iter, position) = destination.iter_position();
+
+                iter.into_iter()
+                    .zip(destination_iter)
+                    .for_each(|(src, dst)| {
+                        ptr::write(dst, src);
+
+                        *position += 1;
+                    });
+            }
+
+            if destination.position < N::USIZE {
+                from_iter_length_fail(destination.position, N::USIZE);
+            }
+
+            destination.into_inner()
+        }
+    }
+}
+
+#[inline(never)]
+#[cold]
+fn from_iter_length_fail(length: usize, expected: usize) -> ! {
+    panic!(
+        "GenericArray::from_iter received {} elements but expected {}",
+        length, expected
+    );
+}
+
+unsafe impl<T, N> GenericSequence<T> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    Self: IntoIterator<Item = T>,
+{
+    type Length = N;
+    type Sequence = Self;
+
+    fn generate<F>(mut f: F) -> GenericArray<T, N>
+    where
+        F: FnMut(usize) -> T,
+    {
+        unsafe {
+            let mut destination = ArrayBuilder::new();
+
+            {
+                let (destination_iter, position) = destination.iter_position();
+
+                destination_iter.enumerate().for_each(|(i, dst)| {
+                    ptr::write(dst, f(i));
+
+                    *position += 1;
+                });
+            }
+
+            destination.into_inner()
+        }
+    }
+
+    #[doc(hidden)]
+    fn inverted_zip<B, U, F>(
+        self,
+        lhs: GenericArray<B, Self::Length>,
+        mut f: F,
+    ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
+    where
+        GenericArray<B, Self::Length>:
+            GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
+        Self: MappedGenericSequence<T, U>,
+        Self::Length: ArrayLength<B> + ArrayLength<U>,
+        F: FnMut(B, Self::Item) -> U,
+    {
+        unsafe {
+            let mut left = ArrayConsumer::new(lhs);
+            let mut right = ArrayConsumer::new(self);
+
+            let (left_array_iter, left_position) = left.iter_position();
+            let (right_array_iter, right_position) = right.iter_position();
+
+            FromIterator::from_iter(left_array_iter.zip(right_array_iter).map(|(l, r)| {
+                let left_value = ptr::read(l);
+                let right_value = ptr::read(r);
+
+                *left_position += 1;
+                *right_position += 1;
+
+                f(left_value, right_value)
+            }))
+        }
+    }
+
+    #[doc(hidden)]
+    fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
+    where
+        Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
+        Self: MappedGenericSequence<T, U>,
+        Self::Length: ArrayLength<B> + ArrayLength<U>,
+        F: FnMut(Lhs::Item, Self::Item) -> U,
+    {
+        unsafe {
+            let mut right = ArrayConsumer::new(self);
+
+            let (right_array_iter, right_position) = right.iter_position();
+
+            FromIterator::from_iter(
+                lhs.into_iter()
+                    .zip(right_array_iter)
+                    .map(|(left_value, r)| {
+                        let right_value = ptr::read(r);
+
+                        *right_position += 1;
+
+                        f(left_value, right_value)
+                    }),
+            )
+        }
+    }
+}
+
+unsafe impl<T, U, N> MappedGenericSequence<T, U> for GenericArray<T, N>
+where
+    N: ArrayLength<T> + ArrayLength<U>,
+    GenericArray<U, N>: GenericSequence<U, Length = N>,
+{
+    type Mapped = GenericArray<U, N>;
+}
+
+unsafe impl<T, N> FunctionalSequence<T> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    Self: GenericSequence<T, Item = T, Length = N>,
+{
+    fn map<U, F>(self, mut f: F) -> MappedSequence<Self, T, U>
+    where
+        Self::Length: ArrayLength<U>,
+        Self: MappedGenericSequence<T, U>,
+        F: FnMut(T) -> U,
+    {
+        unsafe {
+            let mut source = ArrayConsumer::new(self);
+
+            let (array_iter, position) = source.iter_position();
+
+            FromIterator::from_iter(array_iter.map(|src| {
+                let value = ptr::read(src);
+
+                *position += 1;
+
+                f(value)
+            }))
+        }
+    }
+
+    #[inline]
+    fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
+    where
+        Self: MappedGenericSequence<T, U>,
+        Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
+        Self::Length: ArrayLength<B> + ArrayLength<U>,
+        Rhs: GenericSequence<B, Length = Self::Length>,
+        F: FnMut(T, Rhs::Item) -> U,
+    {
+        rhs.inverted_zip(self, f)
+    }
+
+    fn fold<U, F>(self, init: U, mut f: F) -> U
+    where
+        F: FnMut(U, T) -> U,
+    {
+        unsafe {
+            let mut source = ArrayConsumer::new(self);
+
+            let (array_iter, position) = source.iter_position();
+
+            array_iter.fold(init, |acc, src| {
+                let value = ptr::read(src);
+
+                *position += 1;
+
+                f(acc, value)
+            })
+        }
+    }
+}
+
+impl<T, N> GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    /// Extracts a slice containing the entire array.
+    #[inline]
+    pub fn as_slice(&self) -> &[T] {
+        self.deref()
+    }
+
+    /// Extracts a mutable slice containing the entire array.
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        self.deref_mut()
+    }
+
+    /// Converts slice to a generic array reference with inferred length;
+    ///
+    /// Length of the slice must be equal to the length of the array.
+    #[inline]
+    pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
+        slice.into()
+    }
+
+    /// Converts mutable slice to a mutable generic array reference
+    ///
+    /// Length of the slice must be equal to the length of the array.
+    #[inline]
+    pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
+        slice.into()
+    }
+}
+
+impl<'a, T, N: ArrayLength<T>> From<&'a [T]> for &'a GenericArray<T, N> {
+    /// Converts slice to a generic array reference with inferred length;
+    ///
+    /// Length of the slice must be equal to the length of the array.
+    #[inline]
+    fn from(slice: &[T]) -> &GenericArray<T, N> {
+        assert_eq!(slice.len(), N::USIZE);
+
+        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
+    }
+}
+
+impl<'a, T, N: ArrayLength<T>> From<&'a mut [T]> for &'a mut GenericArray<T, N> {
+    /// Converts mutable slice to a mutable generic array reference
+    ///
+    /// Length of the slice must be equal to the length of the array.
+    #[inline]
+    fn from(slice: &mut [T]) -> &mut GenericArray<T, N> {
+        assert_eq!(slice.len(), N::USIZE);
+
+        unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
+    }
+}
+
+impl<T: Clone, N> GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    /// Construct a `GenericArray` from a slice by cloning its content
+    ///
+    /// Length of the slice must be equal to the length of the array
+    #[inline]
+    pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
+        Self::from_exact_iter(list.iter().cloned())
+            .expect("Slice must be the same length as the array")
+    }
+}
+
+impl<T, N> GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+{
+    /// Creates a new `GenericArray` instance from an iterator with a specific size.
+    ///
+    /// Returns `None` if the size is not equal to the number of elements in the `GenericArray`.
+    pub fn from_exact_iter<I>(iter: I) -> Option<Self>
+    where
+        I: IntoIterator<Item = T>,
+    {
+        let mut iter = iter.into_iter();
+
+        unsafe {
+            let mut destination = ArrayBuilder::new();
+
+            {
+                let (destination_iter, position) = destination.iter_position();
+
+                destination_iter.zip(&mut iter).for_each(|(dst, src)| {
+                    ptr::write(dst, src);
+
+                    *position += 1;
+                });
+
+                // The iterator produced fewer than `N` elements.
+                if *position != N::USIZE {
+                    return None;
+                }
+
+                // The iterator produced more than `N` elements.
+                if iter.next().is_some() {
+                    return None;
+                }
+            }
+
+            Some(destination.into_inner())
+        }
+    }
+}
+
+/// A reimplementation of the `transmute` function, avoiding problems
+/// when the compiler can't prove equal sizes.
+#[inline]
+#[doc(hidden)]
+pub unsafe fn transmute<A, B>(a: A) -> B {
+    let a = ManuallyDrop::new(a);
+    ::core::ptr::read(&*a as *const A as *const B)
+}
+
+#[cfg(test)]
+mod test {
+    // Compile with:
+    // cargo rustc --lib --profile test --release --
+    //      -C target-cpu=native -C opt-level=3 --emit asm
+    // and view the assembly to make sure test_assembly generates
+    // SIMD instructions instead of a naive loop.
+
+    #[inline(never)]
+    pub fn black_box<T>(val: T) -> T {
+        use core::{mem, ptr};
+
+        let ret = unsafe { ptr::read_volatile(&val) };
+        mem::forget(val);
+        ret
+    }
+
+    #[test]
+    fn test_assembly() {
+        use crate::functional::*;
+
+        let a = black_box(arr![i32; 1, 3, 5, 7]);
+        let b = black_box(arr![i32; 2, 4, 6, 8]);
+
+        let c = (&a).zip(b, |l, r| l + r);
+
+        let d = a.fold(0, |a, x| a + x);
+
+        assert_eq!(c, arr![i32; 3, 7, 11, 15]);
+
+        assert_eq!(d, 16);
+    }
+}
diff -Nru cargo-0.66.0/vendor/generic-array/src/sequence.rs cargo-0.66.0+ds1/vendor/generic-array/src/sequence.rs
--- cargo-0.66.0/vendor/generic-array/src/sequence.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/generic-array/src/sequence.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,380 @@
+//! Useful traits for manipulating sequences of data stored in `GenericArray`s
+
+use super::*;
+use core::ops::{Add, Sub};
+use core::mem::MaybeUninit;
+use core::ptr;
+use typenum::operator_aliases::*;
+
+/// Defines some sequence with an associated length and iteration capabilities.
+///
+/// This is useful for passing N-length generic arrays as generics.
+pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
+    /// `GenericArray` associated length
+    type Length: ArrayLength<T>;
+
+    /// Concrete sequence type used in conjuction with reference implementations of `GenericSequence`
+    type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
+
+    /// Initializes a new sequence instance using the given function.
+    ///
+    /// If the generator function panics while initializing the sequence,
+    /// any already initialized elements will be dropped.
+    fn generate<F>(f: F) -> Self::Sequence
+    where
+        F: FnMut(usize) -> T;
+
+    #[doc(hidden)]
+    fn inverted_zip<B, U, F>(
+        self,
+        lhs: GenericArray<B, Self::Length>,
+        mut f: F,
+    ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
+    where
+        GenericArray<B, Self::Length>: GenericSequence<B, Length = Self::Length>
+            + MappedGenericSequence<B, U>,
+        Self: MappedGenericSequence<T, U>,
+        Self::Length: ArrayLength<B> + ArrayLength<U>,
+        F: FnMut(B, Self::Item) -> U,
+    {
+        unsafe {
+            let mut left = ArrayConsumer::new(lhs);
+
+            let (left_array_iter, left_position) = left.iter_position();
+
+            FromIterator::from_iter(left_array_iter.zip(self.into_iter()).map(
+                |(l, right_value)| {
+                        let left_value = ptr::read(l);
+
+                        *left_position += 1;
+
+                        f(left_value, right_value)
+                },
+            ))
+        }
+    }
+
+    #[doc(hidden)]
+    fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
+    where
+        Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
+        Self: MappedGenericSequence<T, U>,
+        Self::Length: ArrayLength<B> + ArrayLength<U>,
+        F: FnMut(Lhs::Item, Self::Item) -> U,
+    {
+        FromIterator::from_iter(lhs.into_iter().zip(self.into_iter()).map(|(l, r)| f(l, r)))
+    }
+}
+
+/// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item`
+///
+/// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`,
+/// this can be useful for keeping things organized.
+pub type SequenceItem<T> = <T as IntoIterator>::Item;
+
+unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S
+where
+    &'a S: IntoIterator,
+{
+    type Length = S::Length;
+    type Sequence = S::Sequence;
+
+    #[inline]
+    fn generate<F>(f: F) -> Self::Sequence
+    where
+        F: FnMut(usize) -> T,
+    {
+        S::generate(f)
+    }
+}
+
+unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S
+where
+    &'a mut S: IntoIterator,
+{
+    type Length = S::Length;
+    type Sequence = S::Sequence;
+
+    #[inline]
+    fn generate<F>(f: F) -> Self::Sequence
+    where
+        F: FnMut(usize) -> T,
+    {
+        S::generate(f)
+    }
+}
+
+/// Defines any `GenericSequence` which can be lengthened or extended by appending
+/// or prepending an element to it.
+///
+/// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back`
+pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
+    /// `GenericSequence` that has one more element than `Self`
+    type Longer: Shorten<T, Shorter = Self>;
+
+    /// Returns a new array with the given element appended to the end of it.
+    ///
+    /// Example:
+    ///
+    /// ```rust
+    /// # use generic_array::{arr, sequence::Lengthen};
+    /// # fn main() {
+    /// let a = arr![i32; 1, 2, 3];
+    ///
+    /// let b = a.append(4);
+    ///
+    /// assert_eq!(b, arr![i32; 1, 2, 3, 4]);
+    /// # }
+    /// ```
+    fn append(self, last: T) -> Self::Longer;
+
+    /// Returns a new array with the given element prepended to the front of it.
+    ///
+    /// Example:
+    ///
+    /// ```rust
+    /// # use generic_array::{arr, sequence::Lengthen};
+    /// # fn main() {
+    /// let a = arr![i32; 1, 2, 3];
+    ///
+    /// let b = a.prepend(4);
+    ///
+    /// assert_eq!(b, arr![i32; 4, 1, 2, 3]);
+    /// # }
+    /// ```
+    fn prepend(self, first: T) -> Self::Longer;
+}
+
+/// Defines a `GenericSequence` which can be shortened by removing the first or last element from it.
+///
+/// Additionally, any shortened sequence can be lengthened by
+/// appending or prepending an element to it.
+pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
+    /// `GenericSequence` that has one less element than `Self`
+    type Shorter: Lengthen<T, Longer = Self>;
+
+    /// Returns a new array without the last element, and the last element.
+    ///
+    /// Example:
+    ///
+    /// ```rust
+    /// # use generic_array::{arr, sequence::Shorten};
+    /// # fn main() {
+    /// let a = arr![i32; 1, 2, 3, 4];
+    ///
+    /// let (init, last) = a.pop_back();
+    ///
+    /// assert_eq!(init, arr![i32; 1, 2, 3]);
+    /// assert_eq!(last, 4);
+    /// # }
+    /// ```
+    fn pop_back(self) -> (Self::Shorter, T);
+
+    /// Returns a new array without the first element, and the first element.
+    /// Example:
+    ///
+    /// ```rust
+    /// # use generic_array::{arr, sequence::Shorten};
+    /// # fn main() {
+    /// let a = arr![i32; 1, 2, 3, 4];
+    ///
+    /// let (head, tail) = a.pop_front();
+    ///
+    /// assert_eq!(head, 1);
+    /// assert_eq!(tail, arr![i32; 2, 3, 4]);
+    /// # }
+    /// ```
+    fn pop_front(self) -> (T, Self::Shorter);
+}
+
+unsafe impl<T, N: ArrayLength<T>> Lengthen<T> for GenericArray<T, N>
+where
+    N: Add<B1>,
+    Add1<N>: ArrayLength<T>,
+    Add1<N>: Sub<B1, Output = N>,
+    Sub1<Add1<N>>: ArrayLength<T>,
+{
+    type Longer = GenericArray<T, Add1<N>>;
+
+    fn append(self, last: T) -> Self::Longer {
+        let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
+
+        // Note this is *mut Self, so add(1) increments by the whole array
+        let out_ptr = longer.as_mut_ptr() as *mut Self;
+
+        unsafe {
+            // write self first
+            ptr::write(out_ptr, self);
+            // increment past self, then write the last
+            ptr::write(out_ptr.add(1) as *mut T, last);
+
+            longer.assume_init()
+        }
+    }
+
+    fn prepend(self, first: T) -> Self::Longer {
+        let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
+
+        // Note this is *mut T, so add(1) increments by a single T
+        let out_ptr = longer.as_mut_ptr() as *mut T;
+
+        unsafe {
+            // write the first at the start
+            ptr::write(out_ptr, first);
+            // increment past the first, then write self
+            ptr::write(out_ptr.add(1) as *mut Self, self);
+
+            longer.assume_init()
+        }
+    }
+}
+
+unsafe impl<T, N: ArrayLength<T>> Shorten<T> for GenericArray<T, N>
+where
+    N: Sub<B1>,
+    Sub1<N>: ArrayLength<T>,
+    Sub1<N>: Add<B1, Output = N>,
+    Add1<Sub1<N>>: ArrayLength<T>,
+{
+    type Shorter = GenericArray<T, Sub1<N>>;
+
+    fn pop_back(self) -> (Self::Shorter, T) {
+        let whole = ManuallyDrop::new(self);
+
+        unsafe {
+            let init = ptr::read(whole.as_ptr() as _);
+            let last = ptr::read(whole.as_ptr().add(Sub1::<N>::USIZE) as _);
+
+            (init, last)
+        }
+    }
+
+    fn pop_front(self) -> (T, Self::Shorter) {
+        // ensure this doesn't get dropped
+        let whole = ManuallyDrop::new(self);
+
+        unsafe {
+            let head = ptr::read(whole.as_ptr() as _);
+            let tail = ptr::read(whole.as_ptr().offset(1) as _);
+
+            (head, tail)
+        }
+    }
+}
+
+/// Defines a `GenericSequence` that can be split into two parts at a given pivot index.
+pub unsafe trait Split<T, K>: GenericSequence<T>
+where
+    K: ArrayLength<T>,
+{
+    /// First part of the resulting split array
+    type First: GenericSequence<T>;
+    /// Second part of the resulting split array
+    type Second: GenericSequence<T>;
+
+    /// Splits an array at the given index, returning the separate parts of the array.
+    fn split(self) -> (Self::First, Self::Second);
+}
+
+unsafe impl<T, N, K> Split<T, K> for GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    K: ArrayLength<T>,
+    N: Sub<K>,
+    Diff<N, K>: ArrayLength<T>,
+{
+    type First = GenericArray<T, K>;
+    type Second = GenericArray<T, Diff<N, K>>;
+
+    fn split(self) -> (Self::First, Self::Second) {
+        unsafe {
+            // ensure this doesn't get dropped
+            let whole = ManuallyDrop::new(self);
+
+            let head = ptr::read(whole.as_ptr() as *const _);
+            let tail = ptr::read(whole.as_ptr().add(K::USIZE) as *const _);
+
+            (head, tail)
+        }
+    }
+}
+
+unsafe impl<'a, T, N, K> Split<T, K> for &'a GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    K: ArrayLength<T> + 'static,
+    N: Sub<K>,
+    Diff<N, K>: ArrayLength<T>,
+{
+    type First = &'a GenericArray<T, K>;
+    type Second = &'a GenericArray<T, Diff<N, K>>;
+
+    fn split(self) -> (Self::First, Self::Second) {
+        unsafe {
+            let ptr_to_first: *const T = self.as_ptr();
+            let head = &*(ptr_to_first as *const _);
+            let tail = &*(ptr_to_first.add(K::USIZE) as *const _);
+            (head, tail)
+        }
+    }
+}
+
+unsafe impl<'a, T, N, K> Split<T, K> for &'a mut GenericArray<T, N>
+where
+    N: ArrayLength<T>,
+    K: ArrayLength<T> + 'static,
+    N: Sub<K>,
+    Diff<N, K>: ArrayLength<T>,
+{
+    type First = &'a mut GenericArray<T, K>;
+    type Second = &'a mut GenericArray<T, Diff<N, K>>;
+
+    fn split(self) -> (Self::First, Self::Second) {
+        unsafe {
+            let ptr_to_first: *mut T = self.as_mut_ptr();
+            let head = &mut *(ptr_to_first as *mut _);
+            let tail = &mut *(ptr_to_first.add(K::USIZE) as *mut _);
+            (head, tail)
+        }
+    }
+}
+
+/// Defines `GenericSequence`s which can be joined together, forming a larger array.
+pub unsafe trait Concat<T, M>: GenericSequence<T>
+where
+    M: ArrayLength<T>,
+{
+    /// Sequence to be concatenated with `self`
+    type Rest: GenericSequence<T, Length = M>;
+
+    /// Resulting sequence formed by the concatenation.
+    type Output: GenericSequence<T>;
+
+    /// Concatenate, or join, two sequences.
+    fn concat(self, rest: Self::Rest) -> Self::Output;
+}
+
+unsafe impl<T, N, M> Concat<T, M> for GenericArray<T, N>
+where
+    N: ArrayLength<T> + Add<M>,
+    M: ArrayLength<T>,
+    Sum<N, M>: ArrayLength<T>,
+{
+    type Rest = GenericArray<T, M>;
+    type Output = GenericArray<T, Sum<N, M>>;
+
+    fn concat(self, rest: Self::Rest) -> Self::Output {
+        let mut output: MaybeUninit<Self::Output> = MaybeUninit::uninit();
+
+        let out_ptr = output.as_mut_ptr() as *mut Self;
+
+        unsafe {
+            // write all of self to the pointer
+            ptr::write(out_ptr, self);
+            // increment past self, then write the rest
+            ptr::write(out_ptr.add(1) as *mut _, rest);
+
+            output.assume_init()
+        }
+    }
+}
diff -Nru cargo-0.66.0/vendor/git2/.cargo-checksum.json cargo-0.66.0+ds1/vendor/git2/.cargo-checksum.json
--- cargo-0.66.0/vendor/git2/.cargo-checksum.json	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -1 +1 @@
-{"files":{},"package":"2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"}
\ No newline at end of file
+{"files":{},"package":"be36bc9e0546df253c0cc41fd0af34f5e92845ad8509462ec76672fac6997f5b"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/git2/Cargo.lock cargo-0.66.0+ds1/vendor/git2/Cargo.lock
--- cargo-0.66.0/vendor/git2/Cargo.lock	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/Cargo.lock	2023-01-11 18:41:02.000000000 +0100
@@ -94,7 +94,7 @@
 
 [[package]]
 name = "git2"
-version = "0.15.0"
+version = "0.16.0"
 dependencies = [
  "bitflags",
  "libc",
@@ -170,9 +170,9 @@
 
 [[package]]
 name = "libgit2-sys"
-version = "0.14.0+1.5.0"
+version = "0.14.1+1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b"
+checksum = "4a07fb2692bc3593bda59de45a502bb3071659f2c515e28c71e728306b038e17"
 dependencies = [
  "cc",
  "libc",
diff -Nru cargo-0.66.0/vendor/git2/Cargo.toml cargo-0.66.0+ds1/vendor/git2/Cargo.toml
--- cargo-0.66.0/vendor/git2/Cargo.toml	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -12,7 +12,7 @@
 [package]
 edition = "2018"
 name = "git2"
-version = "0.15.0"
+version = "0.16.0"
 authors = [
     "Josh Triplett <josh at joshtriplett.org>",
     "Alex Crichton <alex at alexcrichton.com>",
@@ -36,7 +36,7 @@
 version = "0.2"
 
 [dependencies.libgit2-sys]
-version = "0.14.0"
+version = "0.14.1"
 
 [dependencies.log]
 version = "0.4.8"
diff -Nru cargo-0.66.0/vendor/git2/README.md cargo-0.66.0+ds1/vendor/git2/README.md
--- cargo-0.66.0/vendor/git2/README.md	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -6,7 +6,7 @@
 
 ```toml
 [dependencies]
-git2 = "0.14"
+git2 = "0.16"
 ```
 
 ## Rust version requirements
diff -Nru cargo-0.66.0/vendor/git2/src/cert.rs cargo-0.66.0+ds1/vendor/git2/src/cert.rs
--- cargo-0.66.0/vendor/git2/src/cert.rs	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/src/cert.rs	2023-01-11 18:41:02.000000000 +0100
@@ -27,6 +27,54 @@
     _marker: marker::PhantomData<&'a raw::git_cert>,
 }
 
+/// The SSH host key type.
+#[derive(Copy, Clone, Debug)]
+#[non_exhaustive]
+pub enum SshHostKeyType {
+    /// Unknown key type
+    Unknown = raw::GIT_CERT_SSH_RAW_TYPE_UNKNOWN as isize,
+    /// RSA key type
+    Rsa = raw::GIT_CERT_SSH_RAW_TYPE_RSA as isize,
+    /// DSS key type
+    Dss = raw::GIT_CERT_SSH_RAW_TYPE_DSS as isize,
+    /// ECDSA 256 key type
+    Ecdsa256 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 as isize,
+    /// ECDSA 384 key type
+    Ecdsa384 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 as isize,
+    /// ECDSA 521 key type
+    Ecdsa521 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 as isize,
+    /// ED25519 key type
+    Ed255219 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 as isize,
+}
+
+impl SshHostKeyType {
+    /// The name of the key type as encoded in the known_hosts file.
+    pub fn name(&self) -> &'static str {
+        match self {
+            SshHostKeyType::Unknown => "unknown",
+            SshHostKeyType::Rsa => "ssh-rsa",
+            SshHostKeyType::Dss => "ssh-dss",
+            SshHostKeyType::Ecdsa256 => "ecdsa-sha2-nistp256",
+            SshHostKeyType::Ecdsa384 => "ecdsa-sha2-nistp384",
+            SshHostKeyType::Ecdsa521 => "ecdsa-sha2-nistp521",
+            SshHostKeyType::Ed255219 => "ssh-ed25519",
+        }
+    }
+
+    /// A short name of the key type, the colloquial form used as a human-readable description.
+    pub fn short_name(&self) -> &'static str {
+        match self {
+            SshHostKeyType::Unknown => "Unknown",
+            SshHostKeyType::Rsa => "RSA",
+            SshHostKeyType::Dss => "DSA",
+            SshHostKeyType::Ecdsa256 => "ECDSA",
+            SshHostKeyType::Ecdsa384 => "ECDSA",
+            SshHostKeyType::Ecdsa521 => "ECDSA",
+            SshHostKeyType::Ed255219 => "ED25519",
+        }
+    }
+}
+
 impl<'a> Cert<'a> {
     /// Attempt to view this certificate as an SSH hostkey.
     ///
@@ -87,6 +135,39 @@
             }
         }
     }
+
+    /// Returns the raw host key.
+    pub fn hostkey(&self) -> Option<&[u8]> {
+        unsafe {
+            if (*self.raw).kind & raw::GIT_CERT_SSH_RAW == 0 {
+                return None;
+            }
+            Some(slice::from_raw_parts(
+                (*self.raw).hostkey as *const u8,
+                (*self.raw).hostkey_len as usize,
+            ))
+        }
+    }
+
+    /// Returns the type of the host key.
+    pub fn hostkey_type(&self) -> Option<SshHostKeyType> {
+        unsafe {
+            if (*self.raw).kind & raw::GIT_CERT_SSH_RAW == 0 {
+                return None;
+            }
+            let t = match (*self.raw).raw_type {
+                raw::GIT_CERT_SSH_RAW_TYPE_UNKNOWN => SshHostKeyType::Unknown,
+                raw::GIT_CERT_SSH_RAW_TYPE_RSA => SshHostKeyType::Rsa,
+                raw::GIT_CERT_SSH_RAW_TYPE_DSS => SshHostKeyType::Dss,
+                raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 => SshHostKeyType::Ecdsa256,
+                raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 => SshHostKeyType::Ecdsa384,
+                raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 => SshHostKeyType::Ecdsa521,
+                raw::GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 => SshHostKeyType::Ed255219,
+                t => panic!("unexpected host key type {:?}", t),
+            };
+            Some(t)
+        }
+    }
 }
 
 impl<'a> CertX509<'a> {
diff -Nru cargo-0.66.0/vendor/git2/src/lib.rs cargo-0.66.0+ds1/vendor/git2/src/lib.rs
--- cargo-0.66.0/vendor/git2/src/lib.rs	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -65,7 +65,7 @@
 //! source `Repository`, to ensure that they do not outlive the repository
 //! itself.
 
-#![doc(html_root_url = "https://docs.rs/git2/0.15")]
+#![doc(html_root_url = "https://docs.rs/git2/0.16")]
 #![allow(trivial_numeric_casts, trivial_casts)]
 #![deny(missing_docs)]
 #![warn(rust_2018_idioms)]
@@ -123,7 +123,7 @@
 pub use crate::remote::{
     FetchOptions, PushOptions, Refspecs, Remote, RemoteConnection, RemoteHead, RemoteRedirect,
 };
-pub use crate::remote_callbacks::{Credentials, RemoteCallbacks};
+pub use crate::remote_callbacks::{CertificateCheckStatus, Credentials, RemoteCallbacks};
 pub use crate::remote_callbacks::{TransportMessage, UpdateTips};
 pub use crate::repo::{Repository, RepositoryInitOptions};
 pub use crate::revert::RevertOptions;
diff -Nru cargo-0.66.0/vendor/git2/src/remote_callbacks.rs cargo-0.66.0+ds1/vendor/git2/src/remote_callbacks.rs
--- cargo-0.66.0/vendor/git2/src/remote_callbacks.rs	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2/src/remote_callbacks.rs	2023-01-11 18:41:02.000000000 +0100
@@ -51,7 +51,18 @@
 ///
 /// The second argument is the hostname for the connection is passed as the last
 /// argument.
-pub type CertificateCheck<'a> = dyn FnMut(&Cert<'_>, &str) -> bool + 'a;
+pub type CertificateCheck<'a> =
+    dyn FnMut(&Cert<'_>, &str) -> Result<CertificateCheckStatus, Error> + 'a;
+
+/// The return value for the [`CertificateCheck`] callback.
+pub enum CertificateCheckStatus {
+    /// Indicates that the certificate should be accepted.
+    CertificateOk,
+    /// Indicates that the certificate callback is neither accepting nor
+    /// rejecting the certificate. The result of the certificate checks
+    /// built-in to libgit2 will be used instead.
+    CertificatePassthrough,
+}
 
 /// Callback for each updated reference on push.
 ///
@@ -162,7 +173,7 @@
     /// connection to proceed.
     pub fn certificate_check<F>(&mut self, cb: F) -> &mut RemoteCallbacks<'a>
     where
-        F: FnMut(&Cert<'_>, &str) -> bool + 'a,
+        F: FnMut(&Cert<'_>, &str) -> Result<CertificateCheckStatus, Error> + 'a,
     {
         self.certificate_check = Some(Box::new(cb) as Box<CertificateCheck<'a>>);
         self
@@ -371,16 +382,26 @@
         let payload = &mut *(data as *mut RemoteCallbacks<'_>);
         let callback = match payload.certificate_check {
             Some(ref mut c) => c,
-            None => return true,
+            None => return Ok(CertificateCheckStatus::CertificatePassthrough),
         };
         let cert = Binding::from_raw(cert);
         let hostname = str::from_utf8(CStr::from_ptr(hostname).to_bytes()).unwrap();
         callback(&cert, hostname)
     });
-    if ok == Some(true) {
-        0
-    } else {
-        -1
+    match ok {
+        Some(Ok(CertificateCheckStatus::CertificateOk)) => 0,
+        Some(Ok(CertificateCheckStatus::CertificatePassthrough)) => raw::GIT_PASSTHROUGH as c_int,
+        Some(Err(e)) => {
+            let s = CString::new(e.message()).unwrap();
+            unsafe {
+                raw::git_error_set_str(e.class() as c_int, s.as_ptr());
+            }
+            e.raw_code() as c_int
+        }
+        None => {
+            // Panic. The *should* get resumed by some future call to check().
+            -1
+        }
     }
 }
 
diff -Nru cargo-0.66.0/vendor/git2-curl/.cargo-checksum.json cargo-0.66.0+ds1/vendor/git2-curl/.cargo-checksum.json
--- cargo-0.66.0/vendor/git2-curl/.cargo-checksum.json	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2-curl/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -1 +1 @@
-{"files":{},"package":"ed817a00721e2f8037ba722e60358d4956dae9cca10315fc982f967907d3b0cd"}
\ No newline at end of file
+{"files":{},"package":"7577f4e6341ba7c90d883511130a45b956c274ba5f4d205d9f9da990f654cd33"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/git2-curl/Cargo.toml cargo-0.66.0+ds1/vendor/git2-curl/Cargo.toml
--- cargo-0.66.0/vendor/git2-curl/Cargo.toml	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2-curl/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -12,7 +12,7 @@
 [package]
 edition = "2018"
 name = "git2-curl"
-version = "0.16.0"
+version = "0.17.0"
 authors = [
     "Josh Triplett <josh at joshtriplett.org>",
     "Alex Crichton <alex at alexcrichton.com>",
@@ -34,7 +34,7 @@
 version = "0.4.33"
 
 [dependencies.git2]
-version = "0.15"
+version = "0.16"
 default-features = false
 
 [dependencies.log]
diff -Nru cargo-0.66.0/vendor/git2-curl/src/lib.rs cargo-0.66.0+ds1/vendor/git2-curl/src/lib.rs
--- cargo-0.66.0/vendor/git2-curl/src/lib.rs	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/git2-curl/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -15,7 +15,7 @@
 //! > **NOTE**: At this time this crate likely does not support a `git push`
 //! >           operation, only clones.
 
-#![doc(html_root_url = "https://docs.rs/git2-curl/0.16")]
+#![doc(html_root_url = "https://docs.rs/git2-curl/0.17")]
 #![deny(missing_docs)]
 #![warn(rust_2018_idioms)]
 #![cfg_attr(test, deny(warnings))]
diff -Nru cargo-0.66.0/vendor/hmac/.cargo-checksum.json cargo-0.66.0+ds1/vendor/hmac/.cargo-checksum.json
--- cargo-0.66.0/vendor/hmac/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/hmac/Cargo.toml cargo-0.66.0+ds1/vendor/hmac/Cargo.toml
--- cargo-0.66.0/vendor/hmac/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,51 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "hmac"
+version = "0.12.1"
+authors = ["RustCrypto Developers"]
+description = "Generic implementation of Hash-based Message Authentication Code (HMAC)"
+documentation = "https://docs.rs/hmac"
+readme = "README.md"
+keywords = ["crypto", "mac", "hmac", "digest"]
+categories = ["cryptography", "no-std"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/RustCrypto/MACs"
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+[dependencies.digest]
+version = "0.10.3"
+features = ["mac"]
+[dev-dependencies.digest]
+version = "0.10"
+features = ["dev"]
+
+[dev-dependencies.hex-literal]
+version = "0.3"
+
+[dev-dependencies.md-5]
+version = "0.10"
+default-features = false
+
+[dev-dependencies.sha1]
+version = "0.10"
+default-features = false
+
+[dev-dependencies.sha2]
+version = "0.10"
+default-features = false
+
+[features]
+reset = []
+std = ["digest/std"]
diff -Nru cargo-0.66.0/vendor/hmac/CHANGELOG.md cargo-0.66.0+ds1/vendor/hmac/CHANGELOG.md
--- cargo-0.66.0/vendor/hmac/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,97 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.12.1 (2022-02-17)
+### Fixed
+- Minimal versions build ([#108])
+
+[#108]: https://github.com/RustCrypto/MACs/pull/108
+
+## 0.12.0 (2021-12-07)
+### Changed
+- Bump `digest` crate dependency to v0.10 and remove `crypto-mac` ([#97])
+- Use a more efficient state representation by using block-level hash API ([#97])
+
+### Added
+- `SimpleHmac` as a less constrained alternative to `Hmac` ([#97])
+
+[#97]: https://github.com/RustCrypto/MACs/pull/97
+
+## 0.11.0 (2021-04-29)
+### Changed
+- Bump `crypto-mac` crate dependency to v0.11 ([#73])
+
+[#73]: https://github.com/RustCrypto/MACs/pull/73
+
+## 0.10.1 (2020-10-16)
+### Added
+- Zulip badge ([#64])
+
+[#64]: https://github.com/RustCrypto/MACs/pull/64
+
+## 0.10.0 (2020-10-16)
+### Changed
+- Bump `crypto-mac` dependency to v0.10 ([#62])
+
+[#62]: https://github.com/RustCrypto/MACs/pull/62
+
+## 0.9.0 (2020-08-12)
+### Changed
+- Bump `crypto-mac` dependency to v0.9 ([#57])
+
+### Added
+- Implement `io::Write` ([#55])
+
+[#55]: https://github.com/RustCrypto/MACs/pull/55
+[#57]: https://github.com/RustCrypto/MACs/pull/57
+
+## 0.8.1 (2020-06-24)
+### Fixed
+- Replace outdated `code` with `into_bytes` in documentation ([#50])
+
+[#50]: https://github.com/RustCrypto/MACs/pull/50
+
+## 0.8.0 (2020-06-09)
+### Changed
+- Upgrade to `digest` v0.9 crate release; MSRV 1.41 ([#45])
+- Upgrade `crypto-mac` to v0.8 ([#33])
+- Rename `*result*` to `finalize` ([#38])
+- Upgrade to Rust 2018 edition  ([#33])
+
+[#45]: https://github.com/RustCrypto/MACs/pull/45
+[#38]: https://github.com/RustCrypto/MACs/pull/38
+[#33]: https://github.com/RustCrypto/MACs/pull/33
+
+## 0.7.1 (2019-07-11)
+
+## 0.7.0 (2018-10-03)
+
+## 0.6.3 (2018-08-15)
+
+## 0.6.2 (2018-04-15)
+
+## 0.6.1 (2018-04-05)
+
+## 0.6.0 (2018-03-30)
+
+## 0.5.0 (2017-11-15)
+
+## 0.4.2 (2017-07-24)
+
+## 0.4.1 (2017-07-24)
+
+## 0.4.0 (2017-07-24)
+
+## 0.3.1 (2017-06-12)
+
+## 0.1.2 (2017-07-24)
+
+## 0.1.1 (2017-05-14)
+
+## 0.1.0 (2017-05-14)
+
+## 0.0.1 (2016-10-21)
diff -Nru cargo-0.66.0/vendor/hmac/debian/patches/disable-streebog.diff cargo-0.66.0+ds1/vendor/hmac/debian/patches/disable-streebog.diff
--- cargo-0.66.0/vendor/hmac/debian/patches/disable-streebog.diff	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/debian/patches/disable-streebog.diff	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,50 @@
+Index: hmac/tests/mod.rs
+===================================================================
+--- hmac.orig/tests/mod.rs
++++ hmac/tests/mod.rs
+@@ -5,7 +5,7 @@ use digest::new_resettable_mac_test as t
+ use hmac::{Hmac, SimpleHmac};
+ use sha1::Sha1;
+ use sha2::{Sha224, Sha256, Sha384, Sha512};
+-use streebog::{Streebog256, Streebog512};
++//use streebog::{Streebog256, Streebog512};
+ 
+ // Test vectors from RFC 2104, plus wiki test
+ test!(hmac_md5_rfc2104, "md5", Hmac<md5::Md5>);
+@@ -23,9 +23,9 @@ test!(hmac_sha512_rfc4231_simple, "sha51
+ 
+ // Test vectors from R 50.1.113-2016:
+ // https://tc26.ru/standard/rs/? 50.1.113-2016.pdf
+-test!(hmac_streebog256, "streebog256", Hmac<Streebog256>);
+-test!(hmac_streebog512, "streebog512", Hmac<Streebog512>);
+-test!(
++//test!(hmac_streebog256, "streebog256", Hmac<Streebog256>);
++//test!(hmac_streebog512, "streebog512", Hmac<Streebog512>);
++/*test!(
+     hmac_streebog256_simple,
+     "streebog256",
+     SimpleHmac<Streebog256>
+@@ -34,7 +34,7 @@ test!(
+     hmac_streebog512_simple,
+     "streebog512",
+     SimpleHmac<Streebog512>
+-);
++);*/
+ 
+ // Tests from Project Wycheproof:
+ // https://github.com/google/wycheproof
+Index: hmac/Cargo.toml
+===================================================================
+--- hmac.orig/Cargo.toml
++++ hmac/Cargo.toml
+@@ -46,10 +46,6 @@ default-features = false
+ version = "0.10"
+ default-features = false
+ 
+-[dev-dependencies.streebog]
+-version = "0.10"
+-default-features = false
+-
+ [features]
+ reset = []
+ std = ["digest/std"]
diff -Nru cargo-0.66.0/vendor/hmac/debian/patches/relax-dep.diff cargo-0.66.0+ds1/vendor/hmac/debian/patches/relax-dep.diff
--- cargo-0.66.0/vendor/hmac/debian/patches/relax-dep.diff	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/debian/patches/relax-dep.diff	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,20 @@
+Index: hmac/Cargo.toml
+===================================================================
+--- hmac.orig/Cargo.toml
++++ hmac/Cargo.toml
+@@ -32,13 +32,13 @@ version = "0.10"
+ features = ["dev"]
+ 
+ [dev-dependencies.hex-literal]
+-version = "0.2.2"
++version = "0.3"
+ 
+ [dev-dependencies.md-5]
+ version = "0.10"
+ default-features = false
+ 
+-[dev-dependencies.sha-1]
++[dev-dependencies.sha1]
+ version = "0.10"
+ default-features = false
+ 
diff -Nru cargo-0.66.0/vendor/hmac/debian/patches/series cargo-0.66.0+ds1/vendor/hmac/debian/patches/series
--- cargo-0.66.0/vendor/hmac/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/debian/patches/series	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,2 @@
+relax-dep.diff
+disable-streebog.diff
diff -Nru cargo-0.66.0/vendor/hmac/LICENSE-APACHE cargo-0.66.0+ds1/vendor/hmac/LICENSE-APACHE
--- cargo-0.66.0/vendor/hmac/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/hmac/LICENSE-MIT cargo-0.66.0+ds1/vendor/hmac/LICENSE-MIT
--- cargo-0.66.0/vendor/hmac/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,25 @@
+Copyright (c) 2017 Artyom Pavlov
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/hmac/README.md cargo-0.66.0+ds1/vendor/hmac/README.md
--- cargo-0.66.0/vendor/hmac/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,53 @@
+# RustCrypto: HMAC
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+
+Pure Rust implementation of the [Hash-based Message Authentication Code (HMAC)][1].
+
+[Documentation][docs-link]
+
+## Minimum Supported Rust Version
+
+Rust **1.41** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be
+done with a minor version bump.
+
+## SemVer Policy
+
+- All on-by-default features of this library are covered by SemVer
+- MSRV is considered exempt from SemVer as noted above
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/hmac.svg
+[crate-link]: https://crates.io/crates/hmac
+[docs-image]: https://docs.rs/hmac/badge.svg
+[docs-link]: https://docs.rs/hmac/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs
+
+[//]: # (general links)
+
+[1]: https://en.wikipedia.org/wiki/HMAC
diff -Nru cargo-0.66.0/vendor/hmac/src/lib.rs cargo-0.66.0+ds1/vendor/hmac/src/lib.rs
--- cargo-0.66.0/vendor/hmac/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,131 @@
+//! Generic implementation of Hash-based Message Authentication Code (HMAC).
+//!
+//! To use it you will need a cryptographic hash function implementation which
+//! implements the [`digest`] crate traits. You can find compatible crates
+//! (e.g. [`sha2`]) in the [`RustCrypto/hashes`] repository.
+//!
+//! This crate provides two HMAC implementation [`Hmac`] and [`SimpleHmac`].
+//! The first one is a buffered wrapper around block-level [`HmacCore`].
+//! Internally it uses efficient state representation, but works only with
+//! hash functions which expose block-level API and consume blocks eagerly
+//! (e.g. it will not work with the BLAKE2 family of  hash functions).
+//! On the other hand, [`SimpleHmac`] is a bit less efficient memory-wise,
+//! but works with all hash functions which implement the [`Digest`] trait.
+//!
+//! # Examples
+//! Let us demonstrate how to use HMAC using the SHA-256 hash function.
+//!
+//! In the following examples [`Hmac`] is interchangeable with [`SimpleHmac`].
+//!
+//! To get authentication code:
+//!
+//! ```rust
+//! use sha2::Sha256;
+//! use hmac::{Hmac, Mac};
+//! use hex_literal::hex;
+//!
+//! // Create alias for HMAC-SHA256
+//! type HmacSha256 = Hmac<Sha256>;
+//!
+//! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key")
+//!     .expect("HMAC can take key of any size");
+//! mac.update(b"input message");
+//!
+//! // `result` has type `CtOutput` which is a thin wrapper around array of
+//! // bytes for providing constant time equality check
+//! let result = mac.finalize();
+//! // To get underlying array use `into_bytes`, but be careful, since
+//! // incorrect use of the code value may permit timing attacks which defeats
+//! // the security provided by the `CtOutput`
+//! let code_bytes = result.into_bytes();
+//! let expected = hex!("
+//!     97d2a569059bbcd8ead4444ff99071f4
+//!     c01d005bcefe0d3567e1be628e5fdcd9
+//! ");
+//! assert_eq!(code_bytes[..], expected[..]);
+//! ```
+//!
+//! To verify the message:
+//!
+//! ```rust
+//! # use sha2::Sha256;
+//! # use hmac::{Hmac, Mac};
+//! # use hex_literal::hex;
+//! # type HmacSha256 = Hmac<Sha256>;
+//! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key")
+//!     .expect("HMAC can take key of any size");
+//!
+//! mac.update(b"input message");
+//!
+//! let code_bytes = hex!("
+//!     97d2a569059bbcd8ead4444ff99071f4
+//!     c01d005bcefe0d3567e1be628e5fdcd9
+//! ");
+//! // `verify_slice` will return `Ok(())` if code is correct, `Err(MacError)` otherwise
+//! mac.verify_slice(&code_bytes[..]).unwrap();
+//! ```
+//!
+//! # Block and input sizes
+//! Usually it is assumed that block size is larger than output size. Due to the
+//! generic nature of the implementation, this edge case must be handled as well
+//! to remove potential panic. This is done by truncating hash output to the hash
+//! block size if needed.
+//!
+//! [`digest`]: https://docs.rs/digest
+//! [`sha2`]: https://docs.rs/sha2
+//! [`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes
+
+#![no_std]
+#![doc(
+    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
+    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
+    html_root_url = "https://docs.rs/hmac/0.12.1"
+)]
+#![forbid(unsafe_code)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![warn(missing_docs, rust_2018_idioms)]
+
+#[cfg(feature = "std")]
+extern crate std;
+
+pub use digest;
+pub use digest::Mac;
+
+use digest::{
+    core_api::{Block, BlockSizeUser},
+    Digest,
+};
+
+mod optim;
+mod simple;
+
+pub use optim::{Hmac, HmacCore};
+pub use simple::SimpleHmac;
+
+const IPAD: u8 = 0x36;
+const OPAD: u8 = 0x5C;
+
+fn get_der_key<D: Digest + BlockSizeUser>(key: &[u8]) -> Block<D> {
+    let mut der_key = Block::<D>::default();
+    // The key that HMAC processes must be the same as the block size of the
+    // underlying hash function. If the provided key is smaller than that,
+    // we just pad it with zeros. If its larger, we hash it and then pad it
+    // with zeros.
+    if key.len() <= der_key.len() {
+        der_key[..key.len()].copy_from_slice(key);
+    } else {
+        let hash = D::digest(key);
+        // All commonly used hash functions have block size bigger
+        // than output hash size, but to be extra rigorous we
+        // handle the potential uncommon cases as well.
+        // The condition is calcualted at compile time, so this
+        // branch gets removed from the final binary.
+        if hash.len() <= der_key.len() {
+            der_key[..hash.len()].copy_from_slice(&hash);
+        } else {
+            let n = der_key.len();
+            der_key.copy_from_slice(&hash[..n]);
+        }
+    }
+    der_key
+}
diff -Nru cargo-0.66.0/vendor/hmac/src/optim.rs cargo-0.66.0+ds1/vendor/hmac/src/optim.rs
--- cargo-0.66.0/vendor/hmac/src/optim.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/src/optim.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,280 @@
+use super::{get_der_key, IPAD, OPAD};
+use core::{fmt, slice};
+#[cfg(feature = "reset")]
+use digest::Reset;
+use digest::{
+    block_buffer::Eager,
+    core_api::{
+        AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper,
+        FixedOutputCore, OutputSizeUser, UpdateCore,
+    },
+    crypto_common::{Key, KeySizeUser},
+    generic_array::typenum::{IsLess, Le, NonZero, U256},
+    HashMarker, InvalidLength, KeyInit, MacMarker, Output,
+};
+
+/// Generic HMAC instance.
+pub type Hmac<D> = CoreWrapper<HmacCore<D>>;
+
+/// Generic core HMAC instance, which operates over blocks.
+pub struct HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    digest: D::Core,
+    opad_digest: D::Core,
+    #[cfg(feature = "reset")]
+    ipad_digest: D::Core,
+}
+
+impl<D> Clone for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    fn clone(&self) -> Self {
+        Self {
+            digest: self.digest.clone(),
+            opad_digest: self.opad_digest.clone(),
+            #[cfg(feature = "reset")]
+            ipad_digest: self.ipad_digest.clone(),
+        }
+    }
+}
+
+impl<D> MacMarker for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+}
+
+impl<D> BufferKindUser for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    type BufferKind = Eager;
+}
+
+impl<D> KeySizeUser for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    type KeySize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize;
+}
+
+impl<D> BlockSizeUser for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    type BlockSize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize;
+}
+
+impl<D> OutputSizeUser for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    type OutputSize = <<D as CoreProxy>::Core as OutputSizeUser>::OutputSize;
+}
+
+impl<D> KeyInit for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    #[inline(always)]
+    fn new(key: &Key<Self>) -> Self {
+        Self::new_from_slice(key.as_slice()).unwrap()
+    }
+
+    #[inline(always)]
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+        let mut buf = get_der_key::<CoreWrapper<D::Core>>(key);
+        for b in buf.iter_mut() {
+            *b ^= IPAD;
+        }
+        let mut digest = D::Core::default();
+        digest.update_blocks(slice::from_ref(&buf));
+
+        for b in buf.iter_mut() {
+            *b ^= IPAD ^ OPAD;
+        }
+
+        let mut opad_digest = D::Core::default();
+        opad_digest.update_blocks(slice::from_ref(&buf));
+
+        Ok(Self {
+            #[cfg(feature = "reset")]
+            ipad_digest: digest.clone(),
+            opad_digest,
+            digest,
+        })
+    }
+}
+
+impl<D> UpdateCore for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    #[inline(always)]
+    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
+        self.digest.update_blocks(blocks);
+    }
+}
+
+impl<D> FixedOutputCore for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    #[inline(always)]
+    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
+        let mut hash = Output::<D::Core>::default();
+        self.digest.finalize_fixed_core(buffer, &mut hash);
+        // finalize_fixed_core should reset the buffer as well, but
+        // to be extra safe we reset it explicitly again.
+        buffer.reset();
+        #[cfg(not(feature = "reset"))]
+        let h = &mut self.opad_digest;
+        #[cfg(feature = "reset")]
+        let mut h = self.opad_digest.clone();
+        buffer.digest_blocks(&hash, |b| h.update_blocks(b));
+        h.finalize_fixed_core(buffer, out);
+    }
+}
+
+#[cfg(feature = "reset")]
+#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
+impl<D> Reset for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    #[inline(always)]
+    fn reset(&mut self) {
+        self.digest = self.ipad_digest.clone();
+    }
+}
+
+impl<D> AlgorithmName for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + AlgorithmName
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("Hmac<")?;
+        <D::Core as AlgorithmName>::write_alg_name(f)?;
+        f.write_str(">")
+    }
+}
+
+impl<D> fmt::Debug for HmacCore<D>
+where
+    D: CoreProxy,
+    D::Core: HashMarker
+        + AlgorithmName
+        + UpdateCore
+        + FixedOutputCore
+        + BufferKindUser<BufferKind = Eager>
+        + Default
+        + Clone,
+    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
+    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("HmacCore<")?;
+        <D::Core as AlgorithmName>::write_alg_name(f)?;
+        f.write_str("> { ... }")
+    }
+}
diff -Nru cargo-0.66.0/vendor/hmac/src/simple.rs cargo-0.66.0+ds1/vendor/hmac/src/simple.rs
--- cargo-0.66.0/vendor/hmac/src/simple.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/src/simple.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,106 @@
+use super::{get_der_key, IPAD, OPAD};
+use core::fmt;
+use digest::{
+    crypto_common::{Block, BlockSizeUser, InvalidLength, Key, KeySizeUser},
+    Digest, FixedOutput, KeyInit, MacMarker, Output, OutputSizeUser, Update,
+};
+#[cfg(feature = "reset")]
+use digest::{FixedOutputReset, Reset};
+
+/// Simplified HMAC instance able to operate over hash functions
+/// which do not expose block-level API and hash functions which
+/// process blocks lazily (e.g. BLAKE2).
+#[derive(Clone)]
+pub struct SimpleHmac<D: Digest + BlockSizeUser> {
+    digest: D,
+    opad_key: Block<D>,
+    #[cfg(feature = "reset")]
+    ipad_key: Block<D>,
+}
+
+impl<D: Digest + BlockSizeUser> KeySizeUser for SimpleHmac<D> {
+    type KeySize = D::BlockSize;
+}
+
+impl<D: Digest + BlockSizeUser> MacMarker for SimpleHmac<D> {}
+
+impl<D: Digest + BlockSizeUser> KeyInit for SimpleHmac<D> {
+    fn new(key: &Key<Self>) -> Self {
+        Self::new_from_slice(key.as_slice()).unwrap()
+    }
+
+    #[inline]
+    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
+        let der_key = get_der_key::<D>(key);
+        let mut ipad_key = der_key.clone();
+        for b in ipad_key.iter_mut() {
+            *b ^= IPAD;
+        }
+        let mut digest = D::new();
+        digest.update(&ipad_key);
+
+        let mut opad_key = der_key;
+        for b in opad_key.iter_mut() {
+            *b ^= OPAD;
+        }
+
+        Ok(Self {
+            digest,
+            opad_key,
+            #[cfg(feature = "reset")]
+            ipad_key,
+        })
+    }
+}
+
+impl<D: Digest + BlockSizeUser> Update for SimpleHmac<D> {
+    #[inline(always)]
+    fn update(&mut self, data: &[u8]) {
+        self.digest.update(data);
+    }
+}
+
+impl<D: Digest + BlockSizeUser> OutputSizeUser for SimpleHmac<D> {
+    type OutputSize = D::OutputSize;
+}
+
+impl<D: Digest + BlockSizeUser> FixedOutput for SimpleHmac<D> {
+    fn finalize_into(self, out: &mut Output<Self>) {
+        let mut h = D::new();
+        h.update(&self.opad_key);
+        h.update(&self.digest.finalize());
+        h.finalize_into(out);
+    }
+}
+
+impl<D: Digest + BlockSizeUser + fmt::Debug> fmt::Debug for SimpleHmac<D> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("SimpleHmac")
+            .field("digest", &self.digest)
+            // TODO: replace with `finish_non_exhaustive` on MSRV
+            // bump to 1.53
+            .field("..", &"..")
+            .finish()
+    }
+}
+
+#[cfg(feature = "reset")]
+#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
+impl<D: Digest + BlockSizeUser + Reset> Reset for SimpleHmac<D> {
+    fn reset(&mut self) {
+        Reset::reset(&mut self.digest);
+        self.digest.update(&self.ipad_key);
+    }
+}
+
+#[cfg(feature = "reset")]
+#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
+impl<D: Digest + BlockSizeUser + FixedOutputReset> FixedOutputReset for SimpleHmac<D> {
+    fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
+        let mut h = D::new();
+        Update::update(&mut h, &self.opad_key);
+        Update::update(&mut h, &self.digest.finalize_reset());
+        Update::update(&mut self.digest, &self.ipad_key);
+        Digest::finalize_into(h, out);
+    }
+}
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/md5.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/md5.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/sha224.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/sha224.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/sha256.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/sha256.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/sha384.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/sha384.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/sha512.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/sha512.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/streebog256.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/streebog256.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/streebog512.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/streebog512.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/wycheproof-sha1.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/wycheproof-sha1.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/wycheproof-sha256.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/wycheproof-sha256.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/wycheproof-sha384.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/wycheproof-sha384.blb differ
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/hmac/tests/data/wycheproof-sha512.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/hmac/tests/data/wycheproof-sha512.blb differ
diff -Nru cargo-0.66.0/vendor/hmac/tests/mod.rs cargo-0.66.0+ds1/vendor/hmac/tests/mod.rs
--- cargo-0.66.0/vendor/hmac/tests/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/hmac/tests/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,88 @@
+#[cfg(not(feature = "reset"))]
+use digest::new_mac_test as test;
+#[cfg(feature = "reset")]
+use digest::new_resettable_mac_test as test;
+use hmac::{Hmac, SimpleHmac};
+use sha1::Sha1;
+use sha2::{Sha224, Sha256, Sha384, Sha512};
+//use streebog::{Streebog256, Streebog512};
+
+// Test vectors from RFC 2104, plus wiki test
+test!(hmac_md5_rfc2104, "md5", Hmac<md5::Md5>);
+test!(hmac_md5_rfc2104_simple, "md5", SimpleHmac<md5::Md5>);
+
+// Test vectors from RFC 4231
+test!(hmac_sha224_rfc4231, "sha224", Hmac<Sha224>);
+test!(hmac_sha256_rfc4231, "sha256", Hmac<Sha256>);
+test!(hmac_sha384_rfc4231, "sha384", Hmac<Sha384>);
+test!(hmac_sha512_rfc4231, "sha512", Hmac<Sha512>);
+test!(hmac_sha224_rfc4231_simple, "sha224", SimpleHmac<Sha224>);
+test!(hmac_sha256_rfc4231_simple, "sha256", SimpleHmac<Sha256>);
+test!(hmac_sha384_rfc4231_simple, "sha384", SimpleHmac<Sha384>);
+test!(hmac_sha512_rfc4231_simple, "sha512", SimpleHmac<Sha512>);
+
+// Test vectors from R 50.1.113-2016:
+// https://tc26.ru/standard/rs/? 50.1.113-2016.pdf
+//test!(hmac_streebog256, "streebog256", Hmac<Streebog256>);
+//test!(hmac_streebog512, "streebog512", Hmac<Streebog512>);
+/*test!(
+    hmac_streebog256_simple,
+    "streebog256",
+    SimpleHmac<Streebog256>
+);
+test!(
+    hmac_streebog512_simple,
+    "streebog512",
+    SimpleHmac<Streebog512>
+);*/
+
+// Tests from Project Wycheproof:
+// https://github.com/google/wycheproof
+test!(
+    hmac_sha1_wycheproof,
+    "wycheproof-sha1",
+    Hmac<Sha1>,
+    trunc_left,
+);
+test!(
+    hmac_sha256_wycheproof,
+    "wycheproof-sha256",
+    Hmac<Sha256>,
+    trunc_left,
+);
+test!(
+    hmac_sha384_wycheproof,
+    "wycheproof-sha384",
+    Hmac<Sha384>,
+    trunc_left,
+);
+test!(
+    hmac_sha512_wycheproof,
+    "wycheproof-sha512",
+    Hmac<Sha512>,
+    trunc_left,
+);
+test!(
+    hmac_sha1_wycheproof_simple,
+    "wycheproof-sha1",
+    SimpleHmac<Sha1>,
+    trunc_left,
+);
+test!(
+    hmac_sha256_wycheproof_simple,
+    "wycheproof-sha256",
+    SimpleHmac<Sha256>,
+    trunc_left,
+);
+test!(
+    hmac_sha384_wycheproof_simple,
+    "wycheproof-sha384",
+    SimpleHmac<Sha384>,
+    trunc_left,
+);
+test!(
+    hmac_sha512_wycheproof_simple,
+    "wycheproof-sha512",
+    SimpleHmac<Sha512>,
+    trunc_left,
+);
diff -Nru cargo-0.66.0/vendor/libgit2-sys/.cargo-checksum.json cargo-0.66.0+ds1/vendor/libgit2-sys/.cargo-checksum.json
--- cargo-0.66.0/vendor/libgit2-sys/.cargo-checksum.json	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/libgit2-sys/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -1 +1 @@
-{"files":{},"package":"47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b"}
\ No newline at end of file
+{"files":{},"package":"4a07fb2692bc3593bda59de45a502bb3071659f2c515e28c71e728306b038e17"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/libgit2-sys/Cargo.toml cargo-0.66.0+ds1/vendor/libgit2-sys/Cargo.toml
--- cargo-0.66.0/vendor/libgit2-sys/Cargo.toml	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/libgit2-sys/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -12,7 +12,7 @@
 [package]
 edition = "2018"
 name = "libgit2-sys"
-version = "0.14.0+1.5.0"
+version = "0.14.1+1.5.0"
 authors = [
     "Josh Triplett <josh at joshtriplett.org>",
     "Alex Crichton <alex at alexcrichton.com>",
diff -Nru cargo-0.66.0/vendor/libgit2-sys/lib.rs cargo-0.66.0+ds1/vendor/libgit2-sys/lib.rs
--- cargo-0.66.0/vendor/libgit2-sys/lib.rs	2023-01-08 16:28:35.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/libgit2-sys/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -489,6 +489,10 @@
         GIT_CERT_SSH_RAW_TYPE_UNKNOWN = 0,
         GIT_CERT_SSH_RAW_TYPE_RSA = 1,
         GIT_CERT_SSH_RAW_TYPE_DSS = 2,
+        GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 = 3,
+        GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 = 4,
+        GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 = 5,
+        GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 = 6,
     }
 }
 
diff -Nru cargo-0.66.0/vendor/sha1/benches/mod.rs cargo-0.66.0+ds1/vendor/sha1/benches/mod.rs
--- cargo-0.66.0/vendor/sha1/benches/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/benches/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,14 @@
+#![feature(test)]
+extern crate test;
+
+use digest::bench_update;
+use sha1::Sha1;
+use test::Bencher;
+
+bench_update!(
+    Sha1::default();
+    sha1_10 10;
+    sha1_100 100;
+    sha1_1000 1000;
+    sha1_10000 10000;
+);
diff -Nru cargo-0.66.0/vendor/sha1/.cargo-checksum.json cargo-0.66.0+ds1/vendor/sha1/.cargo-checksum.json
--- cargo-0.66.0/vendor/sha1/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/sha1/Cargo.toml cargo-0.66.0+ds1/vendor/sha1/Cargo.toml
--- cargo-0.66.0/vendor/sha1/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,52 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "sha1"
+version = "0.10.5"
+authors = ["RustCrypto Developers"]
+description = "SHA-1 hash function"
+documentation = "https://docs.rs/sha1"
+readme = "README.md"
+keywords = ["crypto", "sha1", "hash", "digest"]
+categories = ["cryptography", "no-std"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/RustCrypto/hashes"
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+[dependencies.cfg-if]
+version = "1.0"
+
+[dependencies.digest]
+version = "0.10.4"
+[dev-dependencies.digest]
+version = "0.10.4"
+features = ["dev"]
+
+[dev-dependencies.hex-literal]
+version = "0.2.2"
+
+[features]
+asm = ["sha1-asm"]
+compress = []
+default = ["std"]
+force-soft = []
+oid = ["digest/oid"]
+std = ["digest/std"]
+[target."cfg(any(target_arch = \"aarch64\", target_arch = \"x86\", target_arch = \"x86_64\"))".dependencies.cpufeatures]
+version = "0.2"
+
+[target."cfg(any(target_arch = \"aarch64\", target_arch = \"x86\", target_arch = \"x86_64\"))".dependencies.sha1-asm]
+version = "0.5"
+optional = true
diff -Nru cargo-0.66.0/vendor/sha1/CHANGELOG.md cargo-0.66.0+ds1/vendor/sha1/CHANGELOG.md
--- cargo-0.66.0/vendor/sha1/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,42 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.10.5 (2022-09-16)
+### Added
+- Feature-gated OID support ([#405])
+
+[#405]: https://github.com/RustCrypto/hashes/pull/405
+
+## 0.10.4 (2022-09-02)
+### Fixed
+- MSRV issue which was not resolved by v0.10.3 ([#401])
+
+[#401]: https://github.com/RustCrypto/hashes/pull/401
+
+## 0.10.3 (2022-09-02)
+### Fixed
+- MSRV issue caused by publishing v0.10.2 using a buggy Nightly toolchain ([#399])
+
+[#399]: https://github.com/RustCrypto/hashes/pull/399
+
+## 0.10.2 (2022-08-30)
+### Changed
+- Ignore `asm` feature on unsupported targets ([#388])
+
+[#388]: https://github.com/RustCrypto/hashes/pull/388
+
+## 0.10.1 (2022-02-17)
+### Fixed
+- Minimal versions build ([#363])
+
+[#363]: https://github.com/RustCrypto/hashes/pull/363
+
+## 0.10.0 (2022-01-17)
+### Changed
+- The crate is transferred to the RustCrypto organization. New implementation is identical to the `sha-1 v0.10.0` crate and expressed in terms of traits from the `digest` crate. ([#350])
+
+[#350]: https://github.com/RustCrypto/hashes/pull/350
diff -Nru cargo-0.66.0/vendor/sha1/LICENSE-APACHE cargo-0.66.0+ds1/vendor/sha1/LICENSE-APACHE
--- cargo-0.66.0/vendor/sha1/LICENSE-APACHE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/LICENSE-APACHE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff -Nru cargo-0.66.0/vendor/sha1/LICENSE-MIT cargo-0.66.0+ds1/vendor/sha1/LICENSE-MIT
--- cargo-0.66.0/vendor/sha1/LICENSE-MIT	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/LICENSE-MIT	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,27 @@
+Copyright (c) 2006-2009 Graydon Hoare
+Copyright (c) 2009-2013 Mozilla Foundation
+Copyright (c) 2016 Artyom Pavlov
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff -Nru cargo-0.66.0/vendor/sha1/README.md cargo-0.66.0+ds1/vendor/sha1/README.md
--- cargo-0.66.0/vendor/sha1/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,65 @@
+# RustCrypto: SHA-1
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+[![Build Status][build-image]][build-link]
+
+Pure Rust implementation of the [SHA-1 hash function][1].
+
+[Documentation][docs-link]
+
+## ? Warning: Cryptographically Broken ?
+
+The SHA-1 hash function should be considered cryptographically broken and
+unsuitable for further use in any security critical capacity, as it is
+[practically vulnerable to chosen-prefix collisions][2].
+
+We provide this crate for legacy interoperability purposes only.
+
+## Minimum Supported Rust Version
+
+Rust **1.41** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be
+done with a minor version bump.
+
+## SemVer Policy
+
+- All on-by-default features of this library are covered by SemVer
+- MSRV is considered exempt from SemVer as noted above
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/sha-1.svg
+[crate-link]: https://crates.io/crates/sha-1
+[docs-image]: https://docs.rs/sha-1/badge.svg
+[docs-link]: https://docs.rs/sha-1/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes
+[build-image]: https://github.com/RustCrypto/hashes/workflows/sha1/badge.svg?branch=master
+[build-link]: https://github.com/RustCrypto/hashes/actions?query=workflow%3Asha1
+
+[//]: # (general links)
+
+[1]: https://en.wikipedia.org/wiki/SHA-1
+[2]: https://sha-mbles.github.io/
diff -Nru cargo-0.66.0/vendor/sha1/src/compress/aarch64.rs cargo-0.66.0+ds1/vendor/sha1/src/compress/aarch64.rs
--- cargo-0.66.0/vendor/sha1/src/compress/aarch64.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/src/compress/aarch64.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,18 @@
+//! SHA-1 `aarch64` backend.
+
+// Per rustc target feature docs for `aarch64-unknown-linux-gnu` and
+// `aarch64-apple-darwin` platforms, the `sha2` target feature enables
+// SHA-1 as well:
+//
+// > Enable SHA1 and SHA256 support.
+cpufeatures::new!(sha1_hwcap, "sha2");
+
+pub fn compress(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
+    // TODO: Replace with https://github.com/rust-lang/rfcs/pull/2725
+    // after stabilization
+    if sha1_hwcap::get() {
+        sha1_asm::compress(state, blocks);
+    } else {
+        super::soft::compress(state, blocks);
+    }
+}
diff -Nru cargo-0.66.0/vendor/sha1/src/compress/soft.rs cargo-0.66.0+ds1/vendor/sha1/src/compress/soft.rs
--- cargo-0.66.0/vendor/sha1/src/compress/soft.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/src/compress/soft.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,260 @@
+#![allow(clippy::many_single_char_names)]
+use super::BLOCK_SIZE;
+use core::convert::TryInto;
+
+const K: [u32; 4] = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
+
+#[inline(always)]
+fn add(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    [
+        a[0].wrapping_add(b[0]),
+        a[1].wrapping_add(b[1]),
+        a[2].wrapping_add(b[2]),
+        a[3].wrapping_add(b[3]),
+    ]
+}
+
+#[inline(always)]
+fn xor(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]
+}
+
+#[inline]
+pub fn sha1_first_add(e: u32, w0: [u32; 4]) -> [u32; 4] {
+    let [a, b, c, d] = w0;
+    [e.wrapping_add(a), b, c, d]
+}
+
+fn sha1msg1(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    let [_, _, w2, w3] = a;
+    let [w4, w5, _, _] = b;
+    [a[0] ^ w2, a[1] ^ w3, a[2] ^ w4, a[3] ^ w5]
+}
+
+fn sha1msg2(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    let [x0, x1, x2, x3] = a;
+    let [_, w13, w14, w15] = b;
+
+    let w16 = (x0 ^ w13).rotate_left(1);
+    let w17 = (x1 ^ w14).rotate_left(1);
+    let w18 = (x2 ^ w15).rotate_left(1);
+    let w19 = (x3 ^ w16).rotate_left(1);
+
+    [w16, w17, w18, w19]
+}
+
+#[inline]
+fn sha1_first_half(abcd: [u32; 4], msg: [u32; 4]) -> [u32; 4] {
+    sha1_first_add(abcd[0].rotate_left(30), msg)
+}
+
+fn sha1_digest_round_x4(abcd: [u32; 4], work: [u32; 4], i: i8) -> [u32; 4] {
+    match i {
+        0 => sha1rnds4c(abcd, add(work, [K[0]; 4])),
+        1 => sha1rnds4p(abcd, add(work, [K[1]; 4])),
+        2 => sha1rnds4m(abcd, add(work, [K[2]; 4])),
+        3 => sha1rnds4p(abcd, add(work, [K[3]; 4])),
+        _ => unreachable!("unknown icosaround index"),
+    }
+}
+
+fn sha1rnds4c(abcd: [u32; 4], msg: [u32; 4]) -> [u32; 4] {
+    let [mut a, mut b, mut c, mut d] = abcd;
+    let [t, u, v, w] = msg;
+    let mut e = 0u32;
+
+    macro_rules! bool3ary_202 {
+        ($a:expr, $b:expr, $c:expr) => {
+            $c ^ ($a & ($b ^ $c))
+        };
+    } // Choose, MD5F, SHA1C
+
+    e = e
+        .wrapping_add(a.rotate_left(5))
+        .wrapping_add(bool3ary_202!(b, c, d))
+        .wrapping_add(t);
+    b = b.rotate_left(30);
+
+    d = d
+        .wrapping_add(e.rotate_left(5))
+        .wrapping_add(bool3ary_202!(a, b, c))
+        .wrapping_add(u);
+    a = a.rotate_left(30);
+
+    c = c
+        .wrapping_add(d.rotate_left(5))
+        .wrapping_add(bool3ary_202!(e, a, b))
+        .wrapping_add(v);
+    e = e.rotate_left(30);
+
+    b = b
+        .wrapping_add(c.rotate_left(5))
+        .wrapping_add(bool3ary_202!(d, e, a))
+        .wrapping_add(w);
+    d = d.rotate_left(30);
+
+    [b, c, d, e]
+}
+
+fn sha1rnds4p(abcd: [u32; 4], msg: [u32; 4]) -> [u32; 4] {
+    let [mut a, mut b, mut c, mut d] = abcd;
+    let [t, u, v, w] = msg;
+    let mut e = 0u32;
+
+    macro_rules! bool3ary_150 {
+        ($a:expr, $b:expr, $c:expr) => {
+            $a ^ $b ^ $c
+        };
+    } // Parity, XOR, MD5H, SHA1P
+
+    e = e
+        .wrapping_add(a.rotate_left(5))
+        .wrapping_add(bool3ary_150!(b, c, d))
+        .wrapping_add(t);
+    b = b.rotate_left(30);
+
+    d = d
+        .wrapping_add(e.rotate_left(5))
+        .wrapping_add(bool3ary_150!(a, b, c))
+        .wrapping_add(u);
+    a = a.rotate_left(30);
+
+    c = c
+        .wrapping_add(d.rotate_left(5))
+        .wrapping_add(bool3ary_150!(e, a, b))
+        .wrapping_add(v);
+    e = e.rotate_left(30);
+
+    b = b
+        .wrapping_add(c.rotate_left(5))
+        .wrapping_add(bool3ary_150!(d, e, a))
+        .wrapping_add(w);
+    d = d.rotate_left(30);
+
+    [b, c, d, e]
+}
+
+fn sha1rnds4m(abcd: [u32; 4], msg: [u32; 4]) -> [u32; 4] {
+    let [mut a, mut b, mut c, mut d] = abcd;
+    let [t, u, v, w] = msg;
+    let mut e = 0u32;
+
+    macro_rules! bool3ary_232 {
+        ($a:expr, $b:expr, $c:expr) => {
+            ($a & $b) ^ ($a & $c) ^ ($b & $c)
+        };
+    } // Majority, SHA1M
+
+    e = e
+        .wrapping_add(a.rotate_left(5))
+        .wrapping_add(bool3ary_232!(b, c, d))
+        .wrapping_add(t);
+    b = b.rotate_left(30);
+
+    d = d
+        .wrapping_add(e.rotate_left(5))
+        .wrapping_add(bool3ary_232!(a, b, c))
+        .wrapping_add(u);
+    a = a.rotate_left(30);
+
+    c = c
+        .wrapping_add(d.rotate_left(5))
+        .wrapping_add(bool3ary_232!(e, a, b))
+        .wrapping_add(v);
+    e = e.rotate_left(30);
+
+    b = b
+        .wrapping_add(c.rotate_left(5))
+        .wrapping_add(bool3ary_232!(d, e, a))
+        .wrapping_add(w);
+    d = d.rotate_left(30);
+
+    [b, c, d, e]
+}
+
+macro_rules! rounds4 {
+    ($h0:ident, $h1:ident, $wk:expr, $i:expr) => {
+        sha1_digest_round_x4($h0, sha1_first_half($h1, $wk), $i)
+    };
+}
+
+macro_rules! schedule {
+    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {
+        sha1msg2(xor(sha1msg1($v0, $v1), $v2), $v3)
+    };
+}
+
+macro_rules! schedule_rounds4 {
+    (
+        $h0:ident, $h1:ident,
+        $w0:expr, $w1:expr, $w2:expr, $w3:expr, $w4:expr,
+        $i:expr
+    ) => {
+        $w4 = schedule!($w0, $w1, $w2, $w3);
+        $h1 = rounds4!($h0, $h1, $w4, $i);
+    };
+}
+
+#[inline(always)]
+fn sha1_digest_block_u32(state: &mut [u32; 5], block: &[u32; 16]) {
+    let mut w0 = [block[0], block[1], block[2], block[3]];
+    let mut w1 = [block[4], block[5], block[6], block[7]];
+    let mut w2 = [block[8], block[9], block[10], block[11]];
+    let mut w3 = [block[12], block[13], block[14], block[15]];
+    #[allow(clippy::needless_late_init)]
+    let mut w4;
+
+    let mut h0 = [state[0], state[1], state[2], state[3]];
+    let mut h1 = sha1_first_add(state[4], w0);
+
+    // Rounds 0..20
+    h1 = sha1_digest_round_x4(h0, h1, 0);
+    h0 = rounds4!(h1, h0, w1, 0);
+    h1 = rounds4!(h0, h1, w2, 0);
+    h0 = rounds4!(h1, h0, w3, 0);
+    schedule_rounds4!(h0, h1, w0, w1, w2, w3, w4, 0);
+
+    // Rounds 20..40
+    schedule_rounds4!(h1, h0, w1, w2, w3, w4, w0, 1);
+    schedule_rounds4!(h0, h1, w2, w3, w4, w0, w1, 1);
+    schedule_rounds4!(h1, h0, w3, w4, w0, w1, w2, 1);
+    schedule_rounds4!(h0, h1, w4, w0, w1, w2, w3, 1);
+    schedule_rounds4!(h1, h0, w0, w1, w2, w3, w4, 1);
+
+    // Rounds 40..60
+    schedule_rounds4!(h0, h1, w1, w2, w3, w4, w0, 2);
+    schedule_rounds4!(h1, h0, w2, w3, w4, w0, w1, 2);
+    schedule_rounds4!(h0, h1, w3, w4, w0, w1, w2, 2);
+    schedule_rounds4!(h1, h0, w4, w0, w1, w2, w3, 2);
+    schedule_rounds4!(h0, h1, w0, w1, w2, w3, w4, 2);
+
+    // Rounds 60..80
+    schedule_rounds4!(h1, h0, w1, w2, w3, w4, w0, 3);
+    schedule_rounds4!(h0, h1, w2, w3, w4, w0, w1, 3);
+    schedule_rounds4!(h1, h0, w3, w4, w0, w1, w2, 3);
+    schedule_rounds4!(h0, h1, w4, w0, w1, w2, w3, 3);
+    schedule_rounds4!(h1, h0, w0, w1, w2, w3, w4, 3);
+
+    let e = h1[0].rotate_left(30);
+    let [a, b, c, d] = h0;
+
+    state[0] = state[0].wrapping_add(a);
+    state[1] = state[1].wrapping_add(b);
+    state[2] = state[2].wrapping_add(c);
+    state[3] = state[3].wrapping_add(d);
+    state[4] = state[4].wrapping_add(e);
+}
+
+pub fn compress(state: &mut [u32; 5], blocks: &[[u8; BLOCK_SIZE]]) {
+    let mut block_u32 = [0u32; BLOCK_SIZE / 4];
+    // since LLVM can't properly use aliasing yet it will make
+    // unnecessary state stores without this copy
+    let mut state_cpy = *state;
+    for block in blocks.iter() {
+        for (o, chunk) in block_u32.iter_mut().zip(block.chunks_exact(4)) {
+            *o = u32::from_be_bytes(chunk.try_into().unwrap());
+        }
+        sha1_digest_block_u32(&mut state_cpy, &block_u32);
+    }
+    *state = state_cpy;
+}
diff -Nru cargo-0.66.0/vendor/sha1/src/compress/x86.rs cargo-0.66.0+ds1/vendor/sha1/src/compress/x86.rs
--- cargo-0.66.0/vendor/sha1/src/compress/x86.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/src/compress/x86.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,112 @@
+//! SHA-1 `x86`/`x86_64` backend
+
+#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+
+#[cfg(target_arch = "x86")]
+use core::arch::x86::*;
+#[cfg(target_arch = "x86_64")]
+use core::arch::x86_64::*;
+
+macro_rules! rounds4 {
+    ($h0:ident, $h1:ident, $wk:expr, $i:expr) => {
+        _mm_sha1rnds4_epu32($h0, _mm_sha1nexte_epu32($h1, $wk), $i)
+    };
+}
+
+macro_rules! schedule {
+    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {
+        _mm_sha1msg2_epu32(_mm_xor_si128(_mm_sha1msg1_epu32($v0, $v1), $v2), $v3)
+    };
+}
+
+macro_rules! schedule_rounds4 {
+    (
+        $h0:ident, $h1:ident,
+        $w0:expr, $w1:expr, $w2:expr, $w3:expr, $w4:expr,
+        $i:expr
+    ) => {
+        $w4 = schedule!($w0, $w1, $w2, $w3);
+        $h1 = rounds4!($h0, $h1, $w4, $i);
+    };
+}
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn digest_blocks(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
+    #[allow(non_snake_case)]
+    let MASK: __m128i = _mm_set_epi64x(0x0001_0203_0405_0607, 0x0809_0A0B_0C0D_0E0F);
+
+    let mut state_abcd = _mm_set_epi32(
+        state[0] as i32,
+        state[1] as i32,
+        state[2] as i32,
+        state[3] as i32,
+    );
+    let mut state_e = _mm_set_epi32(state[4] as i32, 0, 0, 0);
+
+    for block in blocks {
+        // SAFETY: we use only unaligned loads with this pointer
+        #[allow(clippy::cast_ptr_alignment)]
+        let block_ptr = block.as_ptr() as *const __m128i;
+
+        let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(0)), MASK);
+        let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(1)), MASK);
+        let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(2)), MASK);
+        let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(3)), MASK);
+        #[allow(clippy::needless_late_init)]
+        let mut w4;
+
+        let mut h0 = state_abcd;
+        let mut h1 = _mm_add_epi32(state_e, w0);
+
+        // Rounds 0..20
+        h1 = _mm_sha1rnds4_epu32(h0, h1, 0);
+        h0 = rounds4!(h1, h0, w1, 0);
+        h1 = rounds4!(h0, h1, w2, 0);
+        h0 = rounds4!(h1, h0, w3, 0);
+        schedule_rounds4!(h0, h1, w0, w1, w2, w3, w4, 0);
+
+        // Rounds 20..40
+        schedule_rounds4!(h1, h0, w1, w2, w3, w4, w0, 1);
+        schedule_rounds4!(h0, h1, w2, w3, w4, w0, w1, 1);
+        schedule_rounds4!(h1, h0, w3, w4, w0, w1, w2, 1);
+        schedule_rounds4!(h0, h1, w4, w0, w1, w2, w3, 1);
+        schedule_rounds4!(h1, h0, w0, w1, w2, w3, w4, 1);
+
+        // Rounds 40..60
+        schedule_rounds4!(h0, h1, w1, w2, w3, w4, w0, 2);
+        schedule_rounds4!(h1, h0, w2, w3, w4, w0, w1, 2);
+        schedule_rounds4!(h0, h1, w3, w4, w0, w1, w2, 2);
+        schedule_rounds4!(h1, h0, w4, w0, w1, w2, w3, 2);
+        schedule_rounds4!(h0, h1, w0, w1, w2, w3, w4, 2);
+
+        // Rounds 60..80
+        schedule_rounds4!(h1, h0, w1, w2, w3, w4, w0, 3);
+        schedule_rounds4!(h0, h1, w2, w3, w4, w0, w1, 3);
+        schedule_rounds4!(h1, h0, w3, w4, w0, w1, w2, 3);
+        schedule_rounds4!(h0, h1, w4, w0, w1, w2, w3, 3);
+        schedule_rounds4!(h1, h0, w0, w1, w2, w3, w4, 3);
+
+        state_abcd = _mm_add_epi32(state_abcd, h0);
+        state_e = _mm_sha1nexte_epu32(h1, state_e);
+    }
+
+    state[0] = _mm_extract_epi32(state_abcd, 3) as u32;
+    state[1] = _mm_extract_epi32(state_abcd, 2) as u32;
+    state[2] = _mm_extract_epi32(state_abcd, 1) as u32;
+    state[3] = _mm_extract_epi32(state_abcd, 0) as u32;
+    state[4] = _mm_extract_epi32(state_e, 3) as u32;
+}
+
+cpufeatures::new!(shani_cpuid, "sha", "sse2", "ssse3", "sse4.1");
+
+pub fn compress(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
+    // TODO: Replace with https://github.com/rust-lang/rfcs/pull/2725
+    // after stabilization
+    if shani_cpuid::get() {
+        unsafe {
+            digest_blocks(state, blocks);
+        }
+    } else {
+        super::soft::compress(state, blocks);
+    }
+}
diff -Nru cargo-0.66.0/vendor/sha1/src/compress.rs cargo-0.66.0+ds1/vendor/sha1/src/compress.rs
--- cargo-0.66.0/vendor/sha1/src/compress.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/src/compress.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,37 @@
+use crate::{Block, BlockSizeUser, Sha1Core};
+use digest::typenum::Unsigned;
+
+cfg_if::cfg_if! {
+    if #[cfg(feature = "force-soft")] {
+        mod soft;
+        use soft::compress as compress_inner;
+    } else if #[cfg(all(feature = "asm", target_arch = "aarch64"))] {
+        mod soft;
+        mod aarch64;
+        use aarch64::compress as compress_inner;
+    } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
+        #[cfg(not(feature = "asm"))]
+        mod soft;
+        #[cfg(feature = "asm")]
+        mod soft {
+            pub use sha1_asm::compress;
+        }
+        mod x86;
+        use x86::compress as compress_inner;
+    } else {
+        mod soft;
+        use soft::compress as compress_inner;
+    }
+}
+
+const BLOCK_SIZE: usize = <Sha1Core as BlockSizeUser>::BlockSize::USIZE;
+
+/// SHA-1 compression function
+#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
+pub fn compress(state: &mut [u32; 5], blocks: &[Block<Sha1Core>]) {
+    // SAFETY: GenericArray<u8, U64> and [u8; 64] have
+    // exactly the same memory layout
+    let blocks: &[[u8; BLOCK_SIZE]] =
+        unsafe { &*(blocks as *const _ as *const [[u8; BLOCK_SIZE]]) };
+    compress_inner(state, blocks);
+}
diff -Nru cargo-0.66.0/vendor/sha1/src/lib.rs cargo-0.66.0+ds1/vendor/sha1/src/lib.rs
--- cargo-0.66.0/vendor/sha1/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,154 @@
+//! Pure Rust implementation of the [SHA-1][1] cryptographic hash algorithm
+//! with optional hardware-specific optimizations.
+//!
+//! # ? Warning: Cryptographically Broken! ?
+//!
+//! The SHA-1 hash function should be considered cryptographically broken and
+//! unsuitable for further use in any security critical capacity, as it is
+//! [practically vulnerable to chosen-prefix collisions][2].
+//!
+//! We provide this crate for legacy interoperability purposes only.
+//!
+//! # Usage
+//!
+//! ```rust
+//! use hex_literal::hex;
+//! use sha1::{Sha1, Digest};
+//!
+//! // create a Sha1 object
+//! let mut hasher = Sha1::new();
+//!
+//! // process input message
+//! hasher.update(b"hello world");
+//!
+//! // acquire hash digest in the form of GenericArray,
+//! // which in this case is equivalent to [u8; 20]
+//! let result = hasher.finalize();
+//! assert_eq!(result[..], hex!("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"));
+//! ```
+//!
+//! Also see [RustCrypto/hashes][3] readme.
+//!
+//! # Note for users of `sha1 v0.6`
+//!
+//! This crate has been transferred to the RustCrypto organization and uses
+//! implementation previously published as the `sha-1` crate. The previous
+//! zero dependencies version is now published as the [`sha1_smoll`] crate.
+//!
+//! [1]: https://en.wikipedia.org/wiki/SHA-1
+//! [2]: https://sha-mbles.github.io/
+//! [3]: https://github.com/RustCrypto/hashes
+//! [`sha1_smoll`]: https://github.com/mitsuhiko/sha1-smol/
+
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![doc(
+    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+#![warn(missing_docs, rust_2018_idioms)]
+
+pub use digest::{self, Digest};
+
+use core::{fmt, slice::from_ref};
+#[cfg(feature = "oid")]
+use digest::const_oid::{AssociatedOid, ObjectIdentifier};
+use digest::{
+    block_buffer::Eager,
+    core_api::{
+        AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore,
+        OutputSizeUser, Reset, UpdateCore,
+    },
+    typenum::{Unsigned, U20, U64},
+    HashMarker, Output,
+};
+
+mod compress;
+
+#[cfg(feature = "compress")]
+pub use compress::compress;
+#[cfg(not(feature = "compress"))]
+use compress::compress;
+
+const STATE_LEN: usize = 5;
+
+/// Core SHA-1 hasher state.
+#[derive(Clone)]
+pub struct Sha1Core {
+    h: [u32; STATE_LEN],
+    block_len: u64,
+}
+
+impl HashMarker for Sha1Core {}
+
+impl BlockSizeUser for Sha1Core {
+    type BlockSize = U64;
+}
+
+impl BufferKindUser for Sha1Core {
+    type BufferKind = Eager;
+}
+
+impl OutputSizeUser for Sha1Core {
+    type OutputSize = U20;
+}
+
+impl UpdateCore for Sha1Core {
+    #[inline]
+    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
+        self.block_len += blocks.len() as u64;
+        compress(&mut self.h, blocks);
+    }
+}
+
+impl FixedOutputCore for Sha1Core {
+    #[inline]
+    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
+        let bs = Self::BlockSize::U64;
+        let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
+
+        let mut h = self.h;
+        buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
+        for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) {
+            chunk.copy_from_slice(&v.to_be_bytes());
+        }
+    }
+}
+
+impl Default for Sha1Core {
+    #[inline]
+    fn default() -> Self {
+        Self {
+            h: [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0],
+            block_len: 0,
+        }
+    }
+}
+
+impl Reset for Sha1Core {
+    #[inline]
+    fn reset(&mut self) {
+        *self = Default::default();
+    }
+}
+
+impl AlgorithmName for Sha1Core {
+    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("Sha1")
+    }
+}
+
+impl fmt::Debug for Sha1Core {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("Sha1Core { ... }")
+    }
+}
+
+#[cfg(feature = "oid")]
+#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
+impl AssociatedOid for Sha1Core {
+    const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
+}
+
+/// SHA-1 hasher state.
+pub type Sha1 = CoreWrapper<Sha1Core>;
Binary files /tmp/0qBeJOL7bD/cargo-0.66.0/vendor/sha1/tests/data/sha1.blb and /tmp/2UpOBpRm2v/cargo-0.66.0+ds1/vendor/sha1/tests/data/sha1.blb differ
diff -Nru cargo-0.66.0/vendor/sha1/tests/mod.rs cargo-0.66.0+ds1/vendor/sha1/tests/mod.rs
--- cargo-0.66.0/vendor/sha1/tests/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/sha1/tests/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,15 @@
+use digest::dev::{feed_rand_16mib, fixed_reset_test};
+use hex_literal::hex;
+use sha1::{Digest, Sha1};
+
+digest::new_test!(sha1_main, "sha1", Sha1, fixed_reset_test);
+
+#[test]
+fn sha1_rand() {
+    let mut h = Sha1::new();
+    feed_rand_16mib(&mut h);
+    assert_eq!(
+        h.finalize()[..],
+        hex!("7e565a25a8b123e9881addbcedcd927b23377a78")[..]
+    );
+}
diff -Nru cargo-0.66.0/vendor/subtle/.cargo-checksum.json cargo-0.66.0+ds1/vendor/subtle/.cargo-checksum.json
--- cargo-0.66.0/vendor/subtle/.cargo-checksum.json	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/.cargo-checksum.json	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1 @@
+{"files":{},"package":"6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"}
\ No newline at end of file
diff -Nru cargo-0.66.0/vendor/subtle/Cargo.toml cargo-0.66.0+ds1/vendor/subtle/Cargo.toml
--- cargo-0.66.0/vendor/subtle/Cargo.toml	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/Cargo.toml	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,36 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "subtle"
+version = "2.4.1"
+authors = ["Isis Lovecruft <isis at patternsinthevoid.net>", "Henry de Valence <hdevalence at hdevalence.ca>"]
+exclude = ["**/.gitignore", ".travis.yml"]
+description = "Pure-Rust traits and utilities for constant-time cryptographic implementations."
+homepage = "https://dalek.rs/"
+documentation = "https://docs.rs/subtle"
+readme = "README.md"
+keywords = ["cryptography", "crypto", "constant-time", "utilities"]
+categories = ["cryptography", "no-std"]
+license = "BSD-3-Clause"
+repository = "https://github.com/dalek-cryptography/subtle"
+[dev-dependencies.rand]
+version = "0.7"
+
+[features]
+default = ["std", "i128"]
+i128 = []
+nightly = []
+std = []
+[badges.travis-ci]
+branch = "master"
+repository = "dalek-cryptography/subtle"
diff -Nru cargo-0.66.0/vendor/subtle/CHANGELOG.md cargo-0.66.0+ds1/vendor/subtle/CHANGELOG.md
--- cargo-0.66.0/vendor/subtle/CHANGELOG.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/CHANGELOG.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,59 @@
+# Changelog
+
+Entries are listed in reverse chronological order.
+
+## 2.4.1
+
+* Fix a bug in how the README was included in the documentation builds
+  which caused nightly builds to break.
+
+## 2.4.0
+
+* Add new `ConstantTimeGreater` and `ConstantTimeLess` traits, as well
+  as implementations for unsigned integers, by @isislovecruft.
+
+## 2.3.0
+
+* Add `impl ConstantTimeEq for Choice` by @tarcieri.
+* Add `impl From<CtOption<T>> for Option<T>` by @CPerezz.  This is useful for
+  handling library code that produces `CtOption`s in contexts where timing
+  doesn't matter.
+* Introduce an MSRV policy.
+
+## 2.2.3
+
+* Remove the `nightly`-only asm-based `black_box` barrier in favor of the
+  volatile-based one, fixing compilation on current nightlies.
+
+## 2.2.2
+
+* Update README.md to clarify that 2.2 and above do not require the `nightly`
+  feature.
+
+## 2.2.1
+
+* Adds an `or_else` combinator for `CtOption`, by @ebfull.
+* Optimized `black_box` for `nightly`, by @jethrogb.
+* Optimized `black_box` for `stable`, by @dsprenkels.
+* Fixed CI for `no_std`, by @dsprenkels.
+* Fixed fuzz target compilation, by @3for.
+
+## 2.2.0
+
+* Error during `cargo publish`, yanked.
+
+## 2.1.1
+
+* Adds the "crypto" tag to crate metadata.
+* New shorter, more efficient ct_eq() for integers, contributed by Thomas Pornin.
+
+## 2.1.0
+
+* Adds a new `CtOption<T>` which acts as a constant-time `Option<T>`
+  (thanks to @ebfull for the implementation).
+* `Choice` now itself implements `ConditionallySelectable`.
+
+## 2.0.0
+
+* Stable version with traits reworked from 1.0.0 to interact better
+  with the orphan rules.
diff -Nru cargo-0.66.0/vendor/subtle/CONTRIBUTING.md cargo-0.66.0+ds1/vendor/subtle/CONTRIBUTING.md
--- cargo-0.66.0/vendor/subtle/CONTRIBUTING.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/CONTRIBUTING.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,33 @@
+# Contributing to subtle
+
+If you have questions or comments, please feel free to email the
+authors. 
+
+For feature requests, suggestions, and bug reports, please open an
+issue on [our Github](https://github.com/dalek-cryptography/subtle).  (Or,
+send us an email if you're opposed to using Github for whatever reason.)
+
+Patches are welcomed as pull requests on
+[our Github](https://github.com/dalek-cryptography/subtle), as well as by
+email (preferably sent to all of the authors listed in `Cargo.toml`).
+
+We're happy to take generalised utility code, provided the code is:
+
+1. constant time for all potential valid invocations, and
+2. applicable to implementations of several different protocols/primitives.
+
+All issues on subtle are mentored, if you want help with a bug just ask
+ at isislovecruft or @hdevalence.
+
+Some issues are easier than others. The `easy` label can be used to find the
+easy issues. If you want to work on an issue, please leave a comment so that we
+can assign it to you!
+
+# Code of Conduct
+
+We follow the [Rust Code of Conduct](http://www.rust-lang.org/conduct.html),
+with the following additional clauses:
+
+* We respect the rights to privacy and anonymity for contributors and people in
+  the community.  If someone wishes to contribute under a pseudonym different to
+  their primary identity, that wish is to be respected by all contributors.
diff -Nru cargo-0.66.0/vendor/subtle/LICENSE cargo-0.66.0+ds1/vendor/subtle/LICENSE
--- cargo-0.66.0/vendor/subtle/LICENSE	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/LICENSE	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,28 @@
+Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
diff -Nru cargo-0.66.0/vendor/subtle/README.md cargo-0.66.0+ds1/vendor/subtle/README.md
--- cargo-0.66.0/vendor/subtle/README.md	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/README.md	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,69 @@
+# subtle [![](https://img.shields.io/crates/v/subtle.svg)](https://crates.io/crates/subtle) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fsubtle%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs/subtle) [![](https://travis-ci.org/dalek-cryptography/subtle.svg?branch=master)](https://travis-ci.org/dalek-cryptography/subtle)
+
+**Pure-Rust traits and utilities for constant-time cryptographic implementations.**
+
+It consists of a `Choice` type, and a collection of traits using `Choice`
+instead of `bool` which are intended to execute in constant-time.  The `Choice`
+type is a wrapper around a `u8` that holds a `0` or `1`.
+
+```toml
+subtle = "2.4"
+```
+
+This crate represents a ?best-effort? attempt, since side-channels
+are ultimately a property of a deployed cryptographic system
+including the hardware it runs on, not just of software.
+
+The traits are implemented using bitwise operations, and should execute in
+constant time provided that a) the bitwise operations are constant-time and
+b) the bitwise operations are not recognized as a conditional assignment and
+optimized back into a branch.
+
+For a compiler to recognize that bitwise operations represent a conditional
+assignment, it needs to know that the value used to generate the bitmasks is
+really a boolean `i1` rather than an `i8` byte value. In an attempt to
+prevent this refinement, the crate tries to hide the value of a `Choice`'s
+inner `u8` by passing it through a volatile read. For more information, see
+the _About_ section below.
+
+Versions prior to `2.2` recommended use of the `nightly` feature to enable an
+optimization barrier; this is not required in versions `2.2` and above.
+
+Note: the `subtle` crate contains `debug_assert`s to check invariants during
+debug builds. These invariant checks involve secret-dependent branches, and
+are not present when compiled in release mode. This crate is intended to be
+used in release mode.
+
+## Documentation
+
+Documentation is available [here][docs].
+
+## Minimum Supported Rust Version
+
+Rust **1.41** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
+
+## About
+
+This library aims to be the Rust equivalent of Go?s `crypto/subtle` module.
+
+The optimization barrier in `impl From<u8> for Choice` was based on Tim
+Maclean's [work on `rust-timing-shield`][rust-timing-shield], which attempts to
+provide a more comprehensive approach for preventing software side-channels in
+Rust code.
+
+`subtle` is authored by isis agora lovecruft and Henry de Valence.
+
+## Warning
+
+This code is a low-level library, intended for specific use-cases implementing
+cryptographic protocols.  It represents a best-effort attempt to protect
+against some software side-channels.  Because side-channel resistance is not a
+property of software alone, but of software together with hardware, any such
+effort is fundamentally limited.
+
+**USE AT YOUR OWN RISK**
+
+[docs]: https://docs.rs/subtle
+[rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
diff -Nru cargo-0.66.0/vendor/subtle/src/lib.rs cargo-0.66.0+ds1/vendor/subtle/src/lib.rs
--- cargo-0.66.0/vendor/subtle/src/lib.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/src/lib.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,864 @@
+// -*- mode: rust; -*-
+//
+// This file is part of subtle, part of the dalek cryptography project.
+// Copyright (c) 2016-2018 isis lovecruft, Henry de Valence
+// See LICENSE for licensing information.
+//
+// Authors:
+// - isis agora lovecruft <isis at patternsinthevoid.net>
+// - Henry de Valence <hdevalence at hdevalence.ca>
+
+#![no_std]
+#![deny(missing_docs)]
+#![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")]
+#![doc(html_root_url = "https://docs.rs/subtle/2.4.1")]
+
+//! # subtle [![](https://img.shields.io/crates/v/subtle.svg)](https://crates.io/crates/subtle) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fsubtle%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs/subtle) [![](https://travis-ci.org/dalek-cryptography/subtle.svg?branch=master)](https://travis-ci.org/dalek-cryptography/subtle)
+//!
+//! **Pure-Rust traits and utilities for constant-time cryptographic implementations.**
+//!
+//! It consists of a `Choice` type, and a collection of traits using `Choice`
+//! instead of `bool` which are intended to execute in constant-time.  The `Choice`
+//! type is a wrapper around a `u8` that holds a `0` or `1`.
+//!
+//! ```toml
+//! subtle = "2.4"
+//! ```
+//!
+//! This crate represents a ?best-effort? attempt, since side-channels
+//! are ultimately a property of a deployed cryptographic system
+//! including the hardware it runs on, not just of software.
+//!
+//! The traits are implemented using bitwise operations, and should execute in
+//! constant time provided that a) the bitwise operations are constant-time and
+//! b) the bitwise operations are not recognized as a conditional assignment and
+//! optimized back into a branch.
+//!
+//! For a compiler to recognize that bitwise operations represent a conditional
+//! assignment, it needs to know that the value used to generate the bitmasks is
+//! really a boolean `i1` rather than an `i8` byte value. In an attempt to
+//! prevent this refinement, the crate tries to hide the value of a `Choice`'s
+//! inner `u8` by passing it through a volatile read. For more information, see
+//! the _About_ section below.
+//!
+//! Versions prior to `2.2` recommended use of the `nightly` feature to enable an
+//! optimization barrier; this is not required in versions `2.2` and above.
+//!
+//! Note: the `subtle` crate contains `debug_assert`s to check invariants during
+//! debug builds. These invariant checks involve secret-dependent branches, and
+//! are not present when compiled in release mode. This crate is intended to be
+//! used in release mode.
+//!
+//! ## Documentation
+//!
+//! Documentation is available [here][docs].
+//!
+//! ## Minimum Supported Rust Version
+//!
+//! Rust **1.41** or higher.
+//!
+//! Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
+//!
+//! ## About
+//!
+//! This library aims to be the Rust equivalent of Go?s `crypto/subtle` module.
+//!
+//! The optimization barrier in `impl From<u8> for Choice` was based on Tim
+//! Maclean's [work on `rust-timing-shield`][rust-timing-shield], which attempts to
+//! provide a more comprehensive approach for preventing software side-channels in
+//! Rust code.
+//!
+//! `subtle` is authored by isis agora lovecruft and Henry de Valence.
+//!
+//! ## Warning
+//!
+//! This code is a low-level library, intended for specific use-cases implementing
+//! cryptographic protocols.  It represents a best-effort attempt to protect
+//! against some software side-channels.  Because side-channel resistance is not a
+//! property of software alone, but of software together with hardware, any such
+//! effort is fundamentally limited.
+//!
+//! **USE AT YOUR OWN RISK**
+//!
+//! [docs]: https://docs.rs/subtle
+//! [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
+
+#[cfg(feature = "std")]
+#[macro_use]
+extern crate std;
+
+use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Neg, Not};
+use core::option::Option;
+
+/// The `Choice` struct represents a choice for use in conditional assignment.
+///
+/// It is a wrapper around a `u8`, which should have the value either `1` (true)
+/// or `0` (false).
+///
+/// The conversion from `u8` to `Choice` passes the value through an optimization
+/// barrier, as a best-effort attempt to prevent the compiler from inferring that
+/// the `Choice` value is a boolean. This strategy is based on Tim Maclean's
+/// [work on `rust-timing-shield`][rust-timing-shield], which attempts to provide
+/// a more comprehensive approach for preventing software side-channels in Rust
+/// code.
+///
+/// The `Choice` struct implements operators for AND, OR, XOR, and NOT, to allow
+/// combining `Choice` values. These operations do not short-circuit.
+///
+/// [rust-timing-shield]:
+/// https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
+#[derive(Copy, Clone, Debug)]
+pub struct Choice(u8);
+
+impl Choice {
+    /// Unwrap the `Choice` wrapper to reveal the underlying `u8`.
+    ///
+    /// # Note
+    ///
+    /// This function only exists as an **escape hatch** for the rare case
+    /// where it's not possible to use one of the `subtle`-provided
+    /// trait impls.
+    ///
+    /// **To convert a `Choice` to a `bool`, use the `From` implementation instead.**
+    #[inline]
+    pub fn unwrap_u8(&self) -> u8 {
+        self.0
+    }
+}
+
+impl From<Choice> for bool {
+    /// Convert the `Choice` wrapper into a `bool`, depending on whether
+    /// the underlying `u8` was a `0` or a `1`.
+    ///
+    /// # Note
+    ///
+    /// This function exists to avoid having higher-level cryptographic protocol
+    /// implementations duplicating this pattern.
+    ///
+    /// The intended use case for this conversion is at the _end_ of a
+    /// higher-level primitive implementation: for example, in checking a keyed
+    /// MAC, where the verification should happen in constant-time (and thus use
+    /// a `Choice`) but it is safe to return a `bool` at the end of the
+    /// verification.
+    #[inline]
+    fn from(source: Choice) -> bool {
+        debug_assert!((source.0 == 0u8) | (source.0 == 1u8));
+        source.0 != 0
+    }
+}
+
+impl BitAnd for Choice {
+    type Output = Choice;
+    #[inline]
+    fn bitand(self, rhs: Choice) -> Choice {
+        (self.0 & rhs.0).into()
+    }
+}
+
+impl BitAndAssign for Choice {
+    #[inline]
+    fn bitand_assign(&mut self, rhs: Choice) {
+        *self = *self & rhs;
+    }
+}
+
+impl BitOr for Choice {
+    type Output = Choice;
+    #[inline]
+    fn bitor(self, rhs: Choice) -> Choice {
+        (self.0 | rhs.0).into()
+    }
+}
+
+impl BitOrAssign for Choice {
+    #[inline]
+    fn bitor_assign(&mut self, rhs: Choice) {
+        *self = *self | rhs;
+    }
+}
+
+impl BitXor for Choice {
+    type Output = Choice;
+    #[inline]
+    fn bitxor(self, rhs: Choice) -> Choice {
+        (self.0 ^ rhs.0).into()
+    }
+}
+
+impl BitXorAssign for Choice {
+    #[inline]
+    fn bitxor_assign(&mut self, rhs: Choice) {
+        *self = *self ^ rhs;
+    }
+}
+
+impl Not for Choice {
+    type Output = Choice;
+    #[inline]
+    fn not(self) -> Choice {
+        (1u8 & (!self.0)).into()
+    }
+}
+
+/// This function is a best-effort attempt to prevent the compiler from knowing
+/// anything about the value of the returned `u8`, other than its type.
+///
+/// Because we want to support stable Rust, we don't have access to inline
+/// assembly or test::black_box, so we use the fact that volatile values will
+/// never be elided to register values.
+///
+/// Note: Rust's notion of "volatile" is subject to change over time. While this
+/// code may break in a non-destructive way in the future, ?constant-time? code
+/// is a continually moving target, and this is better than doing nothing.
+#[inline(never)]
+fn black_box(input: u8) -> u8 {
+    debug_assert!((input == 0u8) | (input == 1u8));
+
+    unsafe {
+        // Optimization barrier
+        //
+        // Unsafe is ok, because:
+        //   - &input is not NULL;
+        //   - size of input is not zero;
+        //   - u8 is neither Sync, nor Send;
+        //   - u8 is Copy, so input is always live;
+        //   - u8 type is always properly aligned.
+        core::ptr::read_volatile(&input as *const u8)
+    }
+}
+
+impl From<u8> for Choice {
+    #[inline]
+    fn from(input: u8) -> Choice {
+        // Our goal is to prevent the compiler from inferring that the value held inside the
+        // resulting `Choice` struct is really an `i1` instead of an `i8`.
+        Choice(black_box(input))
+    }
+}
+
+/// An `Eq`-like trait that produces a `Choice` instead of a `bool`.
+///
+/// # Example
+///
+/// ```
+/// use subtle::ConstantTimeEq;
+/// let x: u8 = 5;
+/// let y: u8 = 13;
+///
+/// assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
+/// assert_eq!(x.ct_eq(&x).unwrap_u8(), 1);
+/// ```
+pub trait ConstantTimeEq {
+    /// Determine if two items are equal.
+    ///
+    /// The `ct_eq` function should execute in constant time.
+    ///
+    /// # Returns
+    ///
+    /// * `Choice(1u8)` if `self == other`;
+    /// * `Choice(0u8)` if `self != other`.
+    #[inline]
+    fn ct_eq(&self, other: &Self) -> Choice;
+}
+
+impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
+    /// Check whether two slices of `ConstantTimeEq` types are equal.
+    ///
+    /// # Note
+    ///
+    /// This function short-circuits if the lengths of the input slices
+    /// are different.  Otherwise, it should execute in time independent
+    /// of the slice contents.
+    ///
+    /// Since arrays coerce to slices, this function works with fixed-size arrays:
+    ///
+    /// ```
+    /// # use subtle::ConstantTimeEq;
+    /// #
+    /// let a: [u8; 8] = [0,1,2,3,4,5,6,7];
+    /// let b: [u8; 8] = [0,1,2,3,0,1,2,3];
+    ///
+    /// let a_eq_a = a.ct_eq(&a);
+    /// let a_eq_b = a.ct_eq(&b);
+    ///
+    /// assert_eq!(a_eq_a.unwrap_u8(), 1);
+    /// assert_eq!(a_eq_b.unwrap_u8(), 0);
+    /// ```
+    #[inline]
+    fn ct_eq(&self, _rhs: &[T]) -> Choice {
+        let len = self.len();
+
+        // Short-circuit on the *lengths* of the slices, not their
+        // contents.
+        if len != _rhs.len() {
+            return Choice::from(0);
+        }
+
+        // This loop shouldn't be shortcircuitable, since the compiler
+        // shouldn't be able to reason about the value of the `u8`
+        // unwrapped from the `ct_eq` result.
+        let mut x = 1u8;
+        for (ai, bi) in self.iter().zip(_rhs.iter()) {
+            x &= ai.ct_eq(bi).unwrap_u8();
+        }
+
+        x.into()
+    }
+}
+
+impl ConstantTimeEq for Choice {
+    #[inline]
+    fn ct_eq(&self, rhs: &Choice) -> Choice {
+        !(*self ^ *rhs)
+    }
+}
+
+/// Given the bit-width `$bit_width` and the corresponding primitive
+/// unsigned and signed types `$t_u` and `$t_i` respectively, generate
+/// an `ConstantTimeEq` implementation.
+macro_rules! generate_integer_equal {
+    ($t_u:ty, $t_i:ty, $bit_width:expr) => {
+        impl ConstantTimeEq for $t_u {
+            #[inline]
+            fn ct_eq(&self, other: &$t_u) -> Choice {
+                // x == 0 if and only if self == other
+                let x: $t_u = self ^ other;
+
+                // If x == 0, then x and -x are both equal to zero;
+                // otherwise, one or both will have its high bit set.
+                let y: $t_u = (x | x.wrapping_neg()) >> ($bit_width - 1);
+
+                // Result is the opposite of the high bit (now shifted to low).
+                ((y ^ (1 as $t_u)) as u8).into()
+            }
+        }
+        impl ConstantTimeEq for $t_i {
+            #[inline]
+            fn ct_eq(&self, other: &$t_i) -> Choice {
+                // Bitcast to unsigned and call that implementation.
+                (*self as $t_u).ct_eq(&(*other as $t_u))
+            }
+        }
+    };
+}
+
+generate_integer_equal!(u8, i8, 8);
+generate_integer_equal!(u16, i16, 16);
+generate_integer_equal!(u32, i32, 32);
+generate_integer_equal!(u64, i64, 64);
+#[cfg(feature = "i128")]
+generate_integer_equal!(u128, i128, 128);
+generate_integer_equal!(usize, isize, ::core::mem::size_of::<usize>() * 8);
+
+/// A type which can be conditionally selected in constant time.
+///
+/// This trait also provides generic implementations of conditional
+/// assignment and conditional swaps.
+pub trait ConditionallySelectable: Copy {
+    /// Select `a` or `b` according to `choice`.
+    ///
+    /// # Returns
+    ///
+    /// * `a` if `choice == Choice(0)`;
+    /// * `b` if `choice == Choice(1)`.
+    ///
+    /// This function should execute in constant time.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # extern crate subtle;
+    /// use subtle::ConditionallySelectable;
+    /// #
+    /// # fn main() {
+    /// let x: u8 = 13;
+    /// let y: u8 = 42;
+    ///
+    /// let z = u8::conditional_select(&x, &y, 0.into());
+    /// assert_eq!(z, x);
+    /// let z = u8::conditional_select(&x, &y, 1.into());
+    /// assert_eq!(z, y);
+    /// # }
+    /// ```
+    #[inline]
+    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self;
+
+    /// Conditionally assign `other` to `self`, according to `choice`.
+    ///
+    /// This function should execute in constant time.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # extern crate subtle;
+    /// use subtle::ConditionallySelectable;
+    /// #
+    /// # fn main() {
+    /// let mut x: u8 = 13;
+    /// let mut y: u8 = 42;
+    ///
+    /// x.conditional_assign(&y, 0.into());
+    /// assert_eq!(x, 13);
+    /// x.conditional_assign(&y, 1.into());
+    /// assert_eq!(x, 42);
+    /// # }
+    /// ```
+    #[inline]
+    fn conditional_assign(&mut self, other: &Self, choice: Choice) {
+        *self = Self::conditional_select(self, other, choice);
+    }
+
+    /// Conditionally swap `self` and `other` if `choice == 1`; otherwise,
+    /// reassign both unto themselves.
+    ///
+    /// This function should execute in constant time.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # extern crate subtle;
+    /// use subtle::ConditionallySelectable;
+    /// #
+    /// # fn main() {
+    /// let mut x: u8 = 13;
+    /// let mut y: u8 = 42;
+    ///
+    /// u8::conditional_swap(&mut x, &mut y, 0.into());
+    /// assert_eq!(x, 13);
+    /// assert_eq!(y, 42);
+    /// u8::conditional_swap(&mut x, &mut y, 1.into());
+    /// assert_eq!(x, 42);
+    /// assert_eq!(y, 13);
+    /// # }
+    /// ```
+    #[inline]
+    fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) {
+        let t: Self = *a;
+        a.conditional_assign(&b, choice);
+        b.conditional_assign(&t, choice);
+    }
+}
+
+macro_rules! to_signed_int {
+    (u8) => {
+        i8
+    };
+    (u16) => {
+        i16
+    };
+    (u32) => {
+        i32
+    };
+    (u64) => {
+        i64
+    };
+    (u128) => {
+        i128
+    };
+    (i8) => {
+        i8
+    };
+    (i16) => {
+        i16
+    };
+    (i32) => {
+        i32
+    };
+    (i64) => {
+        i64
+    };
+    (i128) => {
+        i128
+    };
+}
+
+macro_rules! generate_integer_conditional_select {
+    ($($t:tt)*) => ($(
+        impl ConditionallySelectable for $t {
+            #[inline]
+            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+                // if choice = 0, mask = (-0) = 0000...0000
+                // if choice = 1, mask = (-1) = 1111...1111
+                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
+                a ^ (mask & (a ^ b))
+            }
+
+            #[inline]
+            fn conditional_assign(&mut self, other: &Self, choice: Choice) {
+                // if choice = 0, mask = (-0) = 0000...0000
+                // if choice = 1, mask = (-1) = 1111...1111
+                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
+                *self ^= mask & (*self ^ *other);
+            }
+
+            #[inline]
+            fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) {
+                // if choice = 0, mask = (-0) = 0000...0000
+                // if choice = 1, mask = (-1) = 1111...1111
+                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
+                let t = mask & (*a ^ *b);
+                *a ^= t;
+                *b ^= t;
+            }
+         }
+    )*)
+}
+
+generate_integer_conditional_select!(  u8   i8);
+generate_integer_conditional_select!( u16  i16);
+generate_integer_conditional_select!( u32  i32);
+generate_integer_conditional_select!( u64  i64);
+#[cfg(feature = "i128")]
+generate_integer_conditional_select!(u128 i128);
+
+impl ConditionallySelectable for Choice {
+    #[inline]
+    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+        Choice(u8::conditional_select(&a.0, &b.0, choice))
+    }
+}
+
+/// A type which can be conditionally negated in constant time.
+///
+/// # Note
+///
+/// A generic implementation of `ConditionallyNegatable` is provided
+/// for types `T` which are `ConditionallySelectable` and have `Neg`
+/// implemented on `&T`.
+pub trait ConditionallyNegatable {
+    /// Negate `self` if `choice == Choice(1)`; otherwise, leave it
+    /// unchanged.
+    ///
+    /// This function should execute in constant time.
+    #[inline]
+    fn conditional_negate(&mut self, choice: Choice);
+}
+
+impl<T> ConditionallyNegatable for T
+where
+    T: ConditionallySelectable,
+    for<'a> &'a T: Neg<Output = T>,
+{
+    #[inline]
+    fn conditional_negate(&mut self, choice: Choice) {
+        // Need to cast to eliminate mutability
+        let self_neg: T = -(self as &T);
+        self.conditional_assign(&self_neg, choice);
+    }
+}
+
+/// The `CtOption<T>` type represents an optional value similar to the
+/// [`Option<T>`](core::option::Option) type but is intended for
+/// use in constant time APIs.
+///
+/// Any given `CtOption<T>` is either `Some` or `None`, but unlike
+/// `Option<T>` these variants are not exposed. The
+/// [`is_some()`](CtOption::is_some) method is used to determine if
+/// the value is `Some`, and [`unwrap_or()`](CtOption::unwrap_or) and
+/// [`unwrap_or_else()`](CtOption::unwrap_or_else) methods are
+/// provided to access the underlying value. The value can also be
+/// obtained with [`unwrap()`](CtOption::unwrap) but this will panic
+/// if it is `None`.
+///
+/// Functions that are intended to be constant time may not produce
+/// valid results for all inputs, such as square root and inversion
+/// operations in finite field arithmetic. Returning an `Option<T>`
+/// from these functions makes it difficult for the caller to reason
+/// about the result in constant time, and returning an incorrect
+/// value burdens the caller and increases the chance of bugs.
+#[derive(Clone, Copy, Debug)]
+pub struct CtOption<T> {
+    value: T,
+    is_some: Choice,
+}
+
+impl<T> From<CtOption<T>> for Option<T> {
+    /// Convert the `CtOption<T>` wrapper into an `Option<T>`, depending on whether
+    /// the underlying `is_some` `Choice` was a `0` or a `1` once unwrapped.
+    ///
+    /// # Note
+    ///
+    /// This function exists to avoid ending up with ugly, verbose and/or bad handled
+    /// conversions from the `CtOption<T>` wraps to an `Option<T>` or `Result<T, E>`.
+    /// This implementation doesn't intend to be constant-time nor try to protect the
+    /// leakage of the `T` since the `Option<T>` will do it anyways.
+    fn from(source: CtOption<T>) -> Option<T> {
+        if source.is_some().unwrap_u8() == 1u8 {
+            Option::Some(source.value)
+        } else {
+            None
+        }
+    }
+}
+
+impl<T> CtOption<T> {
+    /// This method is used to construct a new `CtOption<T>` and takes
+    /// a value of type `T`, and a `Choice` that determines whether
+    /// the optional value should be `Some` or not. If `is_some` is
+    /// false, the value will still be stored but its value is never
+    /// exposed.
+    #[inline]
+    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
+        CtOption {
+            value: value,
+            is_some: is_some,
+        }
+    }
+
+    /// This returns the underlying value but panics if it
+    /// is not `Some`.
+    #[inline]
+    pub fn unwrap(self) -> T {
+        assert_eq!(self.is_some.unwrap_u8(), 1);
+
+        self.value
+    }
+
+    /// This returns the underlying value if it is `Some`
+    /// or the provided value otherwise.
+    #[inline]
+    pub fn unwrap_or(self, def: T) -> T
+    where
+        T: ConditionallySelectable,
+    {
+        T::conditional_select(&def, &self.value, self.is_some)
+    }
+
+    /// This returns the underlying value if it is `Some`
+    /// or the value produced by the provided closure otherwise.
+    #[inline]
+    pub fn unwrap_or_else<F>(self, f: F) -> T
+    where
+        T: ConditionallySelectable,
+        F: FnOnce() -> T,
+    {
+        T::conditional_select(&f(), &self.value, self.is_some)
+    }
+
+    /// Returns a true `Choice` if this value is `Some`.
+    #[inline]
+    pub fn is_some(&self) -> Choice {
+        self.is_some
+    }
+
+    /// Returns a true `Choice` if this value is `None`.
+    #[inline]
+    pub fn is_none(&self) -> Choice {
+        !self.is_some
+    }
+
+    /// Returns a `None` value if the option is `None`, otherwise
+    /// returns a `CtOption` enclosing the value of the provided closure.
+    /// The closure is given the enclosed value or, if the option is
+    /// `None`, it is provided a dummy value computed using
+    /// `Default::default()`.
+    ///
+    /// This operates in constant time, because the provided closure
+    /// is always called.
+    #[inline]
+    pub fn map<U, F>(self, f: F) -> CtOption<U>
+    where
+        T: Default + ConditionallySelectable,
+        F: FnOnce(T) -> U,
+    {
+        CtOption::new(
+            f(T::conditional_select(
+                &T::default(),
+                &self.value,
+                self.is_some,
+            )),
+            self.is_some,
+        )
+    }
+
+    /// Returns a `None` value if the option is `None`, otherwise
+    /// returns the result of the provided closure. The closure is
+    /// given the enclosed value or, if the option is `None`, it
+    /// is provided a dummy value computed using `Default::default()`.
+    ///
+    /// This operates in constant time, because the provided closure
+    /// is always called.
+    #[inline]
+    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
+    where
+        T: Default + ConditionallySelectable,
+        F: FnOnce(T) -> CtOption<U>,
+    {
+        let mut tmp = f(T::conditional_select(
+            &T::default(),
+            &self.value,
+            self.is_some,
+        ));
+        tmp.is_some &= self.is_some;
+
+        tmp
+    }
+
+    /// Returns `self` if it contains a value, and otherwise returns the result of
+    /// calling `f`. The provided function `f` is always called.
+    #[inline]
+    pub fn or_else<F>(self, f: F) -> CtOption<T>
+    where
+        T: ConditionallySelectable,
+        F: FnOnce() -> CtOption<T>,
+    {
+        let is_none = self.is_none();
+        let f = f();
+
+        Self::conditional_select(&self, &f, is_none)
+    }
+}
+
+impl<T: ConditionallySelectable> ConditionallySelectable for CtOption<T> {
+    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+        CtOption::new(
+            T::conditional_select(&a.value, &b.value, choice),
+            Choice::conditional_select(&a.is_some, &b.is_some, choice),
+        )
+    }
+}
+
+impl<T: ConstantTimeEq> ConstantTimeEq for CtOption<T> {
+    /// Two `CtOption<T>`s are equal if they are both `Some` and
+    /// their values are equal, or both `None`.
+    #[inline]
+    fn ct_eq(&self, rhs: &CtOption<T>) -> Choice {
+        let a = self.is_some();
+        let b = rhs.is_some();
+
+        (a & b & self.value.ct_eq(&rhs.value)) | (!a & !b)
+    }
+}
+
+/// A type which can be compared in some manner and be determined to be greater
+/// than another of the same type.
+pub trait ConstantTimeGreater {
+    /// Determine whether `self > other`.
+    ///
+    /// The bitwise-NOT of the return value of this function should be usable to
+    /// determine if `self <= other`.
+    ///
+    /// This function should execute in constant time.
+    ///
+    /// # Returns
+    ///
+    /// A `Choice` with a set bit if `self > other`, and with no set bits
+    /// otherwise.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # extern crate subtle;
+    /// use subtle::ConstantTimeGreater;
+    ///
+    /// let x: u8 = 13;
+    /// let y: u8 = 42;
+    ///
+    /// let x_gt_y = x.ct_gt(&y);
+    ///
+    /// assert_eq!(x_gt_y.unwrap_u8(), 0);
+    ///
+    /// let y_gt_x = y.ct_gt(&x);
+    ///
+    /// assert_eq!(y_gt_x.unwrap_u8(), 1);
+    ///
+    /// let x_gt_x = x.ct_gt(&x);
+    ///
+    /// assert_eq!(x_gt_x.unwrap_u8(), 0);
+    /// ```
+    fn ct_gt(&self, other: &Self) -> Choice;
+}
+
+macro_rules! generate_unsigned_integer_greater {
+    ($t_u: ty, $bit_width: expr) => {
+        impl ConstantTimeGreater for $t_u {
+            /// Returns Choice::from(1) iff x > y, and Choice::from(0) iff x <= y.
+            ///
+            /// # Note
+            ///
+            /// This algoritm would also work for signed integers if we first
+            /// flip the top bit, e.g. `let x: u8 = x ^ 0x80`, etc.
+            #[inline]
+            fn ct_gt(&self, other: &$t_u) -> Choice {
+                let gtb = self & !other; // All the bits in self that are greater than their corresponding bits in other.
+                let mut ltb = !self & other; // All the bits in self that are less than their corresponding bits in other.
+                let mut pow = 1;
+
+                // Less-than operator is okay here because it's dependent on the bit-width.
+                while pow < $bit_width {
+                    ltb |= ltb >> pow; // Bit-smear the highest set bit to the right.
+                    pow += pow;
+                }
+                let mut bit = gtb & !ltb; // Select the highest set bit.
+                let mut pow = 1;
+
+                while pow < $bit_width {
+                    bit |= bit >> pow; // Shift it to the right until we end up with either 0 or 1.
+                    pow += pow;
+                }
+                // XXX We should possibly do the above flattening to 0 or 1 in the
+                //     Choice constructor rather than making it a debug error?
+                Choice::from((bit & 1) as u8)
+            }
+        }
+    }
+}
+
+generate_unsigned_integer_greater!(u8, 8);
+generate_unsigned_integer_greater!(u16, 16);
+generate_unsigned_integer_greater!(u32, 32);
+generate_unsigned_integer_greater!(u64, 64);
+#[cfg(feature = "i128")]
+generate_unsigned_integer_greater!(u128, 128);
+
+/// A type which can be compared in some manner and be determined to be less
+/// than another of the same type.
+pub trait ConstantTimeLess: ConstantTimeEq + ConstantTimeGreater {
+    /// Determine whether `self < other`.
+    ///
+    /// The bitwise-NOT of the return value of this function should be usable to
+    /// determine if `self >= other`.
+    ///
+    /// A default implementation is provided and implemented for the unsigned
+    /// integer types.
+    ///
+    /// This function should execute in constant time.
+    ///
+    /// # Returns
+    ///
+    /// A `Choice` with a set bit if `self < other`, and with no set bits
+    /// otherwise.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # extern crate subtle;
+    /// use subtle::ConstantTimeLess;
+    ///
+    /// let x: u8 = 13;
+    /// let y: u8 = 42;
+    ///
+    /// let x_lt_y = x.ct_lt(&y);
+    ///
+    /// assert_eq!(x_lt_y.unwrap_u8(), 1);
+    ///
+    /// let y_lt_x = y.ct_lt(&x);
+    ///
+    /// assert_eq!(y_lt_x.unwrap_u8(), 0);
+    ///
+    /// let x_lt_x = x.ct_lt(&x);
+    ///
+    /// assert_eq!(x_lt_x.unwrap_u8(), 0);
+    /// ```
+    #[inline]
+    fn ct_lt(&self, other: &Self) -> Choice {
+        !self.ct_gt(other) & !self.ct_eq(other)
+    }
+}
+
+impl ConstantTimeLess for u8 {}
+impl ConstantTimeLess for u16 {}
+impl ConstantTimeLess for u32 {}
+impl ConstantTimeLess for u64 {}
+#[cfg(feature = "i128")]
+impl ConstantTimeLess for u128 {}
diff -Nru cargo-0.66.0/vendor/subtle/tests/mod.rs cargo-0.66.0+ds1/vendor/subtle/tests/mod.rs
--- cargo-0.66.0/vendor/subtle/tests/mod.rs	1970-01-01 01:00:00.000000000 +0100
+++ cargo-0.66.0+ds1/vendor/subtle/tests/mod.rs	2023-01-11 18:41:02.000000000 +0100
@@ -0,0 +1,389 @@
+extern crate rand;
+extern crate subtle;
+
+use rand::rngs::OsRng;
+use rand::RngCore;
+
+use subtle::*;
+
+#[test]
+#[should_panic]
+fn slices_equal_different_lengths() {
+    let a: [u8; 3] = [0, 0, 0];
+    let b: [u8; 4] = [0, 0, 0, 0];
+
+    assert_eq!((&a).ct_eq(&b).unwrap_u8(), 1);
+}
+
+#[test]
+fn slices_equal() {
+    let a: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
+    let b: [u8; 8] = [1, 2, 3, 4, 4, 3, 2, 1];
+
+    let a_eq_a = (&a).ct_eq(&a);
+    let a_eq_b = (&a).ct_eq(&b);
+
+    assert_eq!(a_eq_a.unwrap_u8(), 1);
+    assert_eq!(a_eq_b.unwrap_u8(), 0);
+
+    let c: [u8; 16] = [0u8; 16];
+
+    let a_eq_c = (&a).ct_eq(&c);
+    assert_eq!(a_eq_c.unwrap_u8(), 0);
+}
+
+#[test]
+fn conditional_assign_i32() {
+    let mut a: i32 = 5;
+    let b: i32 = 13;
+
+    a.conditional_assign(&b, 0.into());
+    assert_eq!(a, 5);
+    a.conditional_assign(&b, 1.into());
+    assert_eq!(a, 13);
+}
+
+#[test]
+fn conditional_assign_i64() {
+    let mut c: i64 = 2343249123;
+    let d: i64 = 8723884895;
+
+    c.conditional_assign(&d, 0.into());
+    assert_eq!(c, 2343249123);
+    c.conditional_assign(&d, 1.into());
+    assert_eq!(c, 8723884895);
+}
+
+macro_rules! generate_integer_conditional_select_tests {
+    ($($t:ty)*) => ($(
+        let x: $t = 0;  // all 0 bits
+        let y: $t = !0; // all 1 bits
+
+        assert_eq!(<$t>::conditional_select(&x, &y, 0.into()), 0);
+        assert_eq!(<$t>::conditional_select(&x, &y, 1.into()), y);
+
+        let mut z = x;
+        let mut w = y;
+
+        <$t>::conditional_swap(&mut z, &mut w, 0.into());
+        assert_eq!(z, x);
+        assert_eq!(w, y);
+        <$t>::conditional_swap(&mut z, &mut w, 1.into());
+        assert_eq!(z, y);
+        assert_eq!(w, x);
+
+        z.conditional_assign(&x, 1.into());
+        w.conditional_assign(&y, 0.into());
+        assert_eq!(z, x);
+        assert_eq!(w, x);
+    )*)
+}
+
+#[test]
+fn integer_conditional_select() {
+    generate_integer_conditional_select_tests!(u8 u16 u32 u64);
+    generate_integer_conditional_select_tests!(i8 i16 i32 i64);
+    #[cfg(feature = "i128")]
+    generate_integer_conditional_select_tests!(i128 u128);
+}
+
+#[test]
+fn custom_conditional_select_i16() {
+    let x: i16 = 257;
+    let y: i16 = 514;
+
+    assert_eq!(i16::conditional_select(&x, &y, 0.into()), 257);
+    assert_eq!(i16::conditional_select(&x, &y, 1.into()), 514);
+}
+
+macro_rules! generate_integer_equal_tests {
+    ($($t:ty),*) => ($(
+        let y: $t = 0;  // all 0 bits
+        let z: $t = !0; // all 1 bits
+
+        let x = z;
+
+        assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
+        assert_eq!(x.ct_eq(&z).unwrap_u8(), 1);
+    )*)
+}
+
+#[test]
+fn integer_equal() {
+    generate_integer_equal_tests!(u8, u16, u32, u64);
+    generate_integer_equal_tests!(i8, i16, i32, i64);
+    #[cfg(feature = "i128")]
+    generate_integer_equal_tests!(i128, u128);
+    generate_integer_equal_tests!(isize, usize);
+}
+
+#[test]
+fn choice_into_bool() {
+    let choice_true: bool = Choice::from(1).into();
+
+    assert!(choice_true);
+
+    let choice_false: bool = Choice::from(0).into();
+
+    assert!(!choice_false);
+}
+
+#[test]
+fn conditional_select_choice() {
+    let t = Choice::from(1);
+    let f = Choice::from(0);
+
+    assert_eq!(bool::from(Choice::conditional_select(&t, &f, f)), true);
+    assert_eq!(bool::from(Choice::conditional_select(&t, &f, t)), false);
+    assert_eq!(bool::from(Choice::conditional_select(&f, &t, f)), false);
+    assert_eq!(bool::from(Choice::conditional_select(&f, &t, t)), true);
+}
+
+#[test]
+fn choice_equal() {
+    assert!(Choice::from(0).ct_eq(&Choice::from(0)).unwrap_u8() == 1);
+    assert!(Choice::from(0).ct_eq(&Choice::from(1)).unwrap_u8() == 0);
+    assert!(Choice::from(1).ct_eq(&Choice::from(0)).unwrap_u8() == 0);
+    assert!(Choice::from(1).ct_eq(&Choice::from(1)).unwrap_u8() == 1);
+}
+
+#[test]
+fn test_ctoption() {
+    let a = CtOption::new(10, Choice::from(1));
+    let b = CtOption::new(9, Choice::from(1));
+    let c = CtOption::new(10, Choice::from(0));
+    let d = CtOption::new(9, Choice::from(0));
+
+    // Test is_some / is_none
+    assert!(bool::from(a.is_some()));
+    assert!(bool::from(!a.is_none()));
+    assert!(bool::from(b.is_some()));
+    assert!(bool::from(!b.is_none()));
+    assert!(bool::from(!c.is_some()));
+    assert!(bool::from(c.is_none()));
+    assert!(bool::from(!d.is_some()));
+    assert!(bool::from(d.is_none()));
+
+    // Test unwrap for Some
+    assert_eq!(a.unwrap(), 10);
+    assert_eq!(b.unwrap(), 9);
+
+    // Test equality
+    assert!(bool::from(a.ct_eq(&a)));
+    assert!(bool::from(!a.ct_eq(&b)));
+    assert!(bool::from(!a.ct_eq(&c)));
+    assert!(bool::from(!a.ct_eq(&d)));
+
+    // Test equality of None with different
+    // dummy value
+    assert!(bool::from(c.ct_eq(&d)));
+
+    // Test unwrap_or
+    assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or(2), 1);
+    assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or(2), 2);
+
+    // Test unwrap_or_else
+    assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or_else(|| 2), 1);
+    assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or_else(|| 2), 2);
+
+    // Test map
+    assert_eq!(
+        CtOption::new(1, Choice::from(1))
+            .map(|v| {
+                assert_eq!(v, 1);
+                2
+            })
+            .unwrap(),
+        2
+    );
+    assert_eq!(
+        CtOption::new(1, Choice::from(0))
+            .map(|_| 2)
+            .is_none()
+            .unwrap_u8(),
+        1
+    );
+
+    // Test and_then
+    assert_eq!(
+        CtOption::new(1, Choice::from(1))
+            .and_then(|v| {
+                assert_eq!(v, 1);
+                CtOption::new(2, Choice::from(0))
+            })
+            .is_none()
+            .unwrap_u8(),
+        1
+    );
+    assert_eq!(
+        CtOption::new(1, Choice::from(1))
+            .and_then(|v| {
+                assert_eq!(v, 1);
+                CtOption::new(2, Choice::from(1))
+            })
+            .unwrap(),
+        2
+    );
+
+    assert_eq!(
+        CtOption::new(1, Choice::from(0))
+            .and_then(|_| CtOption::new(2, Choice::from(0)))
+            .is_none()
+            .unwrap_u8(),
+        1
+    );
+    assert_eq!(
+        CtOption::new(1, Choice::from(0))
+            .and_then(|_| CtOption::new(2, Choice::from(1)))
+            .is_none()
+            .unwrap_u8(),
+        1
+    );
+
+    // Test or_else
+    assert_eq!(
+        CtOption::new(1, Choice::from(0))
+            .or_else(|| CtOption::new(2, Choice::from(1)))
+            .unwrap(),
+        2
+    );
+    assert_eq!(
+        CtOption::new(1, Choice::from(1))
+            .or_else(|| CtOption::new(2, Choice::from(0)))
+            .unwrap(),
+        1
+    );
+    assert_eq!(
+        CtOption::new(1, Choice::from(1))
+            .or_else(|| CtOption::new(2, Choice::from(1)))
+            .unwrap(),
+        1
+    );
+    assert!(bool::from(
+        CtOption::new(1, Choice::from(0))
+            .or_else(|| CtOption::new(2, Choice::from(0)))
+            .is_none()
+    ));
+
+    // Test (in)equality
+    assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 0);
+    assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 0);
+    assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
+    assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 0);
+    assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 1);
+    assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 1);
+    assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
+    assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
+    assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1);
+    assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1);
+}
+
+#[test]
+#[should_panic]
+fn unwrap_none_ctoption() {
+    // This test might fail (in release mode?) if the
+    // compiler decides to optimize it away.
+    CtOption::new(10, Choice::from(0)).unwrap();
+}
+
+macro_rules! generate_greater_than_test {
+    ($ty: ty) => {
+        for _ in 0..100 {
+            let x = OsRng.next_u64() as $ty;
+            let y = OsRng.next_u64() as $ty;
+            let z = x.ct_gt(&y);
+
+            println!("x={}, y={}, z={:?}", x, y, z);
+
+            if x < y {
+                assert!(z.unwrap_u8() == 0);
+            } else if x == y {
+                assert!(z.unwrap_u8() == 0);
+            } else if x > y {
+                assert!(z.unwrap_u8() == 1);
+            }
+        }
+    }
+}
+
+#[test]
+fn greater_than_u8() {
+    generate_greater_than_test!(u8);
+}
+
+#[test]
+fn greater_than_u16() {
+    generate_greater_than_test!(u16);
+}
+
+#[test]
+fn greater_than_u32() {
+    generate_greater_than_test!(u32);
+}
+
+#[test]
+fn greater_than_u64() {
+    generate_greater_than_test!(u64);
+}
+
+#[cfg(feature = "i128")]
+#[test]
+fn greater_than_u128() {
+    generate_greater_than_test!(u128);
+}
+
+#[test]
+/// Test that the two's compliment min and max, i.e. 0000...0001 < 1111...1110,
+/// gives the correct result. (This fails using the bit-twiddling algorithm that
+/// go/crypto/subtle uses.)
+fn less_than_twos_compliment_minmax() {
+    let z = 1u32.ct_lt(&(2u32.pow(31)-1));
+
+    assert!(z.unwrap_u8() == 1);
+}
+
+macro_rules! generate_less_than_test {
+    ($ty: ty) => {
+        for _ in 0..100 {
+            let x = OsRng.next_u64() as $ty;
+            let y = OsRng.next_u64() as $ty;
+            let z = x.ct_gt(&y);
+
+            println!("x={}, y={}, z={:?}", x, y, z);
+
+            if x < y {
+                assert!(z.unwrap_u8() == 0);
+            } else if x == y {
+                assert!(z.unwrap_u8() == 0);
+            } else if x > y {
+                assert!(z.unwrap_u8() == 1);
+            }
+        }
+    }
+}
+
+#[test]
+fn less_than_u8() {
+    generate_less_than_test!(u8);
+}
+
+#[test]
+fn less_than_u16() {
+    generate_less_than_test!(u16);
+}
+
+#[test]
+fn less_than_u32() {
+    generate_less_than_test!(u32);
+}
+
+#[test]
+fn less_than_u64() {
+    generate_less_than_test!(u64);
+}
+
+#[cfg(feature = "i128")]
+#[test]
+fn less_than_u128() {
+    generate_less_than_test!(u128);
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-rust-maintainers/attachments/20230112/facb1380/attachment-0001.sig>


More information about the Pkg-rust-maintainers mailing list