• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google Inc.
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.internal;
18 
19 import com.google.crypto.tink.InsecureSecretKeyAccess;
20 import com.google.crypto.tink.Key;
21 import com.google.crypto.tink.KeyManager;
22 import com.google.crypto.tink.Parameters;
23 import com.google.crypto.tink.PrivateKey;
24 import com.google.crypto.tink.PrivateKeyManager;
25 import com.google.crypto.tink.proto.KeyData;
26 import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
27 import com.google.crypto.tink.proto.KeyTemplate;
28 import com.google.crypto.tink.proto.OutputPrefixType;
29 import com.google.protobuf.ByteString;
30 import com.google.protobuf.ExtensionRegistryLite;
31 import com.google.protobuf.InvalidProtocolBufferException;
32 import com.google.protobuf.MessageLite;
33 import com.google.protobuf.Parser;
34 import java.security.GeneralSecurityException;
35 
36 /**
37  * A composed KeyManager implements a KeyManager by accessing the internal specific registries.
38  *
39  * <p>Tink offers {@code Registry.getKeyManager} in the public API. While this shouldn't be used by
40  * users, we still want to be backwards compatible for users which use it.
41  *
42  * <p>In this class we use the global instances of the following classes to implement the KeyManager
43  * interface.
44  *
45  * <ul>
46  *   <li>{@link MutableSerializationRegistry}
47  *   <li>{@link MutablePrimitiveRegistry}
48  *   <li>{@link MutableKeyCreationRegistry}
49  * </ul>
50  */
51 public class LegacyKeyManagerImpl<P> implements KeyManager<P> {
52   final String typeUrl;
53   final Class<P> primitiveClass;
54   final KeyMaterialType keyMaterialType;
55   final Parser<? extends MessageLite> protobufKeyParser;
56 
create( String typeUrl, Class<P> primitiveClass, KeyMaterialType keyMaterialType, Parser<? extends MessageLite> protobufKeyParser)57   public static <P> KeyManager<P> create(
58       String typeUrl,
59       Class<P> primitiveClass,
60       KeyMaterialType keyMaterialType,
61       Parser<? extends MessageLite> protobufKeyParser) {
62     return new LegacyKeyManagerImpl<>(typeUrl, primitiveClass, keyMaterialType, protobufKeyParser);
63   }
64 
LegacyKeyManagerImpl( String typeUrl, Class<P> primitiveClass, KeyMaterialType keyMaterialType, Parser<? extends MessageLite> protobufKeyParser)65   LegacyKeyManagerImpl(
66       String typeUrl,
67       Class<P> primitiveClass,
68       KeyMaterialType keyMaterialType,
69       Parser<? extends MessageLite> protobufKeyParser) {
70     this.protobufKeyParser = protobufKeyParser;
71     this.typeUrl = typeUrl;
72     this.primitiveClass = primitiveClass;
73     this.keyMaterialType = keyMaterialType;
74   }
75 
76   @Override
getPrimitive(ByteString serializedKey)77   public P getPrimitive(ByteString serializedKey) throws GeneralSecurityException {
78     ProtoKeySerialization serialization =
79         ProtoKeySerialization.create(
80             typeUrl, serializedKey, keyMaterialType, OutputPrefixType.RAW, null);
81     Key key =
82         MutableSerializationRegistry.globalInstance()
83             .parseKey(serialization, InsecureSecretKeyAccess.get());
84     return MutablePrimitiveRegistry.globalInstance().getPrimitive(key, primitiveClass);
85   }
86 
87   @Override
getPrimitive(MessageLite key)88   public final P getPrimitive(MessageLite key) throws GeneralSecurityException {
89     return getPrimitive(key.toByteString());
90   }
91 
92   @Override
93   @SuppressWarnings("UnusedException")
newKey(ByteString serializedKeyFormat)94   public final MessageLite newKey(ByteString serializedKeyFormat) throws GeneralSecurityException {
95     KeyData keyData = newKeyData(serializedKeyFormat);
96     try {
97       return protobufKeyParser.parseFrom(
98           keyData.getValue(), ExtensionRegistryLite.getEmptyRegistry());
99     } catch (InvalidProtocolBufferException e) {
100       throw new GeneralSecurityException("Unexpectedly failed to parse key");
101     }
102   }
103 
104   @Override
newKey(MessageLite keyFormat)105   public final MessageLite newKey(MessageLite keyFormat) throws GeneralSecurityException {
106     return newKey(keyFormat.toByteString());
107   }
108 
109   @Override
doesSupport(String typeUrl)110   public final boolean doesSupport(String typeUrl) {
111     return typeUrl.equals(getKeyType());
112   }
113 
114   @Override
getKeyType()115   public final String getKeyType() {
116     return typeUrl;
117   }
118 
119   @Override
getVersion()120   public int getVersion() {
121     return 0;
122   }
123 
124   @Override
newKeyData(ByteString serializedKeyFormat)125   public final KeyData newKeyData(ByteString serializedKeyFormat) throws GeneralSecurityException {
126     ProtoParametersSerialization parametersSerialization =
127         ProtoParametersSerialization.checkedCreate(
128             KeyTemplate.newBuilder()
129                 .setTypeUrl(typeUrl)
130                 .setValue(serializedKeyFormat)
131                 .setOutputPrefixType(OutputPrefixType.RAW)
132                 .build());
133     Parameters parameters =
134         MutableSerializationRegistry.globalInstance().parseParameters(parametersSerialization);
135     Key key =
136         MutableKeyCreationRegistry.globalInstance()
137             .createKey(parameters, /* idRequirement= */ null);
138     ProtoKeySerialization keySerialization =
139         MutableSerializationRegistry.globalInstance()
140             .serializeKey(key, ProtoKeySerialization.class, InsecureSecretKeyAccess.get());
141     return KeyData.newBuilder()
142         .setTypeUrl(keySerialization.getTypeUrl())
143         .setValue(keySerialization.getValue())
144         .setKeyMaterialType(keySerialization.getKeyMaterialType())
145         .build();
146   }
147 
148   @Override
getPrimitiveClass()149   public final Class<P> getPrimitiveClass() {
150     return primitiveClass;
151   }
152 
153   private static class LegacyPrivateKeyManagerImpl<P> extends LegacyKeyManagerImpl<P>
154       implements PrivateKeyManager<P> {
LegacyPrivateKeyManagerImpl( String typeUrl, Class<P> primitiveClass, Parser<? extends MessageLite> protobufKeyParser)155     protected LegacyPrivateKeyManagerImpl(
156         String typeUrl, Class<P> primitiveClass, Parser<? extends MessageLite> protobufKeyParser) {
157       super(typeUrl, primitiveClass, KeyMaterialType.ASYMMETRIC_PRIVATE, protobufKeyParser);
158     }
159 
160     @Override
getPublicKeyData(ByteString serializedKey)161     public KeyData getPublicKeyData(ByteString serializedKey) throws GeneralSecurityException {
162       ProtoKeySerialization serialization =
163           ProtoKeySerialization.create(
164               typeUrl, serializedKey, keyMaterialType, OutputPrefixType.RAW, null);
165       Key key =
166           MutableSerializationRegistry.globalInstance()
167               .parseKey(serialization, InsecureSecretKeyAccess.get());
168       if (!(key instanceof PrivateKey)) {
169         throw new GeneralSecurityException("Key not private key");
170       }
171       Key publicKey = ((PrivateKey) key).getPublicKey();
172       ProtoKeySerialization publicKeySerialization =
173           MutableSerializationRegistry.globalInstance()
174               .serializeKey(publicKey, ProtoKeySerialization.class, InsecureSecretKeyAccess.get());
175       return KeyData.newBuilder()
176           .setTypeUrl(publicKeySerialization.getTypeUrl())
177           .setValue(publicKeySerialization.getValue())
178           .setKeyMaterialType(publicKeySerialization.getKeyMaterialType())
179           .build();
180     }
181   }
182 
createPrivateKeyManager( String typeUrl, Class<P> primitiveClass, Parser<? extends MessageLite> protobufKeyParser)183   public static <P> PrivateKeyManager<P> createPrivateKeyManager(
184       String typeUrl, Class<P> primitiveClass, Parser<? extends MessageLite> protobufKeyParser) {
185     return new LegacyPrivateKeyManagerImpl<P>(typeUrl, primitiveClass, protobufKeyParser);
186   }
187 }
188