• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.aead;
18 
19 import static com.google.crypto.tink.internal.Util.toBytesFromPrintableAscii;
20 
21 import com.google.crypto.tink.SecretKeyAccess;
22 import com.google.crypto.tink.internal.KeyParser;
23 import com.google.crypto.tink.internal.KeySerializer;
24 import com.google.crypto.tink.internal.MutableSerializationRegistry;
25 import com.google.crypto.tink.internal.ParametersParser;
26 import com.google.crypto.tink.internal.ParametersSerializer;
27 import com.google.crypto.tink.internal.ProtoKeySerialization;
28 import com.google.crypto.tink.internal.ProtoParametersSerialization;
29 import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
30 import com.google.crypto.tink.proto.KeyTemplate;
31 import com.google.crypto.tink.proto.KmsAeadKeyFormat;
32 import com.google.crypto.tink.proto.OutputPrefixType;
33 import com.google.crypto.tink.util.Bytes;
34 import com.google.protobuf.ExtensionRegistryLite;
35 import com.google.protobuf.InvalidProtocolBufferException;
36 import java.security.GeneralSecurityException;
37 import javax.annotation.Nullable;
38 
39 /** Serializers and Parsers for LegacyKmsAeadProtoKey and LegacyKmsAeadProtoParameters */
40 final class LegacyKmsAeadProtoSerialization {
41   private static final String TYPE_URL = "type.googleapis.com/google.crypto.tink.KmsAeadKey";
42   private static final Bytes TYPE_URL_BYTES = toBytesFromPrintableAscii(TYPE_URL);
43 
44   private static final ParametersSerializer<LegacyKmsAeadParameters, ProtoParametersSerialization>
45       PARAMETERS_SERIALIZER =
46           ParametersSerializer.create(
47               LegacyKmsAeadProtoSerialization::serializeParameters,
48               LegacyKmsAeadParameters.class,
49               ProtoParametersSerialization.class);
50 
51   private static final ParametersParser<ProtoParametersSerialization> PARAMETERS_PARSER =
52       ParametersParser.create(
53           LegacyKmsAeadProtoSerialization::parseParameters,
54           TYPE_URL_BYTES,
55           ProtoParametersSerialization.class);
56 
57   private static final KeySerializer<LegacyKmsAeadKey, ProtoKeySerialization> KEY_SERIALIZER =
58       KeySerializer.create(
59           LegacyKmsAeadProtoSerialization::serializeKey,
60           LegacyKmsAeadKey.class,
61           ProtoKeySerialization.class);
62 
63   private static final KeyParser<ProtoKeySerialization> KEY_PARSER =
64       KeyParser.create(
65           LegacyKmsAeadProtoSerialization::parseKey, TYPE_URL_BYTES, ProtoKeySerialization.class);
66 
toProtoOutputPrefixType(LegacyKmsAeadParameters.Variant variant)67   private static OutputPrefixType toProtoOutputPrefixType(LegacyKmsAeadParameters.Variant variant)
68       throws GeneralSecurityException {
69     if (LegacyKmsAeadParameters.Variant.TINK.equals(variant)) {
70       return OutputPrefixType.TINK;
71     }
72     if (LegacyKmsAeadParameters.Variant.NO_PREFIX.equals(variant)) {
73       return OutputPrefixType.RAW;
74     }
75     throw new GeneralSecurityException("Unable to serialize variant: " + variant);
76   }
77 
toVariant(OutputPrefixType outputPrefixType)78   private static LegacyKmsAeadParameters.Variant toVariant(OutputPrefixType outputPrefixType)
79       throws GeneralSecurityException {
80     switch (outputPrefixType) {
81       case TINK:
82         return LegacyKmsAeadParameters.Variant.TINK;
83       case RAW:
84         return LegacyKmsAeadParameters.Variant.NO_PREFIX;
85       default:
86         throw new GeneralSecurityException(
87             "Unable to parse OutputPrefixType: " + outputPrefixType.getNumber());
88     }
89   }
90 
serializeParameters( LegacyKmsAeadParameters parameters)91   private static ProtoParametersSerialization serializeParameters(
92       LegacyKmsAeadParameters parameters) throws GeneralSecurityException {
93     return ProtoParametersSerialization.create(
94         KeyTemplate.newBuilder()
95             .setTypeUrl(TYPE_URL)
96             .setValue(
97                 KmsAeadKeyFormat.newBuilder().setKeyUri(parameters.keyUri()).build().toByteString())
98             .setOutputPrefixType(toProtoOutputPrefixType(parameters.variant()))
99             .build());
100   }
101 
parseParameters(ProtoParametersSerialization serialization)102   private static LegacyKmsAeadParameters parseParameters(ProtoParametersSerialization serialization)
103       throws GeneralSecurityException {
104     if (!serialization.getKeyTemplate().getTypeUrl().equals(TYPE_URL)) {
105       throw new IllegalArgumentException(
106           "Wrong type URL in call to LegacyKmsAeadProtoSerialization.parseParameters: "
107               + serialization.getKeyTemplate().getTypeUrl());
108     }
109     KmsAeadKeyFormat format;
110     try {
111       format =
112           KmsAeadKeyFormat.parseFrom(
113               serialization.getKeyTemplate().getValue(), ExtensionRegistryLite.getEmptyRegistry());
114     } catch (InvalidProtocolBufferException e) {
115       throw new GeneralSecurityException("Parsing KmsAeadKeyFormat failed: ", e);
116     }
117     return LegacyKmsAeadParameters.create(
118         format.getKeyUri(), toVariant(serialization.getKeyTemplate().getOutputPrefixType()));
119   }
120 
serializeKey( LegacyKmsAeadKey key, @Nullable SecretKeyAccess access)121   private static ProtoKeySerialization serializeKey(
122       LegacyKmsAeadKey key, @Nullable SecretKeyAccess access) throws GeneralSecurityException {
123     return ProtoKeySerialization.create(
124         TYPE_URL,
125         com.google.crypto.tink.proto.KmsAeadKey.newBuilder()
126             .setParams(
127                 KmsAeadKeyFormat.newBuilder().setKeyUri(key.getParameters().keyUri()).build())
128             .build()
129             .toByteString(),
130         KeyMaterialType.REMOTE,
131         toProtoOutputPrefixType(key.getParameters().variant()),
132         key.getIdRequirementOrNull());
133   }
134 
parseKey( ProtoKeySerialization serialization, @Nullable SecretKeyAccess access)135   private static LegacyKmsAeadKey parseKey(
136       ProtoKeySerialization serialization, @Nullable SecretKeyAccess access)
137       throws GeneralSecurityException {
138     if (!serialization.getTypeUrl().equals(TYPE_URL)) {
139       throw new IllegalArgumentException(
140           "Wrong type URL in call to LegacyKmsAeadProtoSerialization.parseKey");
141     }
142     try {
143       com.google.crypto.tink.proto.KmsAeadKey protoKey =
144           com.google.crypto.tink.proto.KmsAeadKey.parseFrom(
145               serialization.getValue(), ExtensionRegistryLite.getEmptyRegistry());
146       if (protoKey.getVersion() != 0) {
147         throw new GeneralSecurityException(
148             "KmsAeadKey are only accepted with version 0, got " + protoKey);
149       }
150       LegacyKmsAeadParameters parameters =
151           LegacyKmsAeadParameters.create(
152               protoKey.getParams().getKeyUri(), toVariant(serialization.getOutputPrefixType()));
153       return LegacyKmsAeadKey.create(parameters, serialization.getIdRequirementOrNull());
154     } catch (InvalidProtocolBufferException e) {
155       throw new GeneralSecurityException("Parsing KmsAeadKey failed: ", e);
156     }
157   }
158 
register()159   public static void register() throws GeneralSecurityException {
160     register(MutableSerializationRegistry.globalInstance());
161   }
162 
register(MutableSerializationRegistry registry)163   public static void register(MutableSerializationRegistry registry)
164       throws GeneralSecurityException {
165     registry.registerParametersSerializer(PARAMETERS_SERIALIZER);
166     registry.registerParametersParser(PARAMETERS_PARSER);
167     registry.registerKeySerializer(KEY_SERIALIZER);
168     registry.registerKeyParser(KEY_PARSER);
169   }
170 
LegacyKmsAeadProtoSerialization()171   private LegacyKmsAeadProtoSerialization() {}
172 }
173