mirror of
https://github.com/google/nomulus.git
synced 2025-05-09 16:28:21 +02:00
Add request/lock to opensource build
This is to fix Kokoro, given the directory added in [] Also, added forgotten keyring/api directory. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=167598465
This commit is contained in:
parent
2e4b63bb79
commit
18a13a09a4
6 changed files with 657 additions and 0 deletions
16
java/google/registry/request/lock/BUILD
Normal file
16
java/google/registry/request/lock/BUILD
Normal file
|
@ -0,0 +1,16 @@
|
|||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
licenses(["notice"]) # Apache 2.0
|
||||
|
||||
java_library(
|
||||
name = "lock",
|
||||
srcs = glob(["*.java"]),
|
||||
deps = [
|
||||
"//java/google/registry/model",
|
||||
"@com_google_code_findbugs_jsr305",
|
||||
"@com_google_dagger",
|
||||
"@joda_time",
|
||||
],
|
||||
)
|
45
java/google/registry/request/lock/LockHandler.java
Normal file
45
java/google/registry/request/lock/LockHandler.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package google.registry.request.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* Code execution locked on some shared resource.
|
||||
*
|
||||
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of
|
||||
* null is used.
|
||||
*/
|
||||
public interface LockHandler extends Serializable {
|
||||
|
||||
/**
|
||||
* Acquire one or more locks and execute a Void {@link Callable}.
|
||||
*
|
||||
* <p>Runs on a thread that will be killed if it doesn't complete before the lease expires.
|
||||
*
|
||||
* <p>Note that locks are specific either to a given tld or to the entire system (in which case
|
||||
* tld should be passed as null).
|
||||
*
|
||||
* @return true if all locks were acquired and the callable was run; false otherwise.
|
||||
*/
|
||||
public boolean executeWithLocks(
|
||||
final Callable<Void> callable,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package google.registry.request.lock;
|
||||
|
||||
import google.registry.model.server.Lock;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
/**
|
||||
* Implementation of {@link LockHandler} that uses Lock as is.
|
||||
*
|
||||
* This is a temporary implementation to help migrate from Lock to LockHandler. Once the migration
|
||||
* is complete - we will create a "proper" LockHandlerImpl class and remove this one.
|
||||
*
|
||||
* TODO(guyben):delete this class once LockHandlerImpl is done.
|
||||
*/
|
||||
public class LockHandlerPassthrough implements LockHandler {
|
||||
|
||||
private static final long serialVersionUID = 6551645164118637767L;
|
||||
|
||||
@Inject public LockHandlerPassthrough() {}
|
||||
|
||||
/**
|
||||
* Acquire one or more locks and execute a Void {@link Callable}.
|
||||
*
|
||||
* <p>Runs on a thread that will be killed if it doesn't complete before the lease expires.
|
||||
*
|
||||
* <p>This is a simple passthrough to {@link Lock#executeWithLocks}.
|
||||
*
|
||||
* @return true if all locks were acquired and the callable was run; false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean executeWithLocks(
|
||||
final Callable<Void> callable,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames) {
|
||||
return Lock.executeWithLocks(callable, tld, leaseLength, lockNames);
|
||||
}
|
||||
}
|
30
javatests/google/registry/keyring/api/BUILD
Normal file
30
javatests/google/registry/keyring/api/BUILD
Normal file
|
@ -0,0 +1,30 @@
|
|||
package(
|
||||
default_testonly = 1,
|
||||
default_visibility = ["//java/google/registry:registry_project"],
|
||||
)
|
||||
|
||||
licenses(["notice"]) # Apache 2.0
|
||||
|
||||
load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
|
||||
|
||||
java_library(
|
||||
name = "api",
|
||||
srcs = glob(["*.java"]),
|
||||
deps = [
|
||||
"//java/google/registry/keyring/api",
|
||||
"//javatests/google/registry/testing",
|
||||
"@com_google_guava_testlib",
|
||||
"@com_google_truth",
|
||||
"@junit",
|
||||
"@org_bouncycastle_bcpg_jdk15on",
|
||||
"@org_bouncycastle_bcpkix_jdk15on",
|
||||
"@org_hamcrest_library",
|
||||
"@org_mockito_all",
|
||||
],
|
||||
)
|
||||
|
||||
GenTestRules(
|
||||
name = "GeneratedTestRules",
|
||||
test_files = glob(["*Test.java"]),
|
||||
deps = [":api"],
|
||||
)
|
345
javatests/google/registry/keyring/api/ComparatorKeyringTest.java
Normal file
345
javatests/google/registry/keyring/api/ComparatorKeyringTest.java
Normal file
|
@ -0,0 +1,345 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package google.registry.keyring.api;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.LogsSubject.assertAboutLogs;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.testing.TestLogHandler;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import org.bouncycastle.bcpg.BCPGKey;
|
||||
import org.bouncycastle.bcpg.PublicKeyPacket;
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link ComparatorKeyring}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class ComparatorKeyringTest {
|
||||
|
||||
private static final String PUBLIC_KEY_FINGERPRINT = "fingerprint";
|
||||
private static final String PUBLIC_KEY_TO_STRING =
|
||||
"PGPPublicKey{fingerprint=66:69:6e:67:65:72:70:72:69:6e:74:}";
|
||||
private static final String PRIVATE_KEY_TO_STRING =
|
||||
"PGPPrivateKey{keyId=1}";
|
||||
private static final String KEY_PAIR_TO_STRING =
|
||||
String.format("PGPKeyPair{%s, %s}", PUBLIC_KEY_TO_STRING, PRIVATE_KEY_TO_STRING);
|
||||
|
||||
private static PGPPublicKey mockPublicKey(
|
||||
boolean altFingerprint,
|
||||
boolean altEncoded) throws IOException {
|
||||
PGPPublicKey publicKey = mock(PGPPublicKey.class);
|
||||
String fingerprint = altFingerprint ? "alternate" : PUBLIC_KEY_FINGERPRINT;
|
||||
String encoded = altEncoded ? "alternate" : "publicKeyEncoded";
|
||||
when(publicKey.getFingerprint()).thenReturn(fingerprint.getBytes(UTF_8));
|
||||
when(publicKey.getEncoded()).thenReturn(encoded.getBytes(UTF_8));
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
private static PGPPrivateKey mockPrivateKey(
|
||||
boolean altId,
|
||||
boolean altBcpgKeyFormat,
|
||||
boolean altBcpgKeyEncoded,
|
||||
boolean altPublicKeyPacketEncoded)
|
||||
throws IOException {
|
||||
String bcpgKeyFormat = altBcpgKeyFormat ? "alternate" : "bcpgFormat";
|
||||
String bcpgKeyEncoded = altBcpgKeyEncoded ? "alternate" : "bcpgEncoded";
|
||||
String publicKeyPacketEncoded = altPublicKeyPacketEncoded ? "alternate" : "packetEncoded";
|
||||
|
||||
BCPGKey bcpgKey = mock(BCPGKey.class);
|
||||
PublicKeyPacket publicKeyPacket = mock(PublicKeyPacket.class);
|
||||
when(bcpgKey.getFormat()).thenReturn(bcpgKeyFormat);
|
||||
when(bcpgKey.getEncoded()).thenReturn(bcpgKeyEncoded.getBytes(UTF_8));
|
||||
when(publicKeyPacket.getEncoded()).thenReturn(publicKeyPacketEncoded.getBytes(UTF_8));
|
||||
return new PGPPrivateKey(altId ? 2 : 1, publicKeyPacket, bcpgKey);
|
||||
}
|
||||
|
||||
private final TestLogHandler testLogHandler = new TestLogHandler();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ComparatorKeyring.logger.addHandler(testLogHandler);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ComparatorKeyring.logger.removeHandler(testLogHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyToString() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.stringify(
|
||||
mockPublicKey(false, false)))
|
||||
.isEqualTo(PUBLIC_KEY_TO_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPublicKey(false, false),
|
||||
mockPublicKey(false, false)))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyDifferFingerprint_notEqual() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPublicKey(false, false),
|
||||
mockPublicKey(true, false)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyDifferEncoded_notEqual() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPublicKey(false, false),
|
||||
mockPublicKey(false, true)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyToString() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.stringify(
|
||||
mockPrivateKey(false, false, false, false)))
|
||||
.isEqualTo(PRIVATE_KEY_TO_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPrivateKey(false, false, false, false),
|
||||
mockPrivateKey(false, false, false, false)))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyDifferId_notEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPrivateKey(false, false, false, false),
|
||||
mockPrivateKey(true, false, false, false)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyDifferBcpgFormat_notEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPrivateKey(false, false, false, false),
|
||||
mockPrivateKey(false, true, false, false)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyDifferBcpgEncoding_notEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPrivateKey(false, false, false, false),
|
||||
mockPrivateKey(false, false, true, false)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateKeyDifferPublicKeyEncoding_notEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
mockPrivateKey(false, false, false, false),
|
||||
mockPrivateKey(false, false, false, true)))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyPairToString() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.stringify(
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false))))
|
||||
.isEqualTo(KEY_PAIR_TO_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyPairEquals() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false)),
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false))))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyPairDifferPublicKey_notEqual() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false)),
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(true, false),
|
||||
mockPrivateKey(false, false, false, false))))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyPairDifferPrivateKey_notEqual() throws Exception {
|
||||
assertThat(
|
||||
ComparatorKeyring.compare(
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false)),
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(true, false, false, false))))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
// We don't need to check every single method in the generated instance to see that it behaves
|
||||
// correctly. This should have been tested in ComparatorGenerator.
|
||||
//
|
||||
// We will fully test a single method just to make sure everything is "connected" correctly.
|
||||
|
||||
@Test
|
||||
public void testRdeSigningKey_actualThrows() throws Exception {
|
||||
Keyring actualKeyring = mock(Keyring.class);
|
||||
Keyring secondKeyring = mock(Keyring.class);
|
||||
PGPKeyPair keyPair =
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false));
|
||||
when(actualKeyring.getRdeSigningKey()).thenThrow(new KeyringException("message"));
|
||||
when(secondKeyring.getRdeSigningKey()).thenReturn(keyPair);
|
||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||
|
||||
try {
|
||||
comparatorKeyring.getRdeSigningKey();
|
||||
fail("Should have thrown KeyringException");
|
||||
} catch (KeyringException expected) {
|
||||
}
|
||||
|
||||
assertAboutLogs()
|
||||
.that(testLogHandler)
|
||||
.hasLogAtLevelWithMessage(
|
||||
Level.SEVERE, ".getRdeSigningKey: Only actual implementation threw exception");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRdeSigningKey_secondThrows() throws Exception {
|
||||
Keyring actualKeyring = mock(Keyring.class);
|
||||
Keyring secondKeyring = mock(Keyring.class);
|
||||
PGPKeyPair keyPair =
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false));
|
||||
when(actualKeyring.getRdeSigningKey()).thenReturn(keyPair);
|
||||
when(secondKeyring.getRdeSigningKey()).thenThrow(new KeyringException("message"));
|
||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||
|
||||
assertThat(comparatorKeyring.getRdeSigningKey()).isSameAs(keyPair);
|
||||
|
||||
assertAboutLogs()
|
||||
.that(testLogHandler)
|
||||
.hasLogAtLevelWithMessage(
|
||||
Level.SEVERE, ".getRdeSigningKey: Only second implementation threw exception");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRdeSigningKey_bothThrow() {
|
||||
Keyring actualKeyring = mock(Keyring.class);
|
||||
Keyring secondKeyring = mock(Keyring.class);
|
||||
when(actualKeyring.getRdeSigningKey()).thenThrow(new KeyringException("message"));
|
||||
when(secondKeyring.getRdeSigningKey()).thenThrow(new KeyringException("message"));
|
||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||
|
||||
try {
|
||||
comparatorKeyring.getRdeSigningKey();
|
||||
fail("Should have thrown KeyringException");
|
||||
} catch (KeyringException expected) {
|
||||
}
|
||||
|
||||
assertAboutLogs().that(testLogHandler).hasNoLogsAtLevel(Level.SEVERE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRdeSigningKey_same() throws Exception {
|
||||
Keyring actualKeyring = mock(Keyring.class);
|
||||
Keyring secondKeyring = mock(Keyring.class);
|
||||
PGPKeyPair keyPair =
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false));
|
||||
PGPKeyPair keyPairCopy =
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false));
|
||||
when(actualKeyring.getRdeSigningKey()).thenReturn(keyPair);
|
||||
when(secondKeyring.getRdeSigningKey()).thenReturn(keyPairCopy);
|
||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||
|
||||
assertThat(comparatorKeyring.getRdeSigningKey()).isSameAs(keyPair);
|
||||
|
||||
assertAboutLogs().that(testLogHandler).hasNoLogsAtLevel(Level.SEVERE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRdeSigningKey_different() throws Exception {
|
||||
Keyring actualKeyring = mock(Keyring.class);
|
||||
Keyring secondKeyring = mock(Keyring.class);
|
||||
PGPKeyPair keyPair =
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(false, false, false, false));
|
||||
PGPKeyPair keyPairDifferent =
|
||||
new PGPKeyPair(
|
||||
mockPublicKey(false, false),
|
||||
mockPrivateKey(true, false, false, false));
|
||||
when(actualKeyring.getRdeSigningKey()).thenReturn(keyPair);
|
||||
when(secondKeyring.getRdeSigningKey()).thenReturn(keyPairDifferent);
|
||||
Keyring comparatorKeyring = ComparatorKeyring.create(actualKeyring, secondKeyring);
|
||||
|
||||
assertThat(comparatorKeyring.getRdeSigningKey()).isSameAs(keyPair);
|
||||
|
||||
String alternateKeyPairString = String.format(
|
||||
"PGPKeyPair{%s, %s}", PUBLIC_KEY_TO_STRING, "PGPPrivateKey{keyId=2}");
|
||||
|
||||
assertAboutLogs()
|
||||
.that(testLogHandler)
|
||||
.hasLogAtLevelWithMessage(
|
||||
Level.SEVERE,
|
||||
String.format(
|
||||
".getRdeSigningKey: Got different results! '%s' vs '%s'",
|
||||
KEY_PAIR_TO_STRING,
|
||||
alternateKeyPairString));
|
||||
}
|
||||
}
|
167
javatests/google/registry/keyring/api/KeySerializerTest.java
Normal file
167
javatests/google/registry/keyring/api/KeySerializerTest.java
Normal file
|
@ -0,0 +1,167 @@
|
|||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package google.registry.keyring.api;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import google.registry.testing.BouncyCastleProviderRule;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPUtil;
|
||||
import org.bouncycastle.openpgp.bc.BcPGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link KeySerializer}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class KeySerializerTest {
|
||||
|
||||
@Rule
|
||||
public final BouncyCastleProviderRule bouncy = new BouncyCastleProviderRule();
|
||||
|
||||
/**
|
||||
* An Armored representation of a pgp secret key.
|
||||
*
|
||||
* <p>This key was created specifically for tests. It has a password of "12345678".
|
||||
*
|
||||
* <p>Created using 'gpg --gen-key' followed by 'gpg --export-secret-key -a'.
|
||||
*/
|
||||
private static final String ARMORED_KEY_STRING =
|
||||
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n"
|
||||
+ "Version: GnuPG v1\n"
|
||||
+ "\n"
|
||||
+ "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\n"
|
||||
+ "GQ==\n"
|
||||
+ "=qeFB\n"
|
||||
+ "-----END PGP PRIVATE KEY BLOCK-----\n";
|
||||
|
||||
private static final BcPGPSecretKeyRing SECRET_KEYRING = getSecretKeyring();
|
||||
|
||||
private static final PGPSecretKey SECRET_KEY = SECRET_KEYRING.getSecretKey();
|
||||
|
||||
private static final PGPPublicKey PUBLIC_KEY = SECRET_KEY.getPublicKey();
|
||||
|
||||
private static final PGPPrivateKey PRIVATE_KEY = extractPrivateKey(SECRET_KEY, "12345678");
|
||||
|
||||
// Used for static initialization only.
|
||||
private static BcPGPSecretKeyRing getSecretKeyring() {
|
||||
try {
|
||||
return new BcPGPSecretKeyRing(
|
||||
PGPUtil.getDecoderStream(new ByteArrayInputStream(ARMORED_KEY_STRING.getBytes(UTF_8))));
|
||||
} catch (IOException | PGPException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Used for static initialization only.
|
||||
private static PGPPrivateKey extractPrivateKey(PGPSecretKey secretKey, String password) {
|
||||
try {
|
||||
return secretKey.extractPrivateKey(
|
||||
new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider())
|
||||
.build(password.toCharArray()));
|
||||
} catch (PGPException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void serializeString() throws Exception {
|
||||
String result = KeySerializer.deserializeString(KeySerializer.serializeString("value\n"));
|
||||
assertThat(result).isEqualTo("value\n");
|
||||
}
|
||||
|
||||
@Test public void serializePublicKey() throws Exception {
|
||||
PGPPublicKey publicKeyResult =
|
||||
KeySerializer.deserializePublicKey(
|
||||
KeySerializer.serializePublicKey(PUBLIC_KEY));
|
||||
|
||||
assertThat(publicKeyResult.getEncoded()).isEqualTo(PUBLIC_KEY.getEncoded());
|
||||
}
|
||||
|
||||
@Test public void serializeKeyPair() throws Exception {
|
||||
PGPKeyPair keyPairResult =
|
||||
KeySerializer.deserializeKeyPair(
|
||||
KeySerializer.serializeKeyPair(new PGPKeyPair(PUBLIC_KEY, PRIVATE_KEY)));
|
||||
|
||||
assertThat(keyPairResult.getPublicKey().getEncoded()).isEqualTo(PUBLIC_KEY.getEncoded());
|
||||
assertThat(keyPairResult.getPrivateKey().getKeyID()).isEqualTo(PRIVATE_KEY.getKeyID());
|
||||
assertThat(keyPairResult.getPrivateKey().getPrivateKeyDataPacket().getEncoded())
|
||||
.isEqualTo(PRIVATE_KEY.getPrivateKeyDataPacket().getEncoded());
|
||||
assertThat(keyPairResult.getPrivateKey().getPublicKeyPacket().getEncoded())
|
||||
.isEqualTo(PRIVATE_KEY.getPublicKeyPacket().getEncoded());
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue