// 
// Decompiled by Procyon v0.6.0
// 

package com.google.crypto.tink.mac.internal;

import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.internal.MutableSerializationRegistry;
import com.google.crypto.tink.util.SecretBytes;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.crypto.tink.proto.KeyData;
import com.google.protobuf.ByteString;
import javax.annotation.Nullable;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.crypto.tink.proto.HmacKeyFormat;
import com.google.crypto.tink.proto.KeyTemplate;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.proto.HmacParams;
import com.google.crypto.tink.internal.KeyParser;
import com.google.crypto.tink.internal.ProtoKeySerialization;
import com.google.crypto.tink.mac.HmacKey;
import com.google.crypto.tink.internal.KeySerializer;
import com.google.crypto.tink.internal.ParametersParser;
import com.google.crypto.tink.internal.ProtoParametersSerialization;
import com.google.crypto.tink.internal.ParametersSerializer;
import com.google.crypto.tink.proto.HashType;
import com.google.crypto.tink.mac.HmacParameters;
import com.google.crypto.tink.proto.OutputPrefixType;
import com.google.crypto.tink.internal.EnumTypeProtoConverter;
import com.google.crypto.tink.util.Bytes;
import com.google.crypto.tink.AccessesPartialKey;

@AccessesPartialKey
public final class HmacProtoSerialization
{
    private static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.HmacKey";
    private static final Bytes TYPE_URL_BYTES;
    private static final EnumTypeProtoConverter<OutputPrefixType, HmacParameters.Variant> OUTPUT_PREFIX_TYPE_CONVERTER;
    private static final EnumTypeProtoConverter<HashType, HmacParameters.HashType> HASH_TYPE_CONVERTER;
    private static final ParametersSerializer<HmacParameters, ProtoParametersSerialization> PARAMETERS_SERIALIZER;
    private static final ParametersParser<ProtoParametersSerialization> PARAMETERS_PARSER;
    private static final KeySerializer<HmacKey, ProtoKeySerialization> KEY_SERIALIZER;
    private static final KeyParser<ProtoKeySerialization> KEY_PARSER;
    
    private static HmacParams getProtoParams(final HmacParameters parameters) throws GeneralSecurityException {
        return HmacParams.newBuilder().setTagSize(parameters.getCryptographicTagSizeBytes()).setHash(HmacProtoSerialization.HASH_TYPE_CONVERTER.toProtoEnum(parameters.getHashType())).build();
    }
    
    private static ProtoParametersSerialization serializeParameters(final HmacParameters parameters) throws GeneralSecurityException {
        return ProtoParametersSerialization.create(KeyTemplate.newBuilder().setTypeUrl("type.googleapis.com/google.crypto.tink.HmacKey").setValue(HmacKeyFormat.newBuilder().setParams(getProtoParams(parameters)).setKeySize(parameters.getKeySizeBytes()).build().toByteString()).setOutputPrefixType(HmacProtoSerialization.OUTPUT_PREFIX_TYPE_CONVERTER.toProtoEnum(parameters.getVariant())).build());
    }
    
    private static ProtoKeySerialization serializeKey(final HmacKey key, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        return ProtoKeySerialization.create("type.googleapis.com/google.crypto.tink.HmacKey", com.google.crypto.tink.proto.HmacKey.newBuilder().setParams(getProtoParams(key.getParameters())).setKeyValue(ByteString.copyFrom(key.getKeyBytes().toByteArray(SecretKeyAccess.requireAccess(access)))).build().toByteString(), KeyData.KeyMaterialType.SYMMETRIC, HmacProtoSerialization.OUTPUT_PREFIX_TYPE_CONVERTER.toProtoEnum(key.getParameters().getVariant()), key.getIdRequirementOrNull());
    }
    
    private static HmacParameters parseParameters(final ProtoParametersSerialization serialization) throws GeneralSecurityException {
        if (!serialization.getKeyTemplate().getTypeUrl().equals("type.googleapis.com/google.crypto.tink.HmacKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to HmacProtoSerialization.parseParameters: " + serialization.getKeyTemplate().getTypeUrl());
        }
        HmacKeyFormat format;
        try {
            format = HmacKeyFormat.parseFrom(serialization.getKeyTemplate().getValue(), ExtensionRegistryLite.getEmptyRegistry());
        }
        catch (final InvalidProtocolBufferException e) {
            throw new GeneralSecurityException("Parsing HmacParameters failed: ", e);
        }
        if (format.getVersion() != 0) {
            throw new GeneralSecurityException("Parsing HmacParameters failed: unknown Version " + format.getVersion());
        }
        return HmacParameters.builder().setKeySizeBytes(format.getKeySize()).setTagSizeBytes(format.getParams().getTagSize()).setHashType(HmacProtoSerialization.HASH_TYPE_CONVERTER.fromProtoEnum(format.getParams().getHash())).setVariant(HmacProtoSerialization.OUTPUT_PREFIX_TYPE_CONVERTER.fromProtoEnum(serialization.getKeyTemplate().getOutputPrefixType())).build();
    }
    
