Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reject weak keys (SHA-1 signature) in admin gpg-validate script #6928

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions admin/bin/validate-gpg-key.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ declare -r fingerprint="$2"
printf "Creating temporary GPG config dir for testing key import...\n"
temporary_gpg_homedir="$(mktemp -d)"
export GNUPGHOME="${temporary_gpg_homedir}"
export KEY_MISMATCH=11
export SQLINT_FAIL=12


function cleanup_temporary_gpg_homedir() {
Expand All @@ -34,10 +36,19 @@ function cleanup_temporary_gpg_homedir() {
}

function report_error() {
printf "Failed! Specified fingerprint does NOT match pubkey file.\n"
exit 1
if [[ $1 -eq $KEY_MISMATCH ]]; then
printf "Failed! Specified fingerprint does NOT match pubkey file.\n"
exit 1
elif [[ $1 -eq $SQLINT_FAIL ]]; then
printf "Failed! Fingerprint matches but key failed sq-keyring-linter.\n"
exit 2
else
printf "Failed! Specified fingerprint has failed validation.\n"
exit 3
fi
}


# Declare traps for cleanup operations. Regardless of exit code, clean up
# temporary directory, so we don't clutter up /tmp with extraneous directories.
trap cleanup_temporary_gpg_homedir EXIT
Expand All @@ -58,7 +69,20 @@ printf "Validating fingerprint and public key key match...\n"
printf "\t Public key: %s\n" "${key_location}"
printf "\t Fingerprint: %s\n" "${fingerprint}"

gpg2 --fingerprint "$fingerprint"
gpg2 --fingerprint "$fingerprint" || report_error $KEY_MISMATCH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns positive for cases where the supplied fingerprint is truncated by 1 char.


# Opportunistically validate against Seqouia's key linter, which checks whether
# OpenPGP certificates use a SHA-1 based binding signature
# (see https://sequoia-pgp.org/blog/2023/02/01/202302-happy-sha1-day/).
# Note: it is possible that the key has been updated on another admin workstation,
rocodes marked this conversation as resolved.
Show resolved Hide resolved
# but the updated pubkey has not been transferred to this workstation.
if [[ $(dpkg-query -W -f='${Status}' sq-keyring-linter) == "install ok installed" ]]; then
printf "Validating that key is supported...\n"
gpg2 --export "$fingerprint" | sq-keyring-linter || report_error $SQLINT_FAIL
else
printf "Warning: sq-keyring-linter package is missing. "
printf "Key validation checks will be limited without it.\n"
fi

printf "Success! Specified fingerprint matches pubkey file.\n"
exit 0
59 changes: 48 additions & 11 deletions admin/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
DIR = os.path.dirname(os.path.realpath(__file__))
VENV_DIR = os.path.join(DIR, ".venv3")

# Space-separated list of apt dependencies
APT_DEPENDENCIES_STR = "python3-virtualenv \
python3-yaml \
python3-pip \
virtualenv \
libffi-dev \
libssl-dev \
libpython3-dev \
sq-keyring-linter"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(dependencies refactored from line 120)


def setup_logger(verbose: bool = False) -> None:
"""Configure logging handler"""
Expand Down Expand Up @@ -95,6 +105,37 @@ def checkenv(args: argparse.Namespace) -> None:
sys.exit(1)


def is_missing_dependency() -> bool:
"""
Check if there are any missing apt dependencies.
This applies to existing Tails systems where `securedrop-setup` may not have been
run recently.
"""
# apt-cache -q0 policy $dependency1 $dependency2 $dependency3 | grep "Installed: (none)"
apt_query = f"apt-cache -q0 policy {APT_DEPENDENCIES_STR}".split(" ")
grep_command = ["grep", "Installed: (none)"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zenmonkeykstop if the admin workstation has all the right dependencies, is_missing_dependency won't prompt for sudo or do any network calls.

If a package name changes (eg sq-keyring-linter gets replaced by sq), this still won't try and install sq-keyring-linter, because the apt-cache policy results wont be Installed: (none), they'll be N: unable to locate package $funnyname.

If you're not a fan, let me know and we can at least move the check into the branch of envsetup where no existing venv is detected.


try:
sdlog.info("Checking apt dependencies are installed")
apt_process = subprocess.Popen(apt_query, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

grep_process = subprocess.Popen(
grep_command, stdin=apt_process.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

# Wait for the process to complete before checking the returncode
grep_process.communicate()
returncode = grep_process.returncode

# If the above command returns 0, then one or more packages are not installed.
return returncode == 0

except subprocess.CalledProcessError as e:
sdlog.error("Error checking apt dependencies")
sdlog.debug(e.output)
raise


def maybe_torify() -> List[str]:
if is_tails():
return ["torify"]
Expand All @@ -117,22 +158,16 @@ def install_apt_dependencies(args: argparse.Namespace) -> None:
"sudo",
"su",
"-c",
"apt-get update && \
apt-get -q -o=Dpkg::Use-Pty=0 install -y \
python3-virtualenv \
python3-yaml \
python3-pip \
virtualenv \
libffi-dev \
libssl-dev \
libpython3-dev",
f"apt-get update && \
apt-get -q -o=Dpkg::Use-Pty=0 install -y {APT_DEPENDENCIES_STR}",
]

try:
# Print command results in real-time, to keep Admin apprised
# of progress during long-running command.
for output_line in run_command(apt_command):
print(output_line.decode("utf-8").rstrip())

except subprocess.CalledProcessError:
# Tails supports apt persistence, which was used by SecureDrop
# under Tails 2.x. If updates are being applied, don't try to pile
Expand All @@ -158,11 +193,13 @@ def envsetup(args: argparse.Namespace, virtualenv_dir: str = VENV_DIR) -> None:
# clean up old Tails venv on major upgrades
clean_up_old_tails_venv(virtualenv_dir)

# Check apt dependencies and ensure all are present.
if is_missing_dependency():
install_apt_dependencies(args)

# virtualenv doesnt exist? Install dependencies and create
if not os.path.exists(virtualenv_dir):

install_apt_dependencies(args)

# Technically you can create a virtualenv from within python
# but pip can only be run over Tor on Tails, and debugging that
# along with instaling a third-party dependency is not worth
Expand Down
22 changes: 17 additions & 5 deletions admin/securedrop_admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,11 +599,23 @@ def validate_gpg_keys(self) -> bool:
)
except subprocess.CalledProcessError as e:
sdlog.debug(e.output)
raise FingerprintException(
f"fingerprint {fingerprint} "
+ "does not match "
+ f"the public key {public_key}"
)
message = f"{fingerprint}: Fingerprint validation failed"
rocodes marked this conversation as resolved.
Show resolved Hide resolved

# The validation script returns different error codes depending on what
# the cause of the validation failure was. See `admin/bin/validate-gpg-key.sh`
if e.returncode == 1:
message = (
f"fingerprint {fingerprint} does not match "
+ f"the public key {public_key}"
)
elif e.returncode == 2:
message = (
f"fingerprint {fingerprint} "
+ "failed sq-keyring-linter check. You may be using an older key that "
+ "needs to be updated. Please contact your SecureDrop administrator, or "
+ "https://support.freedom.press for assistance."
)
raise FingerprintException(message)
return True

def validate_journalist_alert_email(self) -> bool:
Expand Down
77 changes: 52 additions & 25 deletions admin/tests/files/ossec.pub
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.19 (GNU/Linux)

mQINBFJZi2ABEACZJJA53+pEAdkZyD99nxB995ZVTBw60SQ/6E/gws4kInv+YS7t
wSMXGa5bR4SD9voWxzLgyulqbM93jUFKn5GcsSh2O/lxAvEDKsPmXCRP1eBg3pjU
Expand All @@ -25,28 +24,56 @@ iNl4NCgd26iRgTLhfMXpTjRyOb2RvFdzLByDEWIbvu5kCh247UFYSL0llk+suNh3
cm0mOUdL1nZuEo4EyEF1dq+1opMfDMF98q0660wZdwvwUQIXBt/yK3FH0BGA66ai
R78Z4pH1JqtYvzfDJx+XP8O2N9GYGd7kpak/5C2BTJzLVyzagB1yi8SmiYna5yQj
EqW5Txeq0GGd2H4KtUETUevU4x0Rw3luHToaDd9d5sioF48o87PlGwk+OCofPfLj
LnwFPNZcuQINBFJZi2ABEADzfv+9Ogb4KEWFom9zMF+xg8bcd/Ct72/sWLQW6Pz6
+SkmLEHuklTO+k7xiQ6jdzXzj1rTfy317L7G51naBSb6Ekfv8mu2ogOwrvtgYnGC
vfCpooUSxcfi+aEJzIJL29TAi1RCLZm15KRbkvEl8wS93BSLiag5w4/8eP1vXebq
95GrCZwiNZdhdQs3qn4j3VRvTW/SZHIAdJY+mMfUMPjq4c4sA82os6kVrEnWeLGf
T9d+knfm9J/2Rumy90bLAY6SFmRZ9/DxwKwbIsVy8CRvU3RVFSX8HCBQepRCQkls
9r7KVBqYE2Wh+0a+9wHHHNI7VBxKGXPflrirxY1AB5vjLcX1hmXbCoyf4ytgdHyC
KDz9Oc+xkgJeyVW6XwSqc5EhuNFXp3+C7BF7eQZ1REJLbL6CtEkeF0jHBaTeKM/p
N4fVhjPiU/FsNmZGKxxLyxDnnDI5pY8bhphVxwBRZ5GtVNqiVNDw+rRACQalpT21
OcAgLP+Rz+qf3TPyEZN6WPEx8/76ILuSHb8mpOH7W/514f5NuFaAlgmUnO3cT10h
h4IwOQ+kvj0qMww8fASI9DJExXUYb3xDSCmOkJPhu1/Drr3gdFBha4/jAz7jBWls
Vr2RLJzilf8Mi9j8WpHIfP+WXtwWz3+iYPS0SPoB7g9DA0+Ei760pJJf73AEjD+f
FwARAQABiQIfBBgBAgAJBQJSWYtgAhsMAAoJEMxA7xIoJxRBp/cP/3lJx9z5yzZA
6UvLQR6pK+V1iy2hvZ+S+EwYRCiTgYTXekHzLXWwjWGfUYDTHMeaS9O9BMRMGOU3
inyb47GZSoQ0N0bRVTzrY6/0ifhUSJ00MemOodI1bz4pAMk3uR8iWyhlaGn7JAIA
KmCm+K0qkeJd61S9iyrx7s9QmaNPnupm5pc+bpOAkbKyq7sEFpWM5Qx82n1tVMtn
IW2OoRPbz80JkkQB2pl6SjskXqZ89jcFWGI6IChYENKc65xafDt4uFuHU+5j4j2f
4ySYSwfoWC97MOgJLqA/WimxeeNCYFhykUDWrL5mKBTgMXgH/sYk3GDo7fssaYbK
n1xbbX4GXQl3+ru4zT6/F7CxZErjLb+evShyf4itM+5AdbKRiRzoraqKblBa4TfJ
BSqHisdcxdZeBe19+jyY6a8ZMcGhrQeksiKxTRh7ylAk7CLVgLEIHLxXzHoZ0oAF
z2ulG+zH9KS9Pe8MQxHCrlyfoQElQuJoYbrYBOu28itvGPgz6+5xgvZROvPoqIkI
k8DYt9lJqUFBeZuFJd5W1TuHKLxueVYvSKeG+e3TjOYdJFvDZInM4cNWr8N92mYS
iphljiHAKVTQeIf1ma07QUH/ul3YC+g07F+BLonIIXA6uQVebv5iLxTgOzIQwHTJ
Vu4MPiQNn1h4dk1RonfV/aJ+de1+qjA8
=XVz8
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
caA76EYZ2Htu8g==
=LPJh
-----END PGP PUBLIC KEY BLOCK-----
77 changes: 52 additions & 25 deletions admin/tests/files/test_journalist_key.pub
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.19 (GNU/Linux)

mQINBFJZi2ABEACZJJA53+pEAdkZyD99nxB995ZVTBw60SQ/6E/gws4kInv+YS7t
wSMXGa5bR4SD9voWxzLgyulqbM93jUFKn5GcsSh2O/lxAvEDKsPmXCRP1eBg3pjU
Expand All @@ -25,28 +24,56 @@ iNl4NCgd26iRgTLhfMXpTjRyOb2RvFdzLByDEWIbvu5kCh247UFYSL0llk+suNh3
cm0mOUdL1nZuEo4EyEF1dq+1opMfDMF98q0660wZdwvwUQIXBt/yK3FH0BGA66ai
R78Z4pH1JqtYvzfDJx+XP8O2N9GYGd7kpak/5C2BTJzLVyzagB1yi8SmiYna5yQj
EqW5Txeq0GGd2H4KtUETUevU4x0Rw3luHToaDd9d5sioF48o87PlGwk+OCofPfLj
LnwFPNZcuQINBFJZi2ABEADzfv+9Ogb4KEWFom9zMF+xg8bcd/Ct72/sWLQW6Pz6
+SkmLEHuklTO+k7xiQ6jdzXzj1rTfy317L7G51naBSb6Ekfv8mu2ogOwrvtgYnGC
vfCpooUSxcfi+aEJzIJL29TAi1RCLZm15KRbkvEl8wS93BSLiag5w4/8eP1vXebq
95GrCZwiNZdhdQs3qn4j3VRvTW/SZHIAdJY+mMfUMPjq4c4sA82os6kVrEnWeLGf
T9d+knfm9J/2Rumy90bLAY6SFmRZ9/DxwKwbIsVy8CRvU3RVFSX8HCBQepRCQkls
9r7KVBqYE2Wh+0a+9wHHHNI7VBxKGXPflrirxY1AB5vjLcX1hmXbCoyf4ytgdHyC
KDz9Oc+xkgJeyVW6XwSqc5EhuNFXp3+C7BF7eQZ1REJLbL6CtEkeF0jHBaTeKM/p
N4fVhjPiU/FsNmZGKxxLyxDnnDI5pY8bhphVxwBRZ5GtVNqiVNDw+rRACQalpT21
OcAgLP+Rz+qf3TPyEZN6WPEx8/76ILuSHb8mpOH7W/514f5NuFaAlgmUnO3cT10h
h4IwOQ+kvj0qMww8fASI9DJExXUYb3xDSCmOkJPhu1/Drr3gdFBha4/jAz7jBWls
Vr2RLJzilf8Mi9j8WpHIfP+WXtwWz3+iYPS0SPoB7g9DA0+Ei760pJJf73AEjD+f
FwARAQABiQIfBBgBAgAJBQJSWYtgAhsMAAoJEMxA7xIoJxRBp/cP/3lJx9z5yzZA
6UvLQR6pK+V1iy2hvZ+S+EwYRCiTgYTXekHzLXWwjWGfUYDTHMeaS9O9BMRMGOU3
inyb47GZSoQ0N0bRVTzrY6/0ifhUSJ00MemOodI1bz4pAMk3uR8iWyhlaGn7JAIA
KmCm+K0qkeJd61S9iyrx7s9QmaNPnupm5pc+bpOAkbKyq7sEFpWM5Qx82n1tVMtn
IW2OoRPbz80JkkQB2pl6SjskXqZ89jcFWGI6IChYENKc65xafDt4uFuHU+5j4j2f
4ySYSwfoWC97MOgJLqA/WimxeeNCYFhykUDWrL5mKBTgMXgH/sYk3GDo7fssaYbK
n1xbbX4GXQl3+ru4zT6/F7CxZErjLb+evShyf4itM+5AdbKRiRzoraqKblBa4TfJ
BSqHisdcxdZeBe19+jyY6a8ZMcGhrQeksiKxTRh7ylAk7CLVgLEIHLxXzHoZ0oAF
z2ulG+zH9KS9Pe8MQxHCrlyfoQElQuJoYbrYBOu28itvGPgz6+5xgvZROvPoqIkI
k8DYt9lJqUFBeZuFJd5W1TuHKLxueVYvSKeG+e3TjOYdJFvDZInM4cNWr8N92mYS
iphljiHAKVTQeIf1ma07QUH/ul3YC+g07F+BLonIIXA6uQVebv5iLxTgOzIQwHTJ
Vu4MPiQNn1h4dk1RonfV/aJ+de1+qjA8
=XVz8
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
caA76EYZ2Htu8g==
=LPJh
-----END PGP PUBLIC KEY BLOCK-----
20 changes: 20 additions & 0 deletions admin/tests/files/weak_test_key_should_fail_sqlinter.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

mI0EZOPgWwEEALRtUxob9g8IYRBVGZfsIM79e7OuqCUNnnpcNkNZ4tiKyd8yjjfD
2t4OZ5WAv7VuseDThwGnDoCUJ3ZZXtKTtJITtYvtHsQox3BZoz5wSWRSJDO8npKU
Zv0j7Dy8uqv0n69J402+3Fq9mELyekH9/j29UqLdUTzRQgH+ZkXAH27DABEBAAG0
O0JBREtFWSAoU2hvdWxkIGZhaWwgc3Eta2V5cmluZy1saW50ZXIpIDxCQURLRVlA
Tk9SRVBMWS5ORVQ+iM4EEwEKADgWIQRA8cF7fngm2rQLFK53hrAA5tCnbgUCZOPg
WwIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRB3hrAA5tCnboiIA/oDjkPm
fhg9/2XdylpdB0WhY55vNLweSyQW6tWEgoL4IMl2HJx38WiMsNbqgWfsw/cLHrRW
eQfPJiB4n8jbucSFmutO9nlKT+yN/G1eVrSikz0nZ4OlLtW5Jy2T70LVzo3Lb6fE
Ve9zkVp+AaOxgsxlLj8aEX8E9tdD7EdmMKSJIbiNBGTj4FsBBACt+L8aGNutQfqK
iqqtwncUGBWdXNZgy+2SCmNF6QGwj0m8AlgBjERfbeBcYo3Mw2PIPM1r5UlXFiMy
blF32L7kZGxy5ETYaADHilGoJHCubtpBH4hDRsmt9OKydFSQvE01+CHLmAfiXBzx
KK48B2nVTseLIPhdxOW15GGd9QwLNwARAQABiLYEGAEKACAWIQRA8cF7fngm2rQL
FK53hrAA5tCnbgUCZOPgWwIbDAAKCRB3hrAA5tCnbqQ1A/9JSda8nzav4lgBw8co
dbB0s9AdvGymtlTWLUFdfHRaNYwHInUtXIagDhgJNLaa75xd/WNLvvjPcV3SoaOC
hGVDM/BkMb87VxjeYgHzKdN5MxMrPvITS5Y0EGB0ITvG1MTqHWalhY99pyRqeCRA
2BWLtQSMMPWQxML48db4EtfTQw==
=rpbe
-----END PGP PUBLIC KEY BLOCK-----
15 changes: 15 additions & 0 deletions admin/tests/test_securedrop-admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,21 @@ def test_validate_gpg_key(self, tmpdir, caplog):
site_config.validate_gpg_keys()
assert "FAIL does not match" in str(e)

# Test a key with matching fingerprint but that fails sq-keyring-linter
invalid_config = {
# Correct key fingerprint but weak 1024-bit RSA key with SHA-1 self signature
"securedrop_app_gpg_public_key": "weak_test_key_should_fail_sqlinter.asc",
"securedrop_app_gpg_fingerprint": "40F1C17B7E7826DAB40B14AE7786B000E6D0A76E",
"ossec_alert_gpg_public_key": "test_journalist_key.pub",
"ossec_gpg_fpr": "65A1B5FF195B56353CC63DFFCC40EF1228271441",
"journalist_alert_gpg_public_key": "test_journalist_key.pub",
"journalist_gpg_fpr": "65A1B5FF195B56353CC63DFFCC40EF1228271441",
}
site_config.config = invalid_config
with pytest.raises(securedrop_admin.FingerprintException) as e:
site_config.validate_gpg_keys()
assert "failed sq-keyring-linter check" in str(e)

def test_journalist_alert_email(self, tmpdir):
args = argparse.Namespace(
site_config="INVALID",
Expand Down
Loading