• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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;
18 
19 import com.google.crypto.tink.proto.KeyData;
20 import com.google.crypto.tink.proto.KeyStatusType;
21 import com.google.crypto.tink.proto.Keyset;
22 import com.google.crypto.tink.proto.KeysetInfo;
23 import com.google.crypto.tink.proto.OutputPrefixType;
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.nio.charset.Charset;
28 import java.security.GeneralSecurityException;
29 
30 /** Various helpers. */
31 final class Util {
32   public static final Charset UTF_8 = Charset.forName("UTF-8");
33 
34   /** @return a KeysetInfo-proto from a {@code keyset} protobuf. */
getKeysetInfo(Keyset keyset)35   public static KeysetInfo getKeysetInfo(Keyset keyset) {
36     KeysetInfo.Builder info = KeysetInfo.newBuilder().setPrimaryKeyId(keyset.getPrimaryKeyId());
37     for (Keyset.Key key : keyset.getKeyList()) {
38       info.addKeyInfo(getKeyInfo(key));
39     }
40     return info.build();
41   }
42 
43   /** @return a KeyInfo-proto from a {@code key} protobuf. */
getKeyInfo(Keyset.Key key)44   public static KeysetInfo.KeyInfo getKeyInfo(Keyset.Key key) {
45     return KeysetInfo.KeyInfo.newBuilder()
46         .setTypeUrl(key.getKeyData().getTypeUrl())
47         .setStatus(key.getStatus())
48         .setOutputPrefixType(key.getOutputPrefixType())
49         .setKeyId(key.getKeyId())
50         .build();
51   }
52 
53   /**
54    * Validates a {@code key}.
55    *
56    * @throws GeneralSecurityException if {@code key} is invalid.
57    */
validateKey(Keyset.Key key)58   public static void validateKey(Keyset.Key key) throws GeneralSecurityException {
59     if (!key.hasKeyData()) {
60       throw new GeneralSecurityException(String.format("key %d has no key data", key.getKeyId()));
61     }
62 
63     if (key.getOutputPrefixType() == OutputPrefixType.UNKNOWN_PREFIX) {
64       throw new GeneralSecurityException(
65           String.format("key %d has unknown prefix", key.getKeyId()));
66     }
67 
68     if (key.getStatus() == KeyStatusType.UNKNOWN_STATUS) {
69       throw new GeneralSecurityException(
70           String.format("key %d has unknown status", key.getKeyId()));
71     }
72   }
73 
74   /**
75    * Validates a {@code Keyset}.
76    *
77    * @throws GeneralSecurityException if {@code keyset} is invalid.
78    */
validateKeyset(Keyset keyset)79   public static void validateKeyset(Keyset keyset) throws GeneralSecurityException {
80     int primaryKeyId = keyset.getPrimaryKeyId();
81     boolean hasPrimaryKey = false;
82     boolean containsOnlyPublicKeyMaterial = true;
83     int numEnabledKeys = 0;
84     for (Keyset.Key key : keyset.getKeyList()) {
85       if (key.getStatus() != KeyStatusType.ENABLED) {
86         continue;
87       }
88       validateKey(key);
89       if (key.getKeyId() == primaryKeyId) {
90         if (hasPrimaryKey) {
91           throw new GeneralSecurityException("keyset contains multiple primary keys");
92         }
93         hasPrimaryKey = true;
94       }
95       if (key.getKeyData().getKeyMaterialType() != KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC) {
96         containsOnlyPublicKeyMaterial = false;
97       }
98       numEnabledKeys++;
99     }
100     if (numEnabledKeys == 0) {
101       throw new GeneralSecurityException("keyset must contain at least one ENABLED key");
102     }
103     // Checks that a keyset contains a primary key, except when it contains only public keys.
104     if (!hasPrimaryKey && !containsOnlyPublicKeyMaterial) {
105       throw new GeneralSecurityException("keyset doesn't contain a valid primary key");
106     }
107   }
108 
109   /**
110    * Reads all bytes from {@code inputStream}.
111    */
readAll(InputStream inputStream)112   public static byte[] readAll(InputStream inputStream) throws IOException {
113     ByteArrayOutputStream result = new ByteArrayOutputStream();
114     byte[] buf = new byte[1024];
115     int count;
116     while ((count = inputStream.read(buf)) != -1) {
117       result.write(buf, 0, count);
118     }
119     return result.toByteArray();
120   }
121 
Util()122   private Util() {}
123 }
124