1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.gpg.bc.internal.keys;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertTrue;
16
17 import java.io.BufferedInputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.security.Security;
21 import java.util.Iterator;
22
23 import javax.crypto.Cipher;
24
25 import org.bouncycastle.jce.provider.BouncyCastleProvider;
26 import org.bouncycastle.openpgp.PGPException;
27 import org.bouncycastle.openpgp.PGPPublicKey;
28 import org.bouncycastle.openpgp.PGPPublicKeyRing;
29 import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
30 import org.bouncycastle.openpgp.PGPSecretKey;
31 import org.bouncycastle.openpgp.PGPUtil;
32 import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
33 import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
34 import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
35 import org.junit.BeforeClass;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.junit.runners.Parameterized;
39 import org.junit.runners.Parameterized.Parameter;
40 import org.junit.runners.Parameterized.Parameters;
41
42 @RunWith(Parameterized.class)
43 public class SecretKeysTest {
44
45 @BeforeClass
46 public static void ensureBC() {
47 if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
48 Security.addProvider(new BouncyCastleProvider());
49 }
50 }
51
52 private static volatile Boolean haveOCB;
53
54 private static boolean ocbAvailable() {
55 Boolean haveIt = haveOCB;
56 if (haveIt != null) {
57 return haveIt.booleanValue();
58 }
59 try {
60 Cipher c = Cipher.getInstance("AES/OCB/NoPadding");
61 if (c == null) {
62 haveOCB = Boolean.FALSE;
63 return false;
64 }
65 } catch (NoClassDefFoundError | Exception e) {
66 haveOCB = Boolean.FALSE;
67 return false;
68 }
69 haveOCB = Boolean.TRUE;
70 return true;
71 }
72
73 private static class TestData {
74
75 final String name;
76
77 final boolean encrypted;
78
79 final boolean keyValue;
80
81 TestData(String name, boolean encrypted, boolean keyValue) {
82 this.name = name;
83 this.encrypted = encrypted;
84 this.keyValue = keyValue;
85 }
86
87 @Override
88 public String toString() {
89 return name;
90 }
91 }
92
93 @Parameters(name = "{0}")
94 public static TestData[] initTestData() {
95 return new TestData[] {
96 new TestData("AFDA8EA10E185ACF8C0D0F8885A0EF61A72ECB11", false, false),
97 new TestData("2FB05DBB70FC07CB84C13431F640CA6CEA1DBF8A", false, true),
98 new TestData("66CCECEC2AB46A9735B10FEC54EDF9FD0F77BAF9", true, true),
99 new TestData("F727FAB884DA3BD402B6E0F5472E108D21033124", true, true),
100 new TestData("faked", false, true) };
101 }
102
103 private static byte[] readTestKey(String filename) throws Exception {
104 try (InputStream in = new BufferedInputStream(
105 SecretKeysTest.class.getResourceAsStream(filename))) {
106 return SecretKeys.keyFromNameValueFormat(in);
107 }
108 }
109
110 private static PGPPublicKey readAsc(InputStream in)
111 throws IOException, PGPException {
112 PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
113 PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator());
114
115 Iterator<PGPPublicKeyRing> keyRings = pgpPub.getKeyRings();
116 while (keyRings.hasNext()) {
117 PGPPublicKeyRing keyRing = keyRings.next();
118
119 Iterator<PGPPublicKey> keys = keyRing.getPublicKeys();
120 if (keys.hasNext()) {
121 return keys.next();
122 }
123 }
124 return null;
125 }
126
127
128 @Parameter
129 public TestData data;
130
131 @Test
132 public void testKeyRead() throws Exception {
133 if (data.keyValue) {
134 byte[] bytes = readTestKey(data.name + ".key");
135 assertEquals('(', bytes[0]);
136 assertEquals(')', bytes[bytes.length - 1]);
137 }
138 try (InputStream pubIn = this.getClass()
139 .getResourceAsStream(data.name + ".asc")) {
140 if (pubIn != null) {
141 PGPPublicKey publicKey = readAsc(pubIn);
142
143 PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
144 .build();
145 try (InputStream in = new BufferedInputStream(this.getClass()
146 .getResourceAsStream(data.name + ".key"))) {
147 PGPSecretKey secretKey = SecretKeys.readSecretKey(in,
148 calculatorProvider,
149 data.encrypted ? () -> "nonsense".toCharArray()
150 : null,
151 publicKey);
152 assertNotNull(secretKey);
153 } catch (PGPException e) {
154
155 assertTrue(e.getMessage().contains("OCB"));
156 assertTrue(data.encrypted);
157 assertFalse(ocbAvailable());
158 }
159 }
160 }
161 }
162
163 }