• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pgpainless / sop-java / #68

20 Jan 2026 09:05PM UTC coverage: 57.576% (-0.6%) from 58.151%
#68

push

other

vanitasvitae
Fix missing parameter error in validate-userid command

0 of 1 new or added line in 1 file covered. (0.0%)

159 existing lines in 5 files now uncovered.

2109 of 3663 relevant lines covered (57.58%)

0.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.16
/sop-java-testfixtures/src/main/java/sop/testsuite/operation/DetachedSignDetachedVerifyTest.java
1
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
2
//
3
// SPDX-License-Identifier: Apache-2.0
4

5
package sop.testsuite.operation;
6

7
import org.junit.jupiter.api.Disabled;
8
import org.junit.jupiter.api.condition.EnabledIf;
9
import org.junit.jupiter.params.ParameterizedTest;
10
import org.junit.jupiter.params.provider.Arguments;
11
import org.junit.jupiter.params.provider.MethodSource;
12
import sop.SOP;
13
import sop.Verification;
14
import sop.enums.SignAs;
15
import sop.enums.SignatureMode;
16
import sop.exception.SOPGPException;
17
import sop.testsuite.JUtils;
18
import sop.testsuite.TestData;
19
import sop.testsuite.assertions.VerificationListAssert;
20

21
import java.io.IOException;
22
import java.nio.charset.StandardCharsets;
23
import java.util.Date;
24
import java.util.List;
25
import java.util.stream.Stream;
26

27
import static org.junit.jupiter.api.Assertions.assertThrows;
28

