diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/BUILD.bazel b/java_src/src/main/java/com/google/crypto/tink/hybrid/BUILD.bazel index c8e43ecc39..6fb727e049 100644 --- a/java_src/src/main/java/com/google/crypto/tink/hybrid/BUILD.bazel +++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/BUILD.bazel @@ -48,21 +48,6 @@ java_library( java_library( name = "ecies_aead_hkdf_public_key_manager", srcs = ["EciesAeadHkdfPublicKeyManager.java"], - deps = [ - ":hybrid_util", - ":registry_ecies_aead_hkdf_dem_helper", - "//proto:ecies_aead_hkdf_java_proto", - "//proto:tink_java_proto", - "//src/main/java/com/google/crypto/tink:hybrid_encrypt", - "//src/main/java/com/google/crypto/tink/config/internal:tink_fips_util", - "//src/main/java/com/google/crypto/tink/internal:key_type_manager", - "//src/main/java/com/google/crypto/tink/internal:primitive_factory", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_dem_helper", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_encrypt", - "//src/main/java/com/google/crypto/tink/subtle:elliptic_curves", - "//src/main/java/com/google/crypto/tink/subtle:validators", - "@maven//:com_google_protobuf_protobuf_java", - ], ) java_library( @@ -121,30 +106,34 @@ java_library( deps = [ ":ecies_aead_hkdf_public_key_manager", ":ecies_parameters", + ":ecies_private_key", ":ecies_proto_serialization", - ":hybrid_util", - ":registry_ecies_aead_hkdf_dem_helper", - "//proto:common_java_proto", + ":ecies_public_key", "//proto:ecies_aead_hkdf_java_proto", "//proto:tink_java_proto", + "//src/main/java/com/google/crypto/tink:accesses_partial_key", "//src/main/java/com/google/crypto/tink:hybrid_decrypt", + "//src/main/java/com/google/crypto/tink:hybrid_encrypt", + "//src/main/java/com/google/crypto/tink:insecure_secret_key_access", + "//src/main/java/com/google/crypto/tink:key_manager", "//src/main/java/com/google/crypto/tink:key_template", "//src/main/java/com/google/crypto/tink:parameters", - "//src/main/java/com/google/crypto/tink:registry", + "//src/main/java/com/google/crypto/tink:private_key_manager", "//src/main/java/com/google/crypto/tink/aead:aes_ctr_hmac_aead_parameters", "//src/main/java/com/google/crypto/tink/aead:aes_gcm_parameters", - "//src/main/java/com/google/crypto/tink/config/internal:tink_fips_util", - "//src/main/java/com/google/crypto/tink/internal:key_template_proto_converter", - "//src/main/java/com/google/crypto/tink/internal:key_type_manager", + "//src/main/java/com/google/crypto/tink/internal:elliptic_curves_util", + "//src/main/java/com/google/crypto/tink/internal:key_manager_registry", + "//src/main/java/com/google/crypto/tink/internal:legacy_key_manager_impl", + "//src/main/java/com/google/crypto/tink/internal:mutable_key_creation_registry", "//src/main/java/com/google/crypto/tink/internal:mutable_parameters_registry", - "//src/main/java/com/google/crypto/tink/internal:primitive_factory", - "//src/main/java/com/google/crypto/tink/internal:private_key_type_manager", + "//src/main/java/com/google/crypto/tink/internal:mutable_primitive_registry", + "//src/main/java/com/google/crypto/tink/internal:primitive_constructor", "//src/main/java/com/google/crypto/tink/internal:tink_bug_exception", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_dem_helper", "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_decrypt", + "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_encrypt", "//src/main/java/com/google/crypto/tink/subtle:elliptic_curves", - "//src/main/java/com/google/crypto/tink/subtle:validators", - "@maven//:com_google_protobuf_protobuf_java", + "//src/main/java/com/google/crypto/tink/util:secret_big_integer", + "@maven//:com_google_code_findbugs_jsr305", ], ) @@ -430,21 +419,6 @@ android_library( android_library( name = "ecies_aead_hkdf_public_key_manager-android", srcs = ["EciesAeadHkdfPublicKeyManager.java"], - deps = [ - ":hybrid_util-android", - ":registry_ecies_aead_hkdf_dem_helper-android", - "//proto:ecies_aead_hkdf_java_proto_lite", - "//proto:tink_java_proto_lite", - "//src/main/java/com/google/crypto/tink:hybrid_encrypt-android", - "//src/main/java/com/google/crypto/tink/config/internal:tink_fips_util-android", - "//src/main/java/com/google/crypto/tink/internal:key_type_manager-android", - "//src/main/java/com/google/crypto/tink/internal:primitive_factory-android", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_dem_helper-android", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_encrypt-android", - "//src/main/java/com/google/crypto/tink/subtle:elliptic_curves-android", - "//src/main/java/com/google/crypto/tink/subtle:validators-android", - "@maven//:com_google_protobuf_protobuf_javalite", - ], ) android_library( @@ -503,30 +477,34 @@ android_library( deps = [ ":ecies_aead_hkdf_public_key_manager-android", ":ecies_parameters-android", + ":ecies_private_key-android", ":ecies_proto_serialization-android", - ":hybrid_util-android", - ":registry_ecies_aead_hkdf_dem_helper-android", - "//proto:common_java_proto_lite", + ":ecies_public_key-android", "//proto:ecies_aead_hkdf_java_proto_lite", "//proto:tink_java_proto_lite", + "//src/main/java/com/google/crypto/tink:accesses_partial_key-android", "//src/main/java/com/google/crypto/tink:hybrid_decrypt-android", + "//src/main/java/com/google/crypto/tink:hybrid_encrypt-android", + "//src/main/java/com/google/crypto/tink:insecure_secret_key_access-android", + "//src/main/java/com/google/crypto/tink:key_manager-android", "//src/main/java/com/google/crypto/tink:key_template-android", "//src/main/java/com/google/crypto/tink:parameters-android", - "//src/main/java/com/google/crypto/tink:registry-android", + "//src/main/java/com/google/crypto/tink:private_key_manager-android", "//src/main/java/com/google/crypto/tink/aead:aes_ctr_hmac_aead_parameters-android", "//src/main/java/com/google/crypto/tink/aead:aes_gcm_parameters-android", - "//src/main/java/com/google/crypto/tink/config/internal:tink_fips_util-android", - "//src/main/java/com/google/crypto/tink/internal:key_template_proto_converter-android", - "//src/main/java/com/google/crypto/tink/internal:key_type_manager-android", + "//src/main/java/com/google/crypto/tink/internal:elliptic_curves_util-android", + "//src/main/java/com/google/crypto/tink/internal:key_manager_registry-android", + "//src/main/java/com/google/crypto/tink/internal:legacy_key_manager_impl-android", + "//src/main/java/com/google/crypto/tink/internal:mutable_key_creation_registry-android", "//src/main/java/com/google/crypto/tink/internal:mutable_parameters_registry-android", - "//src/main/java/com/google/crypto/tink/internal:primitive_factory-android", - "//src/main/java/com/google/crypto/tink/internal:private_key_type_manager-android", + "//src/main/java/com/google/crypto/tink/internal:mutable_primitive_registry-android", + "//src/main/java/com/google/crypto/tink/internal:primitive_constructor-android", "//src/main/java/com/google/crypto/tink/internal:tink_bug_exception-android", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_dem_helper-android", "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_decrypt-android", + "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_encrypt-android", "//src/main/java/com/google/crypto/tink/subtle:elliptic_curves-android", - "//src/main/java/com/google/crypto/tink/subtle:validators-android", - "@maven//:com_google_protobuf_protobuf_javalite", + "//src/main/java/com/google/crypto/tink/util:secret_big_integer-android", + "@maven//:com_google_code_findbugs_jsr305", ], ) diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManager.java b/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManager.java index 168ff1203b..87cdc1cec3 100644 --- a/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManager.java +++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManager.java @@ -1,4 +1,4 @@ -// Copyright 2017 Google Inc. +// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,162 +18,101 @@ import static com.google.crypto.tink.internal.TinkBugException.exceptionIsBug; +import com.google.crypto.tink.AccessesPartialKey; import com.google.crypto.tink.HybridDecrypt; +import com.google.crypto.tink.HybridEncrypt; +import com.google.crypto.tink.InsecureSecretKeyAccess; +import com.google.crypto.tink.KeyManager; import com.google.crypto.tink.KeyTemplate; import com.google.crypto.tink.Parameters; -import com.google.crypto.tink.Registry; +import com.google.crypto.tink.PrivateKeyManager; import com.google.crypto.tink.aead.AesCtrHmacAeadParameters; import com.google.crypto.tink.aead.AesGcmParameters; -import com.google.crypto.tink.config.internal.TinkFipsUtil; -import com.google.crypto.tink.internal.KeyTemplateProtoConverter; -import com.google.crypto.tink.internal.KeyTypeManager; +import com.google.crypto.tink.internal.EllipticCurvesUtil; +import com.google.crypto.tink.internal.KeyManagerRegistry; +import com.google.crypto.tink.internal.LegacyKeyManagerImpl; +import com.google.crypto.tink.internal.MutableKeyCreationRegistry; import com.google.crypto.tink.internal.MutableParametersRegistry; -import com.google.crypto.tink.internal.PrimitiveFactory; -import com.google.crypto.tink.internal.PrivateKeyTypeManager; -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.EciesAeadHkdfPrivateKey; -import com.google.crypto.tink.proto.EciesAeadHkdfPublicKey; -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.internal.MutablePrimitiveRegistry; +import com.google.crypto.tink.internal.PrimitiveConstructor; import com.google.crypto.tink.proto.KeyData.KeyMaterialType; -import com.google.crypto.tink.subtle.EciesAeadHkdfDemHelper; import com.google.crypto.tink.subtle.EciesAeadHkdfHybridDecrypt; +import com.google.crypto.tink.subtle.EciesAeadHkdfHybridEncrypt; import com.google.crypto.tink.subtle.EllipticCurves; -import com.google.crypto.tink.subtle.Validators; -import com.google.protobuf.ByteString; -import com.google.protobuf.ExtensionRegistryLite; -import com.google.protobuf.InvalidProtocolBufferException; +import com.google.crypto.tink.util.SecretBigInteger; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; -import java.security.spec.ECPoint; +import java.security.spec.ECParameterSpec; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nullable; /** * This key manager generates new {@code EciesAeadHkdfPrivateKey} keys and produces new instances of * {@code EciesAeadHkdfHybridDecrypt}. */ -public final class EciesAeadHkdfPrivateKeyManager - extends PrivateKeyTypeManager { - EciesAeadHkdfPrivateKeyManager() { - super( - EciesAeadHkdfPrivateKey.class, - EciesAeadHkdfPublicKey.class, - new PrimitiveFactory(HybridDecrypt.class) { - @Override - public HybridDecrypt getPrimitive(EciesAeadHkdfPrivateKey recipientKeyProto) - throws GeneralSecurityException { - EciesAeadHkdfParams eciesParams = recipientKeyProto.getPublicKey().getParams(); - EciesHkdfKemParams kemParams = eciesParams.getKemParams(); +public final class EciesAeadHkdfPrivateKeyManager { + private static final PrimitiveConstructor + HYBRID_DECRYPT_PRIMITIVE_CONSTRUCTOR = + PrimitiveConstructor.create( + EciesAeadHkdfHybridDecrypt::create, EciesPrivateKey.class, HybridDecrypt.class); - ECPrivateKey recipientPrivateKey = - EllipticCurves.getEcPrivateKey( - HybridUtil.toCurveType(kemParams.getCurveType()), - recipientKeyProto.getKeyValue().toByteArray()); - EciesAeadHkdfDemHelper demHelper = - new RegistryEciesAeadHkdfDemHelper(eciesParams.getDemParams().getAeadDem()); - return new EciesAeadHkdfHybridDecrypt( - recipientPrivateKey, - kemParams.getHkdfSalt().toByteArray(), - HybridUtil.toHmacAlgo(kemParams.getHkdfHashType()), - HybridUtil.toPointFormatType(eciesParams.getEcPointFormat()), - demHelper); - } - }); - } - - @Override - public TinkFipsUtil.AlgorithmFipsCompatibility fipsStatus() { - return TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_NOT_FIPS; - } + private static final PrimitiveConstructor + HYBRID_ENCRYPT_PRIMITIVE_CONSTRUCTOR = + PrimitiveConstructor.create( + EciesAeadHkdfHybridEncrypt::create, EciesPublicKey.class, HybridEncrypt.class); - @Override - public String getKeyType() { - return "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey"; - } + private static final PrivateKeyManager legacyPrivateKeyManager = + LegacyKeyManagerImpl.createPrivateKeyManager( + getKeyType(), + HybridDecrypt.class, + com.google.crypto.tink.proto.EciesAeadHkdfPrivateKey.parser()); - @Override - public int getVersion() { - return 0; - } + private static final KeyManager legacyPublicKeyManager = + LegacyKeyManagerImpl.create( + EciesAeadHkdfPublicKeyManager.getKeyType(), + HybridEncrypt.class, + KeyMaterialType.ASYMMETRIC_PUBLIC, + com.google.crypto.tink.proto.EciesAeadHkdfPublicKey.parser()); - @Override - public EciesAeadHkdfPublicKey getPublicKey(EciesAeadHkdfPrivateKey key) + private static final ECParameterSpec toParameterSpec(EciesParameters.CurveType curveType) throws GeneralSecurityException { - return key.getPublicKey(); - } - - @Override - public KeyMaterialType keyMaterialType() { - return KeyMaterialType.ASYMMETRIC_PRIVATE; - } - - @Override - public EciesAeadHkdfPrivateKey parseKey(ByteString byteString) - throws InvalidProtocolBufferException { - return EciesAeadHkdfPrivateKey.parseFrom(byteString, ExtensionRegistryLite.getEmptyRegistry()); - } - - @Override - public void validateKey(EciesAeadHkdfPrivateKey keyProto) throws GeneralSecurityException { - if (keyProto.getKeyValue().isEmpty()) { - throw new GeneralSecurityException("invalid ECIES private key"); + if (curveType == EciesParameters.CurveType.NIST_P256) { + return EllipticCurvesUtil.NIST_P256_PARAMS; + } + if (curveType == EciesParameters.CurveType.NIST_P384) { + return EllipticCurvesUtil.NIST_P384_PARAMS; } - Validators.validateVersion(keyProto.getVersion(), getVersion()); - HybridUtil.validate(keyProto.getPublicKey().getParams()); + if (curveType == EciesParameters.CurveType.NIST_P521) { + return EllipticCurvesUtil.NIST_P521_PARAMS; + } + throw new GeneralSecurityException("Unsupported curve type: " + curveType); } - @Override - public KeyTypeManager.KeyFactory keyFactory() { - return new KeyTypeManager.KeyFactory( - EciesAeadHkdfKeyFormat.class) { - @Override - public void validateKeyFormat(EciesAeadHkdfKeyFormat eciesKeyFormat) - throws GeneralSecurityException { - HybridUtil.validate(eciesKeyFormat.getParams()); - } - - @Override - public EciesAeadHkdfKeyFormat parseKeyFormat(ByteString byteString) - throws InvalidProtocolBufferException { - return EciesAeadHkdfKeyFormat.parseFrom( - byteString, ExtensionRegistryLite.getEmptyRegistry()); - } + @AccessesPartialKey + private static EciesPrivateKey createKey( + EciesParameters parameters, @Nullable Integer idRequirement) throws GeneralSecurityException { + // toParameterSpec throws for curve X25519 + KeyPair keyPair = EllipticCurves.generateKeyPair(toParameterSpec(parameters.getCurveType())); + ECPublicKey ecPubKey = (ECPublicKey) keyPair.getPublic(); + ECPrivateKey ecPrivKey = (ECPrivateKey) keyPair.getPrivate(); - @Override - public EciesAeadHkdfPrivateKey createKey(EciesAeadHkdfKeyFormat eciesKeyFormat) - throws GeneralSecurityException { - EciesHkdfKemParams kemParams = eciesKeyFormat.getParams().getKemParams(); - KeyPair keyPair = - EllipticCurves.generateKeyPair(HybridUtil.toCurveType(kemParams.getCurveType())); - ECPublicKey pubKey = (ECPublicKey) keyPair.getPublic(); - ECPrivateKey privKey = (ECPrivateKey) keyPair.getPrivate(); - ECPoint w = pubKey.getW(); + EciesPublicKey publicKey = + EciesPublicKey.createForNistCurve(parameters, ecPubKey.getW(), idRequirement); + return EciesPrivateKey.createForNistCurve( + publicKey, + SecretBigInteger.fromBigInteger(ecPrivKey.getS(), InsecureSecretKeyAccess.get())); + } - // Creates EciesAeadHkdfPublicKey. - EciesAeadHkdfPublicKey eciesPublicKey = - EciesAeadHkdfPublicKey.newBuilder() - .setVersion(getVersion()) - .setParams(eciesKeyFormat.getParams()) - .setX(ByteString.copyFrom(w.getAffineX().toByteArray())) - .setY(ByteString.copyFrom(w.getAffineY().toByteArray())) - .build(); + @SuppressWarnings("InlineLambdaConstant") // We need a correct Object#equals in registration. + private static final MutableKeyCreationRegistry.KeyCreator KEY_CREATOR = + EciesAeadHkdfPrivateKeyManager::createKey; - // Creates EciesAeadHkdfPrivateKey. - return EciesAeadHkdfPrivateKey.newBuilder() - .setVersion(getVersion()) - .setPublicKey(eciesPublicKey) - .setKeyValue(ByteString.copyFrom(privKey.getS().toByteArray())) - .build(); - } - }; + static String getKeyType() { + return "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey"; } private static Map namedParameters() throws GeneralSecurityException { @@ -331,10 +270,15 @@ private static Map namedParameters() throws GeneralSecurityE * with Tink. */ public static void registerPair(boolean newKeyAllowed) throws GeneralSecurityException { - Registry.registerAsymmetricKeyManagers( - new EciesAeadHkdfPrivateKeyManager(), new EciesAeadHkdfPublicKeyManager(), newKeyAllowed); EciesProtoSerialization.register(); MutableParametersRegistry.globalInstance().putAll(namedParameters()); + MutablePrimitiveRegistry.globalInstance() + .registerPrimitiveConstructor(HYBRID_DECRYPT_PRIMITIVE_CONSTRUCTOR); + MutablePrimitiveRegistry.globalInstance() + .registerPrimitiveConstructor(HYBRID_ENCRYPT_PRIMITIVE_CONSTRUCTOR); + MutableKeyCreationRegistry.globalInstance().add(KEY_CREATOR, EciesParameters.class); + KeyManagerRegistry.globalInstance().registerKeyManager(legacyPrivateKeyManager, newKeyAllowed); + KeyManagerRegistry.globalInstance().registerKeyManager(legacyPublicKeyManager, false); } /** @@ -480,28 +424,5 @@ public static final KeyTemplate eciesP256HkdfHmacSha256Aes128CtrHmacSha256Templa .build())); } - /** - * @return a {@link EciesAeadHkdfParams} with the specified parameters. - */ - static EciesAeadHkdfParams createParams( - EllipticCurveType curve, - HashType hashType, - EcPointFormat ecPointFormat, - KeyTemplate demKeyTemplate, - byte[] salt) { - EciesHkdfKemParams kemParams = - EciesHkdfKemParams.newBuilder() - .setCurveType(curve) - .setHkdfHashType(hashType) - .setHkdfSalt(ByteString.copyFrom(salt)) - .build(); - com.google.crypto.tink.proto.KeyTemplate protoKt = - exceptionIsBug(() -> KeyTemplateProtoConverter.toProto(demKeyTemplate)); - EciesAeadDemParams demParams = EciesAeadDemParams.newBuilder().setAeadDem(protoKt).build(); - return EciesAeadHkdfParams.newBuilder() - .setKemParams(kemParams) - .setDemParams(demParams) - .setEcPointFormat(ecPointFormat) - .build(); - } + private EciesAeadHkdfPrivateKeyManager() {} } diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManager.java b/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManager.java index df1b8ca2ab..271f7509d6 100644 --- a/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManager.java +++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManager.java @@ -1,4 +1,4 @@ -// Copyright 2017 Google Inc. +// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,85 +16,11 @@ package com.google.crypto.tink.hybrid; -import com.google.crypto.tink.HybridEncrypt; -import com.google.crypto.tink.config.internal.TinkFipsUtil; -import com.google.crypto.tink.internal.KeyTypeManager; -import com.google.crypto.tink.internal.PrimitiveFactory; -import com.google.crypto.tink.proto.EciesAeadHkdfParams; -import com.google.crypto.tink.proto.EciesAeadHkdfPublicKey; -import com.google.crypto.tink.proto.EciesHkdfKemParams; -import com.google.crypto.tink.proto.KeyData.KeyMaterialType; -import com.google.crypto.tink.subtle.EciesAeadHkdfDemHelper; -import com.google.crypto.tink.subtle.EciesAeadHkdfHybridEncrypt; -import com.google.crypto.tink.subtle.EllipticCurves; -import com.google.crypto.tink.subtle.Validators; -import com.google.protobuf.ByteString; -import com.google.protobuf.ExtensionRegistryLite; -import com.google.protobuf.InvalidProtocolBufferException; -import java.security.GeneralSecurityException; -import java.security.interfaces.ECPublicKey; - -/** - * This key manager produces new instances of {@code EciesAeadHkdfHybridEncrypt}. It doesn't support - * key generation. - */ -class EciesAeadHkdfPublicKeyManager extends KeyTypeManager { - public EciesAeadHkdfPublicKeyManager() { - super( - EciesAeadHkdfPublicKey.class, - new PrimitiveFactory(HybridEncrypt.class) { - @Override - public HybridEncrypt getPrimitive(EciesAeadHkdfPublicKey recipientKeyProto) - throws GeneralSecurityException { - EciesAeadHkdfParams eciesParams = recipientKeyProto.getParams(); - EciesHkdfKemParams kemParams = eciesParams.getKemParams(); - ECPublicKey recipientPublicKey = - EllipticCurves.getEcPublicKey( - HybridUtil.toCurveType(kemParams.getCurveType()), - recipientKeyProto.getX().toByteArray(), - recipientKeyProto.getY().toByteArray()); - EciesAeadHkdfDemHelper demHelper = - new RegistryEciesAeadHkdfDemHelper(eciesParams.getDemParams().getAeadDem()); - return new EciesAeadHkdfHybridEncrypt( - recipientPublicKey, - kemParams.getHkdfSalt().toByteArray(), - HybridUtil.toHmacAlgo(kemParams.getHkdfHashType()), - HybridUtil.toPointFormatType(eciesParams.getEcPointFormat()), - demHelper); - } - }); - } - - @Override - public TinkFipsUtil.AlgorithmFipsCompatibility fipsStatus() { - return TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_NOT_FIPS; - } - - @Override - public String getKeyType() { +/** This class is only here for legacy reasons and should be removed. */ +class EciesAeadHkdfPublicKeyManager { + static String getKeyType() { return "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey"; } - @Override - public int getVersion() { - return 0; - } - - @Override - public KeyMaterialType keyMaterialType() { - return KeyMaterialType.ASYMMETRIC_PUBLIC; - } - - @Override - public EciesAeadHkdfPublicKey parseKey(ByteString byteString) - throws InvalidProtocolBufferException { - return EciesAeadHkdfPublicKey.parseFrom(byteString, ExtensionRegistryLite.getEmptyRegistry()); - } - - @Override - public void validateKey(EciesAeadHkdfPublicKey key) throws GeneralSecurityException { - // TODO(b/74251423): add more checks. - Validators.validateVersion(key.getVersion(), getVersion()); - HybridUtil.validate(key.getParams()); - } + private EciesAeadHkdfPublicKeyManager() {} } diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/HybridKeyTemplates.java b/java_src/src/main/java/com/google/crypto/tink/hybrid/HybridKeyTemplates.java index a5cf5bd016..5443643e32 100644 --- a/java_src/src/main/java/com/google/crypto/tink/hybrid/HybridKeyTemplates.java +++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/HybridKeyTemplates.java @@ -152,7 +152,7 @@ public static KeyTemplate createEciesAeadHkdfKeyTemplate( createEciesAeadHkdfParams(curve, hashType, ecPointFormat, demKeyTemplate, salt)) .build(); return KeyTemplate.newBuilder() - .setTypeUrl(new EciesAeadHkdfPrivateKeyManager().getKeyType()) + .setTypeUrl(EciesAeadHkdfPrivateKeyManager.getKeyType()) .setOutputPrefixType(outputPrefixType) .setValue(format.toByteString()) .build(); 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 618d079647..e1d5d6d378 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 @@ -193,34 +193,31 @@ java_test( size = "small", srcs = ["EciesAeadHkdfPrivateKeyManagerTest.java"], deps = [ - "//proto:common_java_proto", - "//proto:ecies_aead_hkdf_java_proto", - "//proto:tink_java_proto", "//src/main/java/com/google/crypto/tink:hybrid_decrypt", "//src/main/java/com/google/crypto/tink:hybrid_encrypt", + "//src/main/java/com/google/crypto/tink:insecure_secret_key_access", "//src/main/java/com/google/crypto/tink:key_template", "//src/main/java/com/google/crypto/tink:key_templates", "//src/main/java/com/google/crypto/tink:parameters", "//src/main/java/com/google/crypto/tink:registry_cluster", + "//src/main/java/com/google/crypto/tink:tink_proto_keyset_format", "//src/main/java/com/google/crypto/tink/aead:aead_config", - "//src/main/java/com/google/crypto/tink/aead:aes_ctr_hmac_aead_key_manager", "//src/main/java/com/google/crypto/tink/aead:aes_ctr_hmac_aead_parameters", "//src/main/java/com/google/crypto/tink/aead:aes_gcm_parameters", + "//src/main/java/com/google/crypto/tink/aead:x_cha_cha20_poly1305_parameters", "//src/main/java/com/google/crypto/tink/hybrid:ecies_aead_hkdf_private_key_manager", "//src/main/java/com/google/crypto/tink/hybrid:ecies_parameters", + "//src/main/java/com/google/crypto/tink/hybrid:ecies_private_key", + "//src/main/java/com/google/crypto/tink/hybrid:ecies_public_key", "//src/main/java/com/google/crypto/tink/hybrid:hybrid_config", - "//src/main/java/com/google/crypto/tink/hybrid:hybrid_util", - "//src/main/java/com/google/crypto/tink/hybrid:registry_ecies_aead_hkdf_dem_helper", "//src/main/java/com/google/crypto/tink/hybrid/internal/testing:ecies_aead_hkdf_test_util", "//src/main/java/com/google/crypto/tink/hybrid/internal/testing:hybrid_test_vector", - "//src/main/java/com/google/crypto/tink/internal:key_type_manager", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_dem_helper", - "//src/main/java/com/google/crypto/tink/subtle:ecies_aead_hkdf_hybrid_encrypt", - "//src/main/java/com/google/crypto/tink/subtle:elliptic_curves", + "//src/main/java/com/google/crypto/tink/internal:key_manager_registry", "//src/main/java/com/google/crypto/tink/subtle:hex", - "//src/main/java/com/google/crypto/tink/subtle:random", + "//src/main/java/com/google/crypto/tink/subtle:x25519", + "//src/main/java/com/google/crypto/tink/util:bytes", + "//src/main/java/com/google/crypto/tink/util:secret_bytes", "@maven//:com_google_code_findbugs_jsr305", - "@maven//:com_google_protobuf_protobuf_java", "@maven//:com_google_truth_truth", "@maven//:junit_junit", ], @@ -256,28 +253,6 @@ java_test( ], ) -java_test( - name = "EciesAeadHkdfPublicKeyManagerTest", - size = "small", - srcs = ["EciesAeadHkdfPublicKeyManagerTest.java"], - deps = [ - "//proto:common_java_proto", - "//proto:ecies_aead_hkdf_java_proto", - "//proto:tink_java_proto", - "//src/main/java/com/google/crypto/tink:hybrid_decrypt", - "//src/main/java/com/google/crypto/tink:hybrid_encrypt", - "//src/main/java/com/google/crypto/tink/aead:aead_config", - "//src/main/java/com/google/crypto/tink/aead:aead_key_templates", - "//src/main/java/com/google/crypto/tink/hybrid:ecies_aead_hkdf_private_key_manager", - "//src/main/java/com/google/crypto/tink/hybrid:ecies_aead_hkdf_public_key_manager", - "//src/main/java/com/google/crypto/tink/internal:key_type_manager", - "//src/main/java/com/google/crypto/tink/subtle:random", - "@maven//:com_google_protobuf_protobuf_java", - "@maven//:com_google_truth_truth", - "@maven//:junit_junit", - ], -) - java_test( name = "HybridTest", size = "small", diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManagerTest.java b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManagerTest.java index 9fb27e1b10..2f3f0f3a16 100644 --- a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManagerTest.java +++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPrivateKeyManagerTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 Google Inc. +// Copyright 2017 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,37 +21,28 @@ import com.google.crypto.tink.HybridDecrypt; import com.google.crypto.tink.HybridEncrypt; +import com.google.crypto.tink.InsecureSecretKeyAccess; import com.google.crypto.tink.KeyTemplate; import com.google.crypto.tink.KeyTemplates; import com.google.crypto.tink.KeysetHandle; import com.google.crypto.tink.Parameters; +import com.google.crypto.tink.TinkProtoKeysetFormat; import com.google.crypto.tink.aead.AeadConfig; -import com.google.crypto.tink.aead.AesCtrHmacAeadKeyManager; import com.google.crypto.tink.aead.AesCtrHmacAeadParameters; import com.google.crypto.tink.aead.AesGcmParameters; +import com.google.crypto.tink.aead.XChaCha20Poly1305Parameters; import com.google.crypto.tink.hybrid.internal.testing.EciesAeadHkdfTestUtil; import com.google.crypto.tink.hybrid.internal.testing.HybridTestVector; -import com.google.crypto.tink.internal.KeyTypeManager; -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.EciesAeadHkdfPrivateKey; -import com.google.crypto.tink.proto.EciesAeadHkdfPublicKey; -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.KeyData.KeyMaterialType; -import com.google.crypto.tink.proto.OutputPrefixType; -import com.google.crypto.tink.subtle.EciesAeadHkdfDemHelper; -import com.google.crypto.tink.subtle.EciesAeadHkdfHybridEncrypt; -import com.google.crypto.tink.subtle.EllipticCurves; +import com.google.crypto.tink.internal.KeyManagerRegistry; import com.google.crypto.tink.subtle.Hex; -import com.google.crypto.tink.subtle.Random; -import com.google.protobuf.ByteString; +import com.google.crypto.tink.subtle.X25519; +import com.google.crypto.tink.util.Bytes; +import com.google.crypto.tink.util.SecretBytes; +import java.math.BigInteger; import java.security.GeneralSecurityException; -import java.security.interfaces.ECPublicKey; import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; import javax.annotation.Nullable; import org.junit.BeforeClass; import org.junit.Test; @@ -70,182 +61,6 @@ public static void setUp() throws Exception { HybridConfig.register(); } - private final EciesAeadHkdfPrivateKeyManager manager = new EciesAeadHkdfPrivateKeyManager(); - private final KeyTypeManager.KeyFactory factory = - manager.keyFactory(); - - @Test - public void basics() throws Exception { - assertThat(manager.getKeyType()) - .isEqualTo("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey"); - assertThat(manager.getVersion()).isEqualTo(0); - assertThat(manager.keyMaterialType()).isEqualTo(KeyMaterialType.ASYMMETRIC_PRIVATE); - } - - @Test - public void validateKeyFormat_empty() throws Exception { - assertThrows( - GeneralSecurityException.class, - () -> factory.validateKeyFormat(EciesAeadHkdfKeyFormat.getDefaultInstance())); - } - - private static EciesAeadHkdfKeyFormat createKeyFormat( - EllipticCurveType curve, - HashType hashType, - EcPointFormat ecPointFormat, - KeyTemplate demKeyTemplate, - byte[] salt) { - - return EciesAeadHkdfKeyFormat.newBuilder() - .setParams( - EciesAeadHkdfPrivateKeyManager.createParams( - curve, hashType, ecPointFormat, demKeyTemplate, salt)) - .build(); - } - - @Test - public void validateKeyFormat_valid() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.SHA256, - EcPointFormat.UNCOMPRESSED, - AesCtrHmacAeadKeyManager.aes128CtrHmacSha256Template(), - Hex.decode("aabbccddeeff")); - factory.validateKeyFormat(format); - } - - @Test - public void validateKeyFormat_noPointFormat_throws() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.SHA256, - EcPointFormat.UNKNOWN_FORMAT, - AesCtrHmacAeadKeyManager.aes128CtrHmacSha256Template(), - Hex.decode("aabbccddeeff")); - assertThrows(GeneralSecurityException.class, () -> factory.validateKeyFormat(format)); - } - - @Test - public void validateKeyFormat_noDem_throws() throws Exception { - EciesAeadHkdfKeyFormat format = - EciesAeadHkdfKeyFormat.newBuilder() - .setParams( - EciesAeadHkdfParams.newBuilder() - .setKemParams( - EciesHkdfKemParams.newBuilder() - .setCurveType(EllipticCurveType.NIST_P256) - .setHkdfHashType(HashType.SHA256) - .setHkdfSalt(ByteString.copyFrom(Hex.decode("aabbccddeeff")))) - .setDemParams( - EciesAeadDemParams.newBuilder() - .setAeadDem( - com.google.crypto.tink.proto.KeyTemplate.newBuilder() - .setOutputPrefixType(OutputPrefixType.TINK))) - .setEcPointFormat(EcPointFormat.UNCOMPRESSED)) - .build(); - assertThrows(GeneralSecurityException.class, () -> factory.validateKeyFormat(format)); - } - - @Test - public void validateKeyFormat_noKemCurve_throws() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.UNKNOWN_CURVE, - HashType.SHA256, - EcPointFormat.UNCOMPRESSED, - AesCtrHmacAeadKeyManager.aes128CtrHmacSha256Template(), - Hex.decode("aabbccddeeff")); - assertThrows(GeneralSecurityException.class, () -> factory.validateKeyFormat(format)); - } - - @Test - public void validateKeyFormat_noKemHash_throws() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.UNKNOWN_HASH, - EcPointFormat.UNCOMPRESSED, - AesCtrHmacAeadKeyManager.aes128CtrHmacSha256Template(), - Hex.decode("aabbccddeeff")); - assertThrows(GeneralSecurityException.class, () -> factory.validateKeyFormat(format)); - } - - @Test - public void createKey_checkValues() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.SHA256, - EcPointFormat.UNCOMPRESSED, - AesCtrHmacAeadKeyManager.aes128CtrHmacSha256Template(), - Hex.decode("aabbccddeeff")); - EciesAeadHkdfPrivateKey key = factory.createKey(format); - assertThat(key.getPublicKey().getParams()).isEqualTo(format.getParams()); - assertThat(key.getPublicKey().getX()).isNotEmpty(); - assertThat(key.getPublicKey().getY()).isNotEmpty(); - assertThat(key.getKeyValue()).isNotEmpty(); - } - - private EciesAeadHkdfPrivateKey createValidKey() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.SHA256, - EcPointFormat.UNCOMPRESSED, - AesCtrHmacAeadKeyManager.aes128CtrHmacSha256Template(), - Hex.decode("aabbccddeeff")); - return factory.createKey(format); - } - - @Test - public void validateKey_valid() throws Exception { - manager.validateKey(createValidKey()); - } - - @Test - public void validateKey_invalidVersion_throws() throws Exception { - EciesAeadHkdfPrivateKey key = - EciesAeadHkdfPrivateKey.newBuilder(createValidKey()).setVersion(1).build(); - assertThrows(GeneralSecurityException.class, () -> manager.validateKey(key)); - } - - @Test - public void getPublicKey_values() throws Exception { - EciesAeadHkdfPrivateKey key = createValidKey(); - EciesAeadHkdfPublicKey publicKey = manager.getPublicKey(key); - - assertThat(publicKey).isEqualTo(key.getPublicKey()); - } - - @Test - public void createPrimitive() throws Exception { - EciesAeadHkdfPrivateKey key = createValidKey(); - HybridDecrypt hybridDecrypt = manager.getPrimitive(key, HybridDecrypt.class); - - EciesAeadHkdfParams eciesParams = key.getPublicKey().getParams(); - EciesHkdfKemParams kemParams = eciesParams.getKemParams(); - ECPublicKey recipientPublicKey = - EllipticCurves.getEcPublicKey( - HybridUtil.toCurveType(kemParams.getCurveType()), - key.getPublicKey().getX().toByteArray(), - key.getPublicKey().getY().toByteArray()); - EciesAeadHkdfDemHelper demHelper = - new RegistryEciesAeadHkdfDemHelper(eciesParams.getDemParams().getAeadDem()); - HybridEncrypt hybridEncrypt = new EciesAeadHkdfHybridEncrypt( - recipientPublicKey, - kemParams.getHkdfSalt().toByteArray(), - HybridUtil.toHmacAlgo(kemParams.getHkdfHashType()), - HybridUtil.toPointFormatType(eciesParams.getEcPointFormat()), - demHelper); - - byte[] message = Random.randBytes(20); - byte[] contextInfo = Random.randBytes(20); - assertThat(hybridDecrypt.decrypt(hybridEncrypt.encrypt(message, contextInfo), contextInfo)) - .isEqualTo(message); - } - @Test public void testEciesP256HkdfHmacSha256Aes128GcmTemplate() throws Exception { KeyTemplate template = @@ -382,6 +197,65 @@ public void testTemplates(@FromDataPoints("templateNames") String templateName) .isEqualTo(KeyTemplates.get(templateName).toParameters()); } + @Test + public void createKey_nistCurve_alwaysDifferent() throws Exception { + Parameters params = KeyTemplates.get("ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM").toParameters(); + + int numKeys = 10; + Set keys = new TreeSet<>(); + for (int i = 0; i < numKeys; i++) { + KeysetHandle handle = KeysetHandle.generateNew(params); + assertThat(handle.size()).isEqualTo(1); + EciesPrivateKey key = (EciesPrivateKey) handle.getPrimary().getKey(); + keys.add(key.getNistPrivateKeyValue().getBigInteger(InsecureSecretKeyAccess.get())); + } + assertThat(keys).hasSize(numKeys); + } + + @Test + public void createKey_x25519Curve_throws() throws Exception { + Parameters params = + EciesParameters.builder() + .setCurveType(EciesParameters.CurveType.X25519) + .setHashType(EciesParameters.HashType.SHA256) + .setVariant(EciesParameters.Variant.NO_PREFIX) + .setDemParameters( + AesGcmParameters.builder() + .setIvSizeBytes(12) + .setKeySizeBytes(16) + .setTagSizeBytes(16) + .setVariant(AesGcmParameters.Variant.NO_PREFIX) + .build()) + .build(); + assertThrows(GeneralSecurityException.class, () -> KeysetHandle.generateNew(params)); + } + + @Test + public void createPrimitive_x25519Curve_throws() throws Exception { + EciesParameters params = + EciesParameters.builder() + .setHashType(EciesParameters.HashType.SHA256) + .setCurveType(EciesParameters.CurveType.X25519) + .setVariant(EciesParameters.Variant.NO_PREFIX) + .setDemParameters(XChaCha20Poly1305Parameters.create()) + .build(); + + byte[] privateKeyBytes = X25519.generatePrivateKey(); + byte[] publicKeyBytes = X25519.publicFromPrivate(privateKeyBytes); + + EciesPublicKey publicKey = + EciesPublicKey.createForCurveX25519( + params, Bytes.copyFrom(publicKeyBytes), /* idRequirement= */ null); + EciesPrivateKey privateKey = + EciesPrivateKey.createForCurveX25519( + publicKey, SecretBytes.copyFrom(privateKeyBytes, InsecureSecretKeyAccess.get())); + + KeysetHandle.Builder.Entry entry = + KeysetHandle.importKey(privateKey).makePrimary().withRandomId(); + KeysetHandle handle = KeysetHandle.newBuilder().addEntry(entry).build(); + assertThrows(GeneralSecurityException.class, () -> handle.getPrimitive(HybridDecrypt.class)); + } + @DataPoints("testVectors") public static final HybridTestVector[] HYBRID_TEST_VECTORS = EciesAeadHkdfTestUtil.createEciesTestVectors(); @@ -444,4 +318,46 @@ public void test_encryptThenDecryptMessage_works( byte[] plaintext = hybridDecrypt.decrypt(ciphertext, v.getContextInfo()); assertThat(Hex.encode(plaintext)).isEqualTo(Hex.encode(v.getPlaintext())); } + + @Test + public void test_serializeAndParse_works() throws Exception { + HybridTestVector testVector = HYBRID_TEST_VECTORS[0]; + EciesPrivateKey key = (EciesPrivateKey) testVector.getPrivateKey(); + KeysetHandle.Builder.Entry entry = KeysetHandle.importKey(key).withFixedId(1216).makePrimary(); + KeysetHandle handle = KeysetHandle.newBuilder().addEntry(entry).build(); + + byte[] serializedHandle = + TinkProtoKeysetFormat.serializeKeyset(handle, InsecureSecretKeyAccess.get()); + KeysetHandle parsedHandle = + TinkProtoKeysetFormat.parseKeyset(serializedHandle, InsecureSecretKeyAccess.get()); + assertThat(parsedHandle.equalsKeyset(handle)).isTrue(); + } + + @Test + public void test_serializeAndParse_publicKey_works() throws Exception { + HybridTestVector testVector = HYBRID_TEST_VECTORS[0]; + EciesPrivateKey key = (EciesPrivateKey) testVector.getPrivateKey(); + KeysetHandle.Builder.Entry entry = KeysetHandle.importKey(key).withFixedId(1216).makePrimary(); + KeysetHandle handle = KeysetHandle.newBuilder().addEntry(entry).build().getPublicKeysetHandle(); + + byte[] serializedHandle = TinkProtoKeysetFormat.serializeKeysetWithoutSecret(handle); + KeysetHandle parsedHandle = TinkProtoKeysetFormat.parseKeysetWithoutSecret(serializedHandle); + assertThat(parsedHandle.equalsKeyset(handle)).isTrue(); + } + + @Test + public void testKeyManagerRegistered() throws Exception { + assertThat( + KeyManagerRegistry.globalInstance() + .getKeyManager( + "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey", + HybridDecrypt.class)) + .isNotNull(); + assertThat( + KeyManagerRegistry.globalInstance() + .getKeyManager( + "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey", + HybridEncrypt.class)) + .isNotNull(); + } } diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManagerTest.java b/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManagerTest.java deleted file mode 100644 index 467201aafe..0000000000 --- a/java_src/src/test/java/com/google/crypto/tink/hybrid/EciesAeadHkdfPublicKeyManagerTest.java +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2020 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 org.junit.Assert.assertThrows; - -import com.google.crypto.tink.HybridDecrypt; -import com.google.crypto.tink.HybridEncrypt; -import com.google.crypto.tink.aead.AeadConfig; -import com.google.crypto.tink.aead.AeadKeyTemplates; -import com.google.crypto.tink.internal.KeyTypeManager; -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.EciesAeadHkdfPrivateKey; -import com.google.crypto.tink.proto.EciesAeadHkdfPublicKey; -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.KeyData.KeyMaterialType; -import com.google.crypto.tink.proto.KeyTemplate; -import com.google.crypto.tink.subtle.Random; -import com.google.protobuf.ByteString; -import java.security.GeneralSecurityException; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for RsaSsaPssVerifyKeyManager. */ -@RunWith(JUnit4.class) -public final class EciesAeadHkdfPublicKeyManagerTest { - private final EciesAeadHkdfPrivateKeyManager privateManager = - new EciesAeadHkdfPrivateKeyManager(); - private final KeyTypeManager.KeyFactory factory = - privateManager.keyFactory(); - private final EciesAeadHkdfPublicKeyManager publicManager = new EciesAeadHkdfPublicKeyManager(); - - @BeforeClass - public static void setUp() throws Exception { - AeadConfig.register(); - } - - @Test - public void basics() throws Exception { - assertThat(publicManager.getKeyType()) - .isEqualTo("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey"); - assertThat(publicManager.getVersion()).isEqualTo(0); - assertThat(publicManager.keyMaterialType()).isEqualTo(KeyMaterialType.ASYMMETRIC_PUBLIC); - } - - @Test - public void validateKey_empty_throws() throws Exception { - assertThrows( - GeneralSecurityException.class, - () -> publicManager.validateKey(EciesAeadHkdfPublicKey.getDefaultInstance())); - } - - private EciesAeadHkdfKeyFormat createKeyFormat( - EllipticCurveType curve, - HashType hashType, - EcPointFormat ecPointFormat, - KeyTemplate demKeyTemplate, - byte[] salt) { - EciesHkdfKemParams kemParams = - EciesHkdfKemParams.newBuilder() - .setCurveType(curve) - .setHkdfHashType(hashType) - .setHkdfSalt(ByteString.copyFrom(salt)) - .build(); - EciesAeadDemParams demParams = - EciesAeadDemParams.newBuilder().setAeadDem(demKeyTemplate).build(); - EciesAeadHkdfParams params = - EciesAeadHkdfParams.newBuilder() - .setKemParams(kemParams) - .setDemParams(demParams) - .setEcPointFormat(ecPointFormat) - .build(); - - return EciesAeadHkdfKeyFormat.newBuilder().setParams(params).build(); - } - - private EciesAeadHkdfPrivateKey createValidPrivateKey() throws Exception { - EciesAeadHkdfKeyFormat format = - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.SHA256, - EcPointFormat.UNCOMPRESSED, - AeadKeyTemplates.AES128_CTR_HMAC_SHA256, - "some salt".getBytes("UTF-8")); - return factory.createKey(format); - } - - @Test - public void validateKey_valid() throws Exception { - EciesAeadHkdfPrivateKey privateKey = createValidPrivateKey(); - publicManager.validateKey(privateManager.getPublicKey(privateKey)); - } - - @Test - public void validateKey_invalidWrongVersion_throws() throws Exception { - EciesAeadHkdfPrivateKey privateKey = createValidPrivateKey(); - EciesAeadHkdfPublicKey publicKey = privateManager.getPublicKey(privateKey); - EciesAeadHkdfPublicKey invalidKey = EciesAeadHkdfPublicKey.newBuilder().setVersion(1).build(); - assertThrows(GeneralSecurityException.class, () -> publicManager.validateKey(invalidKey)); - } - - @Test - public void validateKey_invalidPointFormat_throws() throws Exception { - EciesAeadHkdfPrivateKey privateKey = createValidPrivateKey(); - EciesAeadHkdfPublicKey publicKey = privateManager.getPublicKey(privateKey); - EciesAeadHkdfPublicKey invalidKey = - EciesAeadHkdfPublicKey.newBuilder() - .setParams( - createKeyFormat( - EllipticCurveType.NIST_P256, - HashType.SHA256, - EcPointFormat.UNKNOWN_FORMAT, - AeadKeyTemplates.AES128_CTR_HMAC_SHA256, - "some salt".getBytes("UTF-8")) - .getParams()).build(); - assertThrows(GeneralSecurityException.class, () -> publicManager.validateKey(invalidKey)); - } - - @Test - public void createPrimitive() throws Exception { - EciesAeadHkdfPrivateKey privateKey = createValidPrivateKey(); - HybridDecrypt hybridDecrypt = privateManager.getPrimitive(privateKey, HybridDecrypt.class); - - EciesAeadHkdfPublicKey publicKey = privateManager.getPublicKey(privateKey); - HybridEncrypt hybridEncrypt = publicManager.getPrimitive(publicKey, HybridEncrypt.class); - - byte[] message = Random.randBytes(20); - byte[] contextInfo = Random.randBytes(20); - assertThat(hybridDecrypt.decrypt(hybridEncrypt.encrypt(message, contextInfo), contextInfo)) - .isEqualTo(message); - } - -} diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/HybridKeyTemplatesTest.java b/java_src/src/test/java/com/google/crypto/tink/hybrid/HybridKeyTemplatesTest.java index 8a3d15d954..8933ac6c91 100644 --- a/java_src/src/test/java/com/google/crypto/tink/hybrid/HybridKeyTemplatesTest.java +++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/HybridKeyTemplatesTest.java @@ -52,7 +52,7 @@ public static void setUp() throws Exception { @Test public void eciesP256HkdfHmaSha256Aes128Gcm() throws Exception { KeyTemplate template = HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM; - assertEquals(new EciesAeadHkdfPrivateKeyManager().getKeyType(), template.getTypeUrl()); + assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); EciesAeadHkdfKeyFormat format = EciesAeadHkdfKeyFormat.parseFrom( @@ -75,7 +75,7 @@ public void eciesP256HkdfHmaSha256Aes128Gcm() throws Exception { public void eciesP256HkdfHmacSha256Aes128GcmCompressedWithoutPrefix() throws Exception { KeyTemplate template = HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM_COMPRESSED_WITHOUT_PREFIX; - assertEquals(new EciesAeadHkdfPrivateKeyManager().getKeyType(), template.getTypeUrl()); + assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.RAW, template.getOutputPrefixType()); EciesAeadHkdfKeyFormat format = EciesAeadHkdfKeyFormat.parseFrom( @@ -97,7 +97,7 @@ public void eciesP256HkdfHmacSha256Aes128GcmCompressedWithoutPrefix() throws Exc @Test public void eciesP256HkdfHmacSha256Aes128CtrHmacSha256() throws Exception { KeyTemplate template = HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256; - assertEquals(new EciesAeadHkdfPrivateKeyManager().getKeyType(), template.getTypeUrl()); + assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); EciesAeadHkdfKeyFormat format = EciesAeadHkdfKeyFormat.parseFrom( @@ -128,7 +128,7 @@ public void testCreateEciesAeadHkdfKeyTemplate() throws Exception { KeyTemplate template = HybridKeyTemplates.createEciesAeadHkdfKeyTemplate( curveType, hashType, ecPointFormat, demKeyTemplate, OutputPrefixType.TINK, salt.getBytes(UTF_8)); - assertEquals(new EciesAeadHkdfPrivateKeyManager().getKeyType(), template.getTypeUrl()); + assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); EciesAeadHkdfKeyFormat format = EciesAeadHkdfKeyFormat.parseFrom(