    private static HmacKey parseKey(final ProtoKeySerialization serialization, @Nullable final SecretKeyAccess access) throws GeneralSecurityException {
        if (!serialization.getTypeUrl().equals("type.googleapis.com/google.crypto.tink.HmacKey")) {
            throw new IllegalArgumentException("Wrong type URL in call to HmacProtoSerialization.parseKey");
        }
        try {
            final com.google.crypto.tink.proto.HmacKey protoKey = com.google.crypto.tink.proto.HmacKey.parseFrom(serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry());
            if (protoKey.getVersion() != 0) {
                throw new GeneralSecurityException("Only version 0 keys are accepted");
            }
            final HmacParameters parameters = HmacParameters.builder().setKeySizeBytes(protoKey.getKeyValue().size()).setTagSizeBytes(protoKey.getParams().getTagSize()).setHashType(HmacProtoSerialization.HASH_TYPE_CONVERTER.fromProtoEnum(protoKey.getParams().getHash())).setVariant(HmacProtoSerialization.OUTPUT_PREFIX_TYPE_CONVERTER.fromProtoEnum(serialization.getOutputPrefixType())).build();
            return HmacKey.builder().setParameters(parameters).setKeyBytes(SecretBytes.copyFrom(protoKey.getKeyValue().toByteArray(), SecretKeyAccess.requireAccess(access))).setIdRequirement(serialization.getIdRequirementOrNull()).build();
        }
        catch (final InvalidProtocolBufferException | IllegalArgumentException e) {
            throw new GeneralSecurityException("Parsing HmacKey failed");
        }
    }
    
    public static void register() throws GeneralSecurityException {
        register(MutableSerializationRegistry.globalInstance());
    }
    
    public static void register(final MutableSerializationRegistry registry) throws GeneralSecurityException {
        registry.registerParametersSerializer(HmacProtoSerialization.PARAMETERS_SERIALIZER);
        registry.registerParametersParser(HmacProtoSerialization.PARAMETERS_PARSER);
        registry.registerKeySerializer(HmacProtoSerialization.KEY_SERIALIZER);
        registry.registerKeyParser(HmacProtoSerialization.KEY_PARSER);
    }
    
    private HmacProtoSerialization() {
    }
    
    static {
        TYPE_URL_BYTES = Util.toBytesFromPrintableAscii("type.googleapis.com/google.crypto.tink.HmacKey");
        OUTPUT_PREFIX_TYPE_CONVERTER = EnumTypeProtoConverter.builder().add(OutputPrefixType.RAW, HmacParameters.Variant.NO_PREFIX).add(OutputPrefixType.TINK, HmacParameters.Variant.TINK).add(OutputPrefixType.LEGACY, HmacParameters.Variant.LEGACY).add(OutputPrefixType.CRUNCHY, HmacParameters.Variant.CRUNCHY).build();
        HASH_TYPE_CONVERTER = EnumTypeProtoConverter.builder().add(HashType.SHA1, HmacParameters.HashType.SHA1).add(HashType.SHA224, HmacParameters.HashType.SHA224).add(HashType.SHA256, HmacParameters.HashType.SHA256).add(HashType.SHA384, HmacParameters.HashType.SHA384).add(HashType.SHA512, HmacParameters.HashType.SHA512).build();
        PARAMETERS_SERIALIZER = ParametersSerializer.create(HmacProtoSerialization::serializeParameters, HmacParameters.class, ProtoParametersSerialization.class);
        PARAMETERS_PARSER = ParametersParser.create(HmacProtoSerialization::parseParameters, HmacProtoSerialization.TYPE_URL_BYTES, ProtoParametersSerialization.class);
        KEY_SERIALIZER = KeySerializer.create(HmacProtoSerialization::serializeKey, HmacKey.class, ProtoKeySerialization.class);
        KEY_PARSER = KeyParser.create(HmacProtoSerialization::parseKey, HmacProtoSerialization.TYPE_URL_BYTES, ProtoKeySerialization.class);
    }
}