29
@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends")
30
public class DetachedSignDetachedVerifyTest extends AbstractSOPTest {
1✔
31

32
    static Stream<Arguments> provideInstances() {
33
        return provideBackends();
1✔
34
    }
35

36
    @ParameterizedTest
37
    @MethodSource("provideInstances")
38
    public void signVerifyWithAliceKey(SOP sop) throws IOException {
39
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
40

41
        byte[] signature = assumeSupported(sop::detachedSign)
1✔
42
                .key(TestData.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
1✔
43
                .data(message)
1✔
44
                .toByteArrayAndResult()
1✔
45
                .getBytes();
1✔
46

47
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
1✔
48
                .cert(TestData.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
1✔
49
                .signatures(signature)
1✔
50
                .data(message);
1✔
51

52
        VerificationListAssert.assertThatVerificationList(verificationList)
1✔
53
                .isNotEmpty()
1✔
54
                .hasSingleItem()
1✔
55
                .issuedBy(TestData.ALICE_SIGNING_FINGERPRINT, TestData.ALICE_PRIMARY_FINGERPRINT)
1✔
56
                .hasModeOrNull(SignatureMode.binary);
1✔
57
    }
1✔
58

59
    @ParameterizedTest
60
    @MethodSource("provideInstances")
61
    public void signVerifyTextModeWithAliceKey(SOP sop) throws IOException {
62
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
63

64
        byte[] signature = assumeSupported(sop::detachedSign)
1✔
65
                .key(TestData.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
1✔
66
                .mode(SignAs.text)
1✔
67
                .data(message)
1✔
68
                .toByteArrayAndResult()
1✔
69
                .getBytes();
1✔
70

71
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
1✔
72
                .cert(TestData.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
1✔
73
                .signatures(signature)
1✔
74
                .data(message);
1✔
75

76
        VerificationListAssert.assertThatVerificationList(verificationList)
1✔
77
                .isNotEmpty()
1✔
78
                .hasSingleItem()
1✔
79
                .issuedBy(TestData.ALICE_SIGNING_FINGERPRINT, TestData.ALICE_PRIMARY_FINGERPRINT)
1✔
80
                .hasModeOrNull(SignatureMode.text);
1✔
81
    }
1✔
82

83
    @ParameterizedTest
84
    @MethodSource("provideInstances")
85
    public void verifyKnownMessageWithAliceCert(SOP sop) throws IOException {
86
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
87
        byte[] signature = TestData.ALICE_DETACHED_SIGNED_MESSAGE.getBytes(StandardCharsets.UTF_8);
1✔
88

89
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
1✔
90
                .cert(TestData.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
1✔
91
                .signatures(signature)
1✔
92
                .data(message);
1✔
93

94
        VerificationListAssert.assertThatVerificationList(verificationList)
1✔
95
                .isNotEmpty()
1✔
96
                .hasSingleItem()
1✔
97
                .issuedBy(TestData.ALICE_SIGNING_FINGERPRINT, TestData.ALICE_PRIMARY_FINGERPRINT);
1✔
98
    }
1✔
99

100
    @ParameterizedTest
101
    @MethodSource("provideInstances")
102
    public void signVerifyWithBobKey(SOP sop) throws IOException {
103
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
104

105
        byte[] signature = assumeSupported(sop::detachedSign)
1✔
106
                .key(TestData.BOB_KEY.getBytes(StandardCharsets.UTF_8))
1✔
107
                .data(message)
1✔
108
                .toByteArrayAndResult()
1✔
109
                .getBytes();
1✔
110

111
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
1✔
112
                .cert(TestData.BOB_CERT.getBytes(StandardCharsets.UTF_8))
1✔
113
                .signatures(signature)
1✔
114
                .data(message);
1✔
115

116
        VerificationListAssert.assertThatVerificationList(verificationList)
1✔
117
                .isNotEmpty()
1✔
118
                .hasSingleItem()
1✔
119
                .issuedBy(TestData.BOB_SIGNING_FINGERPRINT, TestData.BOB_PRIMARY_FINGERPRINT);
1✔
120
    }
1✔
121

122
    @ParameterizedTest
123
    @MethodSource("provideInstances")
124
    @Disabled("Carol is a deprecated ElGamal key")
125
    public void signVerifyWithCarolKey(SOP sop) throws IOException {
UNCOV
126
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
×
127

UNCOV
128
        byte[] signature = assumeSupported(sop::detachedSign)
×
UNCOV
129
                .key(TestData.CAROL_KEY.getBytes(StandardCharsets.UTF_8))
×
UNCOV
130
                .data(message)
×
UNCOV
131
                .toByteArrayAndResult()
×
UNCOV
132
                .getBytes();
×
133

UNCOV
134
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
×
UNCOV
135
                .cert(TestData.CAROL_CERT.getBytes(StandardCharsets.UTF_8))
×
UNCOV
136
                .signatures(signature)
×
UNCOV
137
                .data(message);
×
138

UNCOV
139
        VerificationListAssert.assertThatVerificationList(verificationList)
×
UNCOV
140
                .isNotEmpty()
×
UNCOV
141
                .hasSingleItem()
×
UNCOV
142
                .issuedBy(TestData.CAROL_SIGNING_FINGERPRINT, TestData.CAROL_PRIMARY_FINGERPRINT);
×
UNCOV
143
    }
×
144

145
    @ParameterizedTest
146
    @MethodSource("provideInstances")
147
    public void signVerifyWithEncryptedKey(SOP sop) throws IOException {
148
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
149

150
        byte[] signature = assumeSupported(sop::detachedSign)
1✔
151
                .key(TestData.PASSWORD_PROTECTED_KEY.getBytes(StandardCharsets.UTF_8))
1✔
152
                .withKeyPassword(TestData.PASSWORD)
1✔
153
                .data(message)
1✔
UNCOV
154
                .toByteArrayAndResult()
×
155
                .getBytes();
×
156

157
        JUtils.assertArrayStartsWith(signature, TestData.BEGIN_PGP_SIGNATURE);
×
158

159
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
×
160
                .cert(TestData.PASSWORD_PROTECTED_CERT.getBytes(StandardCharsets.UTF_8))
×
UNCOV
161
                .signatures(signature)
×
162
                .data(message);
×
163

164
        VerificationListAssert.assertThatVerificationList(verificationList)
×
165
                .isNotEmpty()
×
166
                .hasSingleItem()
×
UNCOV
167
                .issuedBy(TestData.PASSWORD_PROTECTED_SIGNING_FINGERPRINT, TestData.PASSWORD_PROTECTED_PRIMARY_FINGERPRINT);
×
UNCOV
168
    }
×
169

170
    @ParameterizedTest
171
    @MethodSource("provideInstances")
172
    public void signArmorVerifyWithBobKey(SOP sop) throws IOException {
173
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
174

175
        byte[] signature = assumeSupported(sop::detachedSign)
1✔
176
                .key(TestData.BOB_KEY.getBytes(StandardCharsets.UTF_8))
1✔
177
                .noArmor()
1✔
178
                .data(message)
1✔
179
                .toByteArrayAndResult()
1✔
180
                .getBytes();
1✔
181

182
        byte[] armored = assumeSupported(sop::armor)
1✔
183
                .data(signature)
1✔
184
                .getBytes();
1✔
185

186
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
1✔
187
                .cert(TestData.BOB_CERT.getBytes(StandardCharsets.UTF_8))
1✔
188
                .signatures(armored)
1✔
189
                .data(message);
1✔
190

191
        VerificationListAssert.assertThatVerificationList(verificationList)
1✔
192
                .isNotEmpty()
1✔
193
                .hasSingleItem()
1✔
194
                .issuedBy(TestData.BOB_SIGNING_FINGERPRINT, TestData.BOB_PRIMARY_FINGERPRINT);
1✔
195
    }
1✔
196

197
    @ParameterizedTest
198
    @MethodSource("provideInstances")
199
    public void verifyNotAfterThrowsNoSignature(SOP sop) {
200
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
201
        byte[] signature = TestData.ALICE_DETACHED_SIGNED_MESSAGE.getBytes(StandardCharsets.UTF_8);
1✔
202
        Date beforeSignature = new Date(TestData.ALICE_DETACHED_SIGNED_MESSAGE_DATE.getTime() - 1000); // 1 sec before sig
1✔
203

204
        assertThrows(SOPGPException.NoSignature.class, () -> assumeSupported(sop::detachedVerify)
1✔
205
                .cert(TestData.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
1✔
206
                .notAfter(beforeSignature)
1✔
207
                .signatures(signature)
1✔
UNCOV
208
                .data(message));
×
UNCOV
209
    }
×
210

211
    @ParameterizedTest
212
    @MethodSource("provideInstances")
213
    public void verifyNotBeforeThrowsNoSignature(SOP sop) {
214
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
215
        byte[] signature = TestData.ALICE_DETACHED_SIGNED_MESSAGE.getBytes(StandardCharsets.UTF_8);
1✔
216
        Date afterSignature = new Date(TestData.ALICE_DETACHED_SIGNED_MESSAGE_DATE.getTime() + 1000); // 1 sec after sig
1✔
217

218
        assertThrows(SOPGPException.NoSignature.class, () -> assumeSupported(sop::detachedVerify)
1✔
219
                .cert(TestData.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
1✔
220
                .notBefore(afterSignature)
1✔
221
                .signatures(signature)
1✔
UNCOV
222
                .data(message));
×
UNCOV
223
    }
×
224

225
    @ParameterizedTest
226
    @MethodSource("provideInstances")
227
    public void signWithAliceVerifyWithBobThrowsNoSignature(SOP sop) throws IOException {
228
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
229
        byte[] signatures = assumeSupported(sop::detachedSign)
1✔
230
                .key(TestData.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
1✔
231
                .data(message)
1✔
232
                .toByteArrayAndResult()
1✔
233
                .getBytes();
1✔
234

235
        assertThrows(SOPGPException.NoSignature.class, () -> assumeSupported(sop::detachedVerify)
1✔
236
                .cert(TestData.BOB_CERT.getBytes(StandardCharsets.UTF_8))
1✔
237
                .signatures(signatures)
1✔
UNCOV
238
                .data(message));
×
UNCOV
239
    }
×
240

241
    @ParameterizedTest
242
    @MethodSource("provideInstances")
243
    public void signVerifyWithEncryptedKeyWithoutPassphraseFails(SOP sop) {
UNCOV
244
        assertThrows(SOPGPException.KeyIsProtected.class, () ->
×
245
                assumeSupported(sop::detachedSign)
1✔
246
                        .key(TestData.PASSWORD_PROTECTED_KEY.getBytes(StandardCharsets.UTF_8))
1✔
247
                        .data(TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8))
1✔
248
                        .toByteArrayAndResult()
×
UNCOV
249
                        .getBytes());
×
UNCOV
250
    }
×
251

252
    @ParameterizedTest
253
    @MethodSource("provideInstances")
254
    public void signWithProtectedKeyAndMultiplePassphrasesTest(SOP sop)
255
            throws IOException {
256
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
257

258
        byte[] signature = assumeSupported(sop::sign)
1✔
259
                .key(TestData.PASSWORD_PROTECTED_KEY.getBytes(StandardCharsets.UTF_8))
1✔
260
                .withKeyPassword("wrong")
1✔
261
                .withKeyPassword(TestData.PASSWORD) // correct
1✔
262
                .withKeyPassword("wrong2")
1✔
263
                .data(message)
1✔
UNCOV
264
                .toByteArrayAndResult()
×
265
                .getBytes();
×
266

267
        List<Verification> verificationList = assumeSupported(sop::verify)
×
268
                .cert(TestData.PASSWORD_PROTECTED_CERT.getBytes(StandardCharsets.UTF_8))
×
UNCOV
269
                .signatures(signature)
×
270
                .data(message);
×
271

272
        VerificationListAssert.assertThatVerificationList(verificationList)
×
273
                .isNotEmpty()
×
274
                .hasSingleItem()
×
UNCOV
275
                .issuedBy(TestData.PASSWORD_PROTECTED_SIGNING_FINGERPRINT, TestData.PASSWORD_PROTECTED_PRIMARY_FINGERPRINT);
×
UNCOV
276
    }
×
277

278
    @ParameterizedTest
279
    @MethodSource("provideInstances")
280
    public void verifyMissingCertCausesMissingArg(SOP sop) {
281
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
282

UNCOV
283
        assertThrows(SOPGPException.MissingArg.class, () ->
×
284
                assumeSupported(sop::verify)
1✔
285
                        .signatures(TestData.ALICE_DETACHED_SIGNED_MESSAGE.getBytes(StandardCharsets.UTF_8))
1✔
UNCOV
286
                        .data(message));
×
UNCOV
287
    }
×
288

289
    @ParameterizedTest
290
    @MethodSource("provideInstances")
291
    public void signVerifyWithMultipleKeys(SOP sop) throws IOException {
292
        byte[] message = TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8);
1✔
293
        byte[] signatures = assumeSupported(sop::detachedSign)
1✔
294
                .key(TestData.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
1✔
295
                .key(TestData.BOB_KEY.getBytes(StandardCharsets.UTF_8))
1✔
296
                .data(message)
1✔
297
                .toByteArrayAndResult()
1✔
298
                .getBytes();
1✔
299

300
        List<Verification> verificationList = assumeSupported(sop::detachedVerify)
1✔
301
                .cert(TestData.ALICE_CERT.getBytes(StandardCharsets.UTF_8))
1✔
302
                .cert(TestData.BOB_CERT.getBytes(StandardCharsets.UTF_8))
1✔
303
                .signatures(signatures)
1✔
304
                .data(message);
1✔
305

306
        VerificationListAssert.assertThatVerificationList(verificationList)
1✔
307
                .isNotEmpty()
1✔
308
                .sizeEquals(2)
1✔
309
                .containsVerificationBy(TestData.ALICE_SIGNING_FINGERPRINT, TestData.ALICE_PRIMARY_FINGERPRINT)
1✔
310
                .containsVerificationBy(TestData.BOB_SIGNING_FINGERPRINT, TestData.BOB_PRIMARY_FINGERPRINT);
1✔
311
    }
1✔
312

313

314
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc