summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2019-02-01 14:40:06 +0000
committerJulian Andres Klode <jak@debian.org>2019-02-01 14:40:06 +0000
commitd5dcc2e9d3008b57c3fae0bcb5b1c2a197f5430c (patch)
tree18472bd719bbd40e687d58f09c578382ae6a72ac /test
parentb358bd64fc537de4e25c25b79de87346ec51a50c (diff)
parent8aa2053368d1bb82755164eaa36a10410b434c7c (diff)
downloadapt-d5dcc2e9d3008b57c3fae0bcb5b1c2a197f5430c.tar.gz
Merge branch 'pu/refuseunsignedlines' into 'master'
Fail if InRelease or Release.gpg contain unsigned lines See merge request apt-team/apt!45
Diffstat (limited to 'test')
-rwxr-xr-xtest/integration/test-apt-extracttemplates7
-rwxr-xr-xtest/integration/test-cve-2013-1051-InRelease-parsing7
-rwxr-xr-xtest/integration/test-cve-2019-3462-Release.gpg-payload43
-rwxr-xr-xtest/integration/test-method-gpgv48
-rw-r--r--test/libapt/openmaybeclearsignedfile_test.cc164
5 files changed, 225 insertions, 44 deletions
diff --git a/test/integration/test-apt-extracttemplates b/test/integration/test-apt-extracttemplates
index 9b07ef79f..a47257cfd 100755
--- a/test/integration/test-apt-extracttemplates
+++ b/test/integration/test-apt-extracttemplates
@@ -44,6 +44,13 @@ Description: Some bar var
testfileequal "$TEMPLATE" "$TEMPLATE_STR"
CONFIG=$(cut -f4 -d' ' $OUT)
testfileequal "$CONFIG" "$CONFIG_STR"
+ msgtest 'No extra files or directories in extraction directory'
+ if [ "$(find ./extracttemplates-out | wc -l)" = '3' ]; then
+ msgpass
+ else
+ msgfail
+ ls -l ./extracttemplates-out
+ fi
# ensure that the format of the output string has the right number of dots
for s in "$CONFIG" "$TEMPLATE"; do
diff --git a/test/integration/test-cve-2013-1051-InRelease-parsing b/test/integration/test-cve-2013-1051-InRelease-parsing
index 6238057c3..1f0cbda04 100755
--- a/test/integration/test-cve-2013-1051-InRelease-parsing
+++ b/test/integration/test-cve-2013-1051-InRelease-parsing
@@ -46,9 +46,12 @@ touch -d '+1hour' aptarchive/dists/stable/InRelease
listcurrentlistsdirectory | sed '/_InRelease/ d' > listsdir.lst
msgtest 'apt-get update should ignore unsigned data in the' 'InRelease'
testwarningequal "Get:1 http://localhost:${APTHTTPPORT} stable InRelease [$(stat -c%s aptarchive/dists/stable/InRelease) B]
+Err:1 http://localhost:${APTHTTPPORT} stable InRelease
+ Splitting up ${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial/localhost:${APTHTTPPORT}_dists_stable_InRelease into data and signature failed
Reading package lists...
-W: Clearsigned file '${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial/localhost:${APTHTTPPORT}_dists_stable_InRelease' contains unsigned lines.
-W: Clearsigned file '${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/localhost:${APTHTTPPORT}_dists_stable_InRelease' contains unsigned lines." --nomsg aptget update
+W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://localhost:${APTHTTPPORT} stable InRelease: Splitting up ${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial/localhost:${APTHTTPPORT}_dists_stable_InRelease into data and signature failed
+W: Failed to fetch http://localhost:${APTHTTPPORT}/dists/stable/InRelease Splitting up ${TMPWORKINGDIRECTORY}/rootdir/var/lib/apt/lists/partial/localhost:${APTHTTPPORT}_dists_stable_InRelease into data and signature failed
+W: Some index files failed to download. They have been ignored, or old ones used instead." --nomsg aptget update
testfileequal './listsdir.lst' "$(listcurrentlistsdirectory | sed '/_InRelease/ d')"
# ensure there is no package
diff --git a/test/integration/test-cve-2019-3462-Release.gpg-payload b/test/integration/test-cve-2019-3462-Release.gpg-payload
new file mode 100755
index 000000000..fd0f96713
--- /dev/null
+++ b/test/integration/test-cve-2019-3462-Release.gpg-payload
@@ -0,0 +1,43 @@
+#!/bin/sh
+set -e
+
+# This is not covered by the CVE and harmless by itself, but used in
+# the exploit and while harmless it is also pointless to allow it
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+
+setupenvironment
+configarchitecture 'amd64'
+
+export APT_DONT_SIGN='InRelease'
+
+insertpackage 'unstable' 'foo' 'all' '1'
+setupaptarchive
+rm -rf rootdir/var/lib/apt/lists
+
+verify() {
+ testfailure apt update
+ testsuccess grep '^ Detached signature file' rootdir/tmp/testfailure.output
+ testfailure apt show foo
+}
+
+msgmsg 'Payload after detached signature'
+find aptarchive -name 'Release.gpg' | while read FILE; do
+ cp -a "$FILE" "${FILE}.bak"
+ echo "evil payload" >> "$FILE"
+done
+verify
+
+msgmsg 'Payload in-between detached signatures'
+find aptarchive -name 'Release.gpg' | while read FILE; do
+ cat "${FILE}.bak" >> "$FILE"
+done
+verify
+
+msgmsg 'Payload before detached signature'
+find aptarchive -name 'Release.gpg' | while read FILE; do
+ echo "evil payload" > "$FILE"
+ cat "${FILE}.bak" >> "$FILE"
+done
+verify
diff --git a/test/integration/test-method-gpgv b/test/integration/test-method-gpgv
index 70521881d..bfa5af4c2 100755
--- a/test/integration/test-method-gpgv
+++ b/test/integration/test-method-gpgv
@@ -71,44 +71,60 @@ testrun() {
[GNUPG:] VALIDSIG 891CC50E605796A0C6E733F74BC0A39C27CE74F9 2016-09-01 1472742629 0 4 0 1 11 00 891CC50E605796A0C6E733F74BC0A39C27CE74F9'
}
+echo 'Test' > message.data
+cat >message.sig <<EOF
+-----BEGIN PGP SIGNATURE-----
+
+iQFEBAEBCgAuFiEENKjp0Y2zIPNn6OqgWpDRQdusja4FAlhT7+kQHGpvZUBleGFt
+cGxlLm9yZwAKCRBakNFB26yNrjvEB/9/e3jA1l0fvPafx9LEXcH8CLpUFQK7ra9l
+3M4YAH4JKQlTG1be7ixruBRlCTh3YiSs66fKMeJeUYoxA2HPhvbGFEjQFAxunEYg
+X/LBKv1mQWa+Q34P5GBjK8kQdLCN+yJAiUErmWNQG3GPninrxsC9tY5jcWvHeP1k
+V7N3MLnNqzXaCJM24mnKidC5IDadUdQ8qC8c3rjUexQ8vBz0eucH56jbqV5oOcvx
+pjlW965dCPIf3OI8q6J7bIOjyY+u/PTcVlqPq3TUz/ti6RkVbKpLH0D4ll3lUTns
+JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq
+=TB1F
+-----END PGP SIGNATURE-----
+EOF
+
+
gpgvmethod() {
- echo '601 Configuration
+ echo "601 Configuration
Config-Item: Debug::Acquire::gpgv=1
Config-Item: Dir::Bin::apt-key=./faked-apt-key
Config-Item: APT::Hashes::SHA1::Weak=true
600 URI Acquire
-URI: file:///dev/null
-Filename: /dev/zero
-' | runapt "${METHODSDIR}/gpgv"
+URI: file://${TMPWORKINGDIRECTORY}/message.sig
+Filename: ${TMPWORKINGDIRECTORY}/message.data
+" | runapt "${METHODSDIR}/gpgv"
}
testrun
gpgvmethod() {
- echo '601 Configuration
+ echo "601 Configuration
Config-Item: Debug::Acquire::gpgv=1
Config-Item: Dir::Bin::apt-key=./faked-apt-key
Config-Item: APT::Hashes::SHA1::Weak=true
600 URI Acquire
-URI: file:///dev/null
-Filename: /dev/zero
+URI: file://${TMPWORKINGDIRECTORY}/message.sig
+Filename: ${TMPWORKINGDIRECTORY}/message.data
Signed-By: /dev/null,34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE
-' | runapt "${METHODSDIR}/gpgv"
+" | runapt "${METHODSDIR}/gpgv"
}
testrun
gpgvmethod() {
- echo '601 Configuration
+ echo "601 Configuration
Config-Item: Debug::Acquire::gpgv=1
Config-Item: Dir::Bin::apt-key=./faked-apt-key
Config-Item: APT::Hashes::SHA1::Weak=true
600 URI Acquire
-URI: file:///dev/null
-Filename: /dev/zero
+URI: file://${TMPWORKINGDIRECTORY}/message.sig
+Filename: ${TMPWORKINGDIRECTORY}/message.data
Signed-By: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE,/dev/null
-' | runapt "${METHODSDIR}/gpgv"
+" | runapt "${METHODSDIR}/gpgv"
}
testrun
@@ -122,16 +138,16 @@ testsuccess grep '^\s\+Good:\s\+$' method.output
testsuccess grep 'verified because the public key is not available: GOODSIG' method.output
gpgvmethod() {
- echo '601 Configuration
+ echo "601 Configuration
Config-Item: Debug::Acquire::gpgv=1
Config-Item: Dir::Bin::apt-key=./faked-apt-key
Config-Item: APT::Hashes::SHA1::Weak=true
600 URI Acquire
-URI: file:///dev/null
-Filename: /dev/zero
+URI: file://${TMPWORKINGDIRECTORY}/message.sig
+Filename: ${TMPWORKINGDIRECTORY}/message.data
Signed-By: 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE!
-' | runapt "${METHODSDIR}/gpgv"
+" | runapt "${METHODSDIR}/gpgv"
}
testgpgv 'Exact matched subkey signed with long keyid' 'Good: GOODSIG 5A90D141DBAC8DAE' '34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE!' '[GNUPG:] GOODSIG 5A90D141DBAC8DAE Sebastian Subkey <subkey@example.org>
[GNUPG:] VALIDSIG 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE 2018-08-16 1534459673 0 4 0 1 11 00 4281DEDBD466EAE8C1F4157E5B6896415D44C43E'
diff --git a/test/libapt/openmaybeclearsignedfile_test.cc b/test/libapt/openmaybeclearsignedfile_test.cc
index 1f63fb8fc..0a4d4438a 100644
--- a/test/libapt/openmaybeclearsignedfile_test.cc
+++ b/test/libapt/openmaybeclearsignedfile_test.cc
@@ -111,7 +111,6 @@ TEST(OpenMaybeClearSignedFileTest,SignedFileWithContentHeaders)
EXPECT_TRUE(fd.Eof());
}
-// That isn't how multiple signatures are done
TEST(OpenMaybeClearSignedFileTest,SignedFileWithTwoSignatures)
{
std::string tempfile;
@@ -190,19 +189,16 @@ TEST(OpenMaybeClearSignedFileTest,TwoSimpleSignedFile)
"-----END PGP SIGNATURE-----");
EXPECT_TRUE(_error->empty());
EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile));
- EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd));
+ EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd));
if (tempfile.empty() == false)
unlink(tempfile.c_str());
EXPECT_FALSE(_error->empty());
- EXPECT_TRUE(fd.IsOpen());
- char buffer[100];
- EXPECT_TRUE(fd.ReadLine(buffer, sizeof(buffer)));
- EXPECT_STREQ(buffer, "Test");
- EXPECT_TRUE(fd.Eof());
- ASSERT_FALSE(_error->empty());
+ EXPECT_FALSE(fd.IsOpen());
+ // technically they are signed, but we just want one message
+ EXPECT_TRUE(_error->PendingError());
std::string msg;
- _error->PopMessage(msg);
+ EXPECT_TRUE(_error->PopMessage(msg));
EXPECT_EQ("Clearsigned file '" + tempfile + "' contains unsigned lines.", msg);
}
@@ -244,19 +240,15 @@ TEST(OpenMaybeClearSignedFileTest,GarbageTop)
"-----END PGP SIGNATURE-----\n");
EXPECT_FALSE(StartsWithGPGClearTextSignature(tempfile));
EXPECT_TRUE(_error->empty());
- EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd));
+ EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd));
if (tempfile.empty() == false)
unlink(tempfile.c_str());
- EXPECT_TRUE(fd.IsOpen());
- char buffer[100];
- EXPECT_TRUE(fd.ReadLine(buffer, sizeof(buffer)));
- EXPECT_STREQ(buffer, "Test");
- EXPECT_TRUE(fd.Eof());
+ EXPECT_FALSE(fd.IsOpen());
ASSERT_FALSE(_error->empty());
- ASSERT_FALSE(_error->PendingError());
+ ASSERT_TRUE(_error->PendingError());
std::string msg;
- _error->PopMessage(msg);
+ EXPECT_TRUE(_error->PopMessage(msg));
EXPECT_EQ("Clearsigned file '" + tempfile + "' does not start with a signed message block.", msg);
}
@@ -313,19 +305,15 @@ TEST(OpenMaybeClearSignedFileTest,GarbageBottom)
"Garbage");
EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile));
EXPECT_TRUE(_error->empty());
- EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd));
+ EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd));
if (tempfile.empty() == false)
unlink(tempfile.c_str());
- EXPECT_TRUE(fd.IsOpen());
- char buffer[100];
- EXPECT_TRUE(fd.ReadLine(buffer, sizeof(buffer)));
- EXPECT_STREQ(buffer, "Test");
- EXPECT_TRUE(fd.Eof());
+ EXPECT_FALSE(fd.IsOpen());
ASSERT_FALSE(_error->empty());
- ASSERT_FALSE(_error->PendingError());
+ ASSERT_TRUE(_error->PendingError());
std::string msg;
- _error->PopMessage(msg);
+ EXPECT_TRUE(_error->PopMessage(msg));
EXPECT_EQ("Clearsigned file '" + tempfile + "' contains unsigned lines.", msg);
}
@@ -347,7 +335,7 @@ TEST(OpenMaybeClearSignedFileTest,BogusNoSig)
std::string msg;
_error->PopMessage(msg);
- EXPECT_EQ("Splitting of file " + tempfile + " failed as it doesn't contain all expected parts 0 1 0", msg);
+ EXPECT_EQ("Splitting of clearsigned file " + tempfile + " failed as it doesn't contain all expected parts", msg);
}
TEST(OpenMaybeClearSignedFileTest,BogusSigStart)
@@ -371,3 +359,127 @@ TEST(OpenMaybeClearSignedFileTest,BogusSigStart)
_error->PopMessage(msg);
EXPECT_EQ("Signature in file " + tempfile + " wasn't closed", msg);
}
+
+TEST(OpenMaybeClearSignedFileTest,DashedSignedFile)
+{
+ std::string tempfile;
+ FileFd fd;
+ createTemporaryFile("dashedsignedfile", fd, &tempfile, "-----BEGIN PGP SIGNED MESSAGE-----\n"
+"Hash: SHA512\n"
+"\n"
+"- Test\n"
+"-----BEGIN PGP SIGNATURE-----\n"
+"\n"
+"iQFEBAEBCgAuFiEENKjp0Y2zIPNn6OqgWpDRQdusja4FAlhT7+kQHGpvZUBleGFt\n"
+"cGxlLm9yZwAKCRBakNFB26yNrjvEB/9/e3jA1l0fvPafx9LEXcH8CLpUFQK7ra9l\n"
+"3M4YAH4JKQlTG1be7ixruBRlCTh3YiSs66fKMeJeUYoxA2HPhvbGFEjQFAxunEYg\n"
+"X/LBKv1mQWa+Q34P5GBjK8kQdLCN+yJAiUErmWNQG3GPninrxsC9tY5jcWvHeP1k\n"
+"V7N3MLnNqzXaCJM24mnKidC5IDadUdQ8qC8c3rjUexQ8vBz0eucH56jbqV5oOcvx\n"
+"pjlW965dCPIf3OI8q6J7bIOjyY+u/PTcVlqPq3TUz/ti6RkVbKpLH0D4ll3lUTns\n"
+"JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n"
+"=TB1F\n"
+"-----END PGP SIGNATURE-----\n");
+ EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile));
+ EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd));
+ if (tempfile.empty() == false)
+ unlink(tempfile.c_str());
+ EXPECT_TRUE(fd.IsOpen());
+ char buffer[100];
+ EXPECT_TRUE(fd.ReadLine(buffer, sizeof(buffer)));
+ EXPECT_STREQ(buffer, "Test");
+ EXPECT_TRUE(fd.Eof());
+}
+TEST(OpenMaybeClearSignedFileTest,StrangeDashArmorFile)
+{
+ std::string tempfile;
+ FileFd fd;
+ createTemporaryFile("strangedashfile", fd, &tempfile, "-----BEGIN PGP SIGNED MESSAGE-----\n"
+"Hash: SHA512\n"
+"-Hash: SHA512\n"
+"\n"
+"Test\n"
+"-----BEGIN PGP SIGNATURE-----\n"
+"\n"
+"iQFEBAEBCgAuFiEENKjp0Y2zIPNn6OqgWpDRQdusja4FAlhT7+kQHGpvZUBleGFt\n"
+"cGxlLm9yZwAKCRBakNFB26yNrjvEB/9/e3jA1l0fvPafx9LEXcH8CLpUFQK7ra9l\n"
+"3M4YAH4JKQlTG1be7ixruBRlCTh3YiSs66fKMeJeUYoxA2HPhvbGFEjQFAxunEYg\n"
+"X/LBKv1mQWa+Q34P5GBjK8kQdLCN+yJAiUErmWNQG3GPninrxsC9tY5jcWvHeP1k\n"
+"V7N3MLnNqzXaCJM24mnKidC5IDadUdQ8qC8c3rjUexQ8vBz0eucH56jbqV5oOcvx\n"
+"pjlW965dCPIf3OI8q6J7bIOjyY+u/PTcVlqPq3TUz/ti6RkVbKpLH0D4ll3lUTns\n"
+"JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n"
+"=TB1F\n"
+"-----END PGP SIGNATURE-----\n");
+ EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile));
+ EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd));
+ if (tempfile.empty() == false)
+ unlink(tempfile.c_str());
+ EXPECT_FALSE(_error->empty());
+ EXPECT_FALSE(fd.IsOpen());
+
+ std::string msg;
+ EXPECT_TRUE(_error->PendingError());
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Clearsigned file '" + tempfile + "' contains unexpected line starting with a dash (armor)", msg);
+}
+TEST(OpenMaybeClearSignedFileTest,StrangeDashMsgFile)
+{
+ std::string tempfile;
+ FileFd fd;
+ createTemporaryFile("strangedashfile", fd, &tempfile, "-----BEGIN PGP SIGNED MESSAGE-----\n"
+"Hash: SHA512\n"
+"\n"
+"-Test\n"
+"-----BEGIN PGP SIGNATURE-----\n"
+"\n"
+"iQFEBAEBCgAuFiEENKjp0Y2zIPNn6OqgWpDRQdusja4FAlhT7+kQHGpvZUBleGFt\n"
+"cGxlLm9yZwAKCRBakNFB26yNrjvEB/9/e3jA1l0fvPafx9LEXcH8CLpUFQK7ra9l\n"
+"3M4YAH4JKQlTG1be7ixruBRlCTh3YiSs66fKMeJeUYoxA2HPhvbGFEjQFAxunEYg\n"
+"X/LBKv1mQWa+Q34P5GBjK8kQdLCN+yJAiUErmWNQG3GPninrxsC9tY5jcWvHeP1k\n"
+"V7N3MLnNqzXaCJM24mnKidC5IDadUdQ8qC8c3rjUexQ8vBz0eucH56jbqV5oOcvx\n"
+"pjlW965dCPIf3OI8q6J7bIOjyY+u/PTcVlqPq3TUz/ti6RkVbKpLH0D4ll3lUTns\n"
+"JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n"
+"=TB1F\n"
+"-----END PGP SIGNATURE-----\n");
+ EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile));
+ EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd));
+ if (tempfile.empty() == false)
+ unlink(tempfile.c_str());
+ EXPECT_FALSE(_error->empty());
+ EXPECT_FALSE(fd.IsOpen());
+
+ std::string msg;
+ EXPECT_TRUE(_error->PendingError());
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Clearsigned file '" + tempfile + "' contains unexpected line starting with a dash (msg)", msg);
+}
+TEST(OpenMaybeClearSignedFileTest,StrangeDashSigFile)
+{
+ std::string tempfile;
+ FileFd fd;
+ createTemporaryFile("strangedashfile", fd, &tempfile, "-----BEGIN PGP SIGNED MESSAGE-----\n"
+"Hash: SHA512\n"
+"\n"
+"Test\n"
+"-----BEGIN PGP SIGNATURE-----\n"
+"\n"
+"iQFEBAEBCgAuFiEENKjp0Y2zIPNn6OqgWpDRQdusja4FAlhT7+kQHGpvZUBleGFt\n"
+"cGxlLm9yZwAKCRBakNFB26yNrjvEB/9/e3jA1l0fvPafx9LEXcH8CLpUFQK7ra9l\n"
+"3M4YAH4JKQlTG1be7ixruBRlCTh3YiSs66fKMeJeUYoxA2HPhvbGFEjQFAxunEYg\n"
+"-/LBKv1mQWa+Q34P5GBjK8kQdLCN+yJAiUErmWNQG3GPninrxsC9tY5jcWvHeP1k\n"
+"V7N3MLnNqzXaCJM24mnKidC5IDadUdQ8qC8c3rjUexQ8vBz0eucH56jbqV5oOcvx\n"
+"pjlW965dCPIf3OI8q6J7bIOjyY+u/PTcVlqPq3TUz/ti6RkVbKpLH0D4ll3lUTns\n"
+"JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n"
+"=TB1F\n"
+"-----END PGP SIGNATURE-----\n");
+ EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile));
+ EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd));
+ if (tempfile.empty() == false)
+ unlink(tempfile.c_str());
+ EXPECT_FALSE(_error->empty());
+ EXPECT_FALSE(fd.IsOpen());
+
+ std::string msg;
+ EXPECT_TRUE(_error->PendingError());
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Clearsigned file '" + tempfile + "' contains unexpected line starting with a dash (sig)", msg);
+}