• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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.streamingaead;
18 
19 import com.google.crypto.tink.StreamingAead;
20 import com.google.crypto.tink.internal.LegacyProtoKey;
21 import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
22 import com.google.crypto.tink.internal.PrimitiveConstructor;
23 import com.google.crypto.tink.internal.PrimitiveRegistry;
24 import com.google.crypto.tink.internal.PrimitiveSet;
25 import com.google.crypto.tink.internal.PrimitiveWrapper;
26 import com.google.crypto.tink.streamingaead.internal.LegacyFullStreamingAead;
27 import java.security.GeneralSecurityException;
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * StreamingAeadWrapper is the implementation of PrimitiveWrapper for the StreamingAead primitive.
33  *
34  * <p>The returned primitive works with a keyset (rather than a single key). To encrypt a plaintext,
35  * it uses the primary key in the keyset. To decrypt, the primitive tries the enabled keys from the
36  * keyset to select the right key for decryption. All keys in a keyset of StreamingAead have type
37  * {@link com.google.crypto.tink.proto.OutputPrefixType#RAW}.
38  */
39 public class StreamingAeadWrapper implements PrimitiveWrapper<StreamingAead, StreamingAead> {
40 
41   private static final StreamingAeadWrapper WRAPPER = new StreamingAeadWrapper();
42   private static final PrimitiveConstructor<LegacyProtoKey, StreamingAead>
43       LEGACY_FULL_STREAMING_AEAD_PRIMITIVE_CONSTRUCTOR =
44           PrimitiveConstructor.create(
45               LegacyFullStreamingAead::create, LegacyProtoKey.class, StreamingAead.class);
46 
StreamingAeadWrapper()47   StreamingAeadWrapper() {}
48 
49   /**
50    * @return a StreamingAead primitive from a {@code keysetHandle}.
51    * @throws GeneralSecurityException
52    */
53   @Override
wrap(final PrimitiveSet<StreamingAead> primitives)54   public StreamingAead wrap(final PrimitiveSet<StreamingAead> primitives)
55       throws GeneralSecurityException {
56     List<StreamingAead> allStreamingAeads = new ArrayList<>();
57     for (List<PrimitiveSet.Entry<StreamingAead>> entryList : primitives.getAll()) {
58       // For legacy reasons (Tink always encrypted with non-RAW keys) we use all
59       // primitives, even those which have output_prefix_type != RAW.
60       for (PrimitiveSet.Entry<StreamingAead> entry : entryList) {
61         if (entry.getFullPrimitive() == null) {
62           throw new GeneralSecurityException(
63               "No full primitive set for key id " + entry.getKeyId());
64         }
65         allStreamingAeads.add(entry.getFullPrimitive());
66       }
67     }
68     PrimitiveSet.Entry<StreamingAead> primary = primitives.getPrimary();
69     if (primary == null || primary.getFullPrimitive() == null) {
70       throw new GeneralSecurityException("No primary set");
71     }
72     return new StreamingAeadHelper(allStreamingAeads, primary.getFullPrimitive());
73   }
74 
75   @Override
getPrimitiveClass()76   public Class<StreamingAead> getPrimitiveClass() {
77     return StreamingAead.class;
78   }
79 
80   @Override
getInputPrimitiveClass()81   public Class<StreamingAead> getInputPrimitiveClass() {
82     return StreamingAead.class;
83   }
84 
register()85   public static void register() throws GeneralSecurityException {
86     MutablePrimitiveRegistry.globalInstance().registerPrimitiveWrapper(WRAPPER);
87     MutablePrimitiveRegistry.globalInstance()
88         .registerPrimitiveConstructor(LEGACY_FULL_STREAMING_AEAD_PRIMITIVE_CONSTRUCTOR);
89   }
90 
91   /**
92    * registerToInternalPrimitiveRegistry is a non-public method (it takes an argument of an
93    * internal-only type) registering an instance of {@code StreamingAeadWrapper} to the provided
94    * {@code PrimitiveRegistry.Builder}.
95    */
registerToInternalPrimitiveRegistry( PrimitiveRegistry.Builder primitiveRegistryBuilder)96   public static void registerToInternalPrimitiveRegistry(
97       PrimitiveRegistry.Builder primitiveRegistryBuilder) throws GeneralSecurityException {
98     primitiveRegistryBuilder.registerPrimitiveWrapper(WRAPPER);
99   }
100 }
101