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