aboutsummaryrefslogtreecommitdiff
path: root/java_src/src/test/java/com/google/crypto/tink
diff options
context:
space:
mode:
authorioannanedelcu <ioannanedelcu@google.com>2023-07-07 06:40:40 -0700
committerCopybara-Service <copybara-worker@google.com>2023-07-07 06:41:52 -0700
commitfbd77e2d296a2dc126b3ff6ff1acf004fe46ed63 (patch)
tree52211c6779ef2df54ed7b617307acb649fe425e0 /java_src/src/test/java/com/google/crypto/tink
parent6bb319334db547bfba91da531557f2221ab3e930 (diff)
downloadtink-fbd77e2d296a2dc126b3ff6ff1acf004fe46ed63.tar.gz
Add Parser and Serializer for EciesParameters.
PiperOrigin-RevId: 546265787
Diffstat (limited to 'java_src/src/test/java/com/google/crypto/tink')
-rw-r--r--java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel27
-rw-r--r--java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java394
2 files changed, 421 insertions, 0 deletions
diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel b/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel
index 5304a7f18..fb30e99c2 100644
--- a/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel
+++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/BUILD.bazel
@@ -375,3 +375,30 @@ java_test(
"@maven//:junit_junit",
],
)
+
+java_test(
+ name = "EciesProtoSerializationTest",
+ size = "small",
+ srcs = ["EciesProtoSerializationTest.java"],
+ deps = [
+ "//proto:common_java_proto",
+ "//proto:ecies_aead_hkdf_java_proto",
+ "//proto:tink_java_proto",
+ "//proto:xchacha20_poly1305_java_proto",
+ "//src/main/java/com/google/crypto/tink:parameters",
+ "//src/main/java/com/google/crypto/tink/aead:aead_config",
+ "//src/main/java/com/google/crypto/tink/aead:x_cha_cha20_poly1305_parameters",
+ "//src/main/java/com/google/crypto/tink/hybrid:ecies_parameters",
+ "//src/main/java/com/google/crypto/tink/hybrid:ecies_proto_serialization",
+ "//src/main/java/com/google/crypto/tink/internal:mutable_serialization_registry",
+ "//src/main/java/com/google/crypto/tink/internal:proto_parameters_serialization",
+ "//src/main/java/com/google/crypto/tink/internal:tink_bug_exception",
+ "//src/main/java/com/google/crypto/tink/internal/testing:asserts",
+ "//src/main/java/com/google/crypto/tink/subtle:hex",
+ "//src/main/java/com/google/crypto/tink/util:bytes",
+ "@maven//:com_google_code_findbugs_jsr305",
+ "@maven//:com_google_protobuf_protobuf_java",
+ "@maven//:com_google_truth_truth",
+ "@maven//:junit_junit",
+ ],
+)
diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java
new file mode 100644
index 000000000..02a53f5fe
--- /dev/null
+++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesProtoSerializationTest.java
@@ -0,0 +1,394 @@
+// Copyright 2023 Google LLC
+//
+// 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 com.google.crypto.tink.hybrid;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.crypto.tink.internal.TinkBugException.exceptionIsBug;
+import static com.google.crypto.tink.internal.testing.Asserts.assertEqualWhenValueParsed;
+import static org.junit.Assert.assertThrows;
+
+import com.google.crypto.tink.Parameters;
+import com.google.crypto.tink.aead.AeadConfig;
+import com.google.crypto.tink.aead.XChaCha20Poly1305Parameters;
+import com.google.crypto.tink.internal.MutableSerializationRegistry;
+import com.google.crypto.tink.internal.ProtoParametersSerialization;
+import com.google.crypto.tink.proto.EcPointFormat;
+import com.google.crypto.tink.proto.EciesAeadDemParams;
+import com.google.crypto.tink.proto.EciesAeadHkdfKeyFormat;
+import com.google.crypto.tink.proto.EciesAeadHkdfParams;
+import com.google.crypto.tink.proto.EciesHkdfKemParams;
+import com.google.crypto.tink.proto.EllipticCurveType;
+import com.google.crypto.tink.proto.HashType;
+import com.google.crypto.tink.proto.KeyTemplate;
+import com.google.crypto.tink.proto.OutputPrefixType;
+import com.google.crypto.tink.proto.XChaCha20Poly1305KeyFormat;
+import com.google.crypto.tink.subtle.Hex;
+import com.google.crypto.tink.util.Bytes;
+import com.google.protobuf.ByteString;
+import java.security.GeneralSecurityException;
+import javax.annotation.Nullable;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+/** Unit tests for {@link EciesProtoSerialization}. */
+@RunWith(Theories.class)
+@SuppressWarnings("UnnecessarilyFullyQualified") // Fully specifying proto types is more readable
+public final class EciesProtoSerializationTest {
+ private static final String PRIVATE_TYPE_URL =
+ "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey";
+
+ private static final Bytes SALT = Bytes.copyFrom(Hex.decode("2023af"));
+ private static final Parameters DEM_PARAMETERS =
+ exceptionIsBug(() -> XChaCha20Poly1305Parameters.create());
+
+ private static final XChaCha20Poly1305KeyFormat DEM_KEY_FORMAT_PROTO =
+ XChaCha20Poly1305KeyFormat.newBuilder().setVersion(0).build();
+
+ private static final MutableSerializationRegistry registry = new MutableSerializationRegistry();
+
+ private static final class VariantTuple {
+ final EciesParameters.Variant variant;
+ final OutputPrefixType outputPrefixType;
+
+ VariantTuple(
+ EciesParameters.Variant variant,
+ OutputPrefixType outputPrefixType,
+ @Nullable Integer idRequirement) {
+ this.variant = variant;
+ this.outputPrefixType = outputPrefixType;
+ }
+ }
+
+ @DataPoints("variants")
+ public static final VariantTuple[] VARIANTS_TUPLES =
+ new VariantTuple[] {
+ new VariantTuple(
+ EciesParameters.Variant.NO_PREFIX, OutputPrefixType.RAW, /* idRequirement= */ null),
+ new VariantTuple(
+ EciesParameters.Variant.TINK, OutputPrefixType.TINK, /* idRequirement= */ 123),
+ new VariantTuple(
+ EciesParameters.Variant.CRUNCHY, OutputPrefixType.CRUNCHY, /* idRequirement= */ 456),
+ };
+
+ private static final EciesAeadHkdfParams createEciesProtoParams(
+ EllipticCurveType curveType,
+ HashType hashType,
+ EcPointFormat pointFormat,
+ @Nullable ByteString salt,
+ KeyTemplate demKeyTemplate) {
+ EciesHkdfKemParams.Builder kemProtoParamsBuilder =
+ com.google.crypto.tink.proto.EciesHkdfKemParams.newBuilder()
+ .setCurveType(curveType)
+ .setHkdfHashType(hashType);
+
+ if (salt != null) {
+ kemProtoParamsBuilder.setHkdfSalt(salt);
+ }
+
+ EciesHkdfKemParams kemProtoParams = kemProtoParamsBuilder.build();
+
+ EciesAeadDemParams demProtoParams =
+ com.google.crypto.tink.proto.EciesAeadDemParams.newBuilder()
+ .setAeadDem(demKeyTemplate)
+ .build();
+
+ return EciesAeadHkdfParams.newBuilder()
+ .setKemParams(kemProtoParams)
+ .setDemParams(demProtoParams)
+ .setEcPointFormat(pointFormat)
+ .build();
+ }
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ AeadConfig.register();
+ EciesProtoSerialization.register(registry);
+ }
+
+ @Test
+ public void register_calledTwice_succeedsAndSecondCallHasNoEffect() throws Exception {
+ EciesParameters parameters =
+ EciesParameters.builder()
+ .setCurveType(EciesParameters.CurveType.NIST_P256)
+ .setHashType(EciesParameters.HashType.SHA256)
+ .setPointFormat(EciesParameters.PointFormat.UNCOMPRESSED)
+ .setVariant(EciesParameters.Variant.NO_PREFIX)
+ .setDemParameters(DEM_PARAMETERS)
+ .setSalt(SALT)
+ .build();
+
+ EciesAeadHkdfParams protoParams =
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build());
+ EciesAeadHkdfKeyFormat format =
+ EciesAeadHkdfKeyFormat.newBuilder().setParams(protoParams).build();
+ ProtoParametersSerialization serialization =
+ ProtoParametersSerialization.create(PRIVATE_TYPE_URL, OutputPrefixType.RAW, format);
+
+ MutableSerializationRegistry registry = new MutableSerializationRegistry();
+ assertThat(registry.hasParserForParameters(serialization)).isFalse();
+ assertThat(registry.hasSerializerForParameters(parameters, ProtoParametersSerialization.class))
+ .isFalse();
+
+ EciesProtoSerialization.register(registry);
+
+ assertThat(registry.hasParserForParameters(serialization)).isTrue();
+ assertThat(registry.hasSerializerForParameters(parameters, ProtoParametersSerialization.class))
+ .isTrue();
+
+ EciesProtoSerialization.register(registry);
+
+ assertThat(registry.hasParserForParameters(serialization)).isTrue();
+ assertThat(registry.hasSerializerForParameters(parameters, ProtoParametersSerialization.class))
+ .isTrue();
+ }
+
+ @Theory
+ public void serializeParseParameters(@FromDataPoints("variants") VariantTuple variantTuple)
+ throws Exception {
+ EciesParameters parameters =
+ EciesParameters.builder()
+ .setCurveType(EciesParameters.CurveType.NIST_P256)
+ .setHashType(EciesParameters.HashType.SHA256)
+ .setPointFormat(EciesParameters.PointFormat.UNCOMPRESSED)
+ .setVariant(variantTuple.variant)
+ .setDemParameters(DEM_PARAMETERS)
+ .setSalt(SALT)
+ .build();
+
+ EciesAeadHkdfParams protoParams =
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build());
+ EciesAeadHkdfKeyFormat format =
+ EciesAeadHkdfKeyFormat.newBuilder().setParams(protoParams).build();
+
+ ProtoParametersSerialization serialization =
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL, variantTuple.outputPrefixType, format);
+
+ ProtoParametersSerialization serialized =
+ registry.serializeParameters(parameters, ProtoParametersSerialization.class);
+ assertEqualWhenValueParsed(EciesAeadHkdfKeyFormat.parser(), serialized, serialization);
+
+ Parameters parsed = registry.parseParameters(serialization);
+ assertThat(parsed).isEqualTo(parameters);
+ }
+
+ @Theory
+ public void serializeParseParametersX25519() throws Exception {
+ EciesParameters parameters =
+ EciesParameters.builder()
+ .setCurveType(EciesParameters.CurveType.X25519)
+ .setHashType(EciesParameters.HashType.SHA256)
+ .setPointFormat(EciesParameters.PointFormat.COMPRESSED)
+ .setVariant(EciesParameters.Variant.NO_PREFIX)
+ .setDemParameters(DEM_PARAMETERS)
+ .build();
+
+ EciesAeadHkdfParams protoParams =
+ createEciesProtoParams(
+ EllipticCurveType.CURVE25519,
+ HashType.SHA256,
+ EcPointFormat.COMPRESSED,
+ null,
+ KeyTemplate.newBuilder()
+ .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build());
+ EciesAeadHkdfKeyFormat format =
+ EciesAeadHkdfKeyFormat.newBuilder().setParams(protoParams).build();
+
+ ProtoParametersSerialization serialization =
+ ProtoParametersSerialization.create(PRIVATE_TYPE_URL, OutputPrefixType.RAW, format);
+
+ ProtoParametersSerialization serialized =
+ registry.serializeParameters(parameters, ProtoParametersSerialization.class);
+ assertEqualWhenValueParsed(EciesAeadHkdfKeyFormat.parser(), serialized, serialization);
+
+ Parameters parsed = registry.parseParameters(serialization);
+ assertThat(parsed).isEqualTo(parameters);
+ }
+
+ @DataPoints("invalidParametersSerializations")
+ public static final ProtoParametersSerialization[] INVALID_PARAMETERS_SERIALIZATIONS =
+ new ProtoParametersSerialization[] {
+ // Unknown output prefix.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.UNKNOWN_PREFIX,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl(
+ "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build()))
+ .build()),
+ // Unknown Curve.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.TINK,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.UNKNOWN_CURVE,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl(
+ "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build()))
+ .build()),
+ // Unknown HashType.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.TINK,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.UNKNOWN_HASH,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl(
+ "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build()))
+ .build()),
+ // Unknown Point Format.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.TINK,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNKNOWN_FORMAT,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl(
+ "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build()))
+ .build()),
+ // Bad dem key template Type URL.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.TINK,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl("Non Existent Type Url")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build()))
+ .build()),
+ // Bad dem key template value.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.TINK,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl(
+ "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(ByteString.copyFrom(new byte[] {(byte) 0x80}))
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .build()))
+ .build()),
+ // Unknown dem key template prefix.
+ ProtoParametersSerialization.create(
+ PRIVATE_TYPE_URL,
+ OutputPrefixType.TINK,
+ EciesAeadHkdfKeyFormat.newBuilder()
+ .setParams(
+ createEciesProtoParams(
+ EllipticCurveType.NIST_P256,
+ HashType.SHA256,
+ EcPointFormat.UNCOMPRESSED,
+ ByteString.copyFrom(SALT.toByteArray()),
+ KeyTemplate.newBuilder()
+ .setTypeUrl(
+ "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
+ .setValue(DEM_KEY_FORMAT_PROTO.toByteString())
+ .setOutputPrefixType(OutputPrefixType.UNKNOWN_PREFIX)
+ .build()))
+ .build()),
+ // Proto messages start with a VarInt, which always ends with a byte with most
+ // significant bit unset. 0x80 is hence invalid.
+ ProtoParametersSerialization.create(
+ KeyTemplate.newBuilder()
+ .setTypeUrl(PRIVATE_TYPE_URL)
+ .setOutputPrefixType(OutputPrefixType.RAW)
+ .setValue(ByteString.copyFrom(new byte[] {(byte) 0x80}))
+ .build()),
+ };
+
+ @Theory
+ public void parseInvalidParameters_fails(
+ @FromDataPoints("invalidParametersSerializations")
+ ProtoParametersSerialization serializedParameters)
+ throws Exception {
+ assertThrows(
+ GeneralSecurityException.class, () -> registry.parseParameters(serializedParameters));
+ }
+}