1 // Copyright 2022 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.signature; 18 19 import static java.nio.charset.StandardCharsets.UTF_8; 20 import static org.junit.Assert.assertThrows; 21 22 import com.google.crypto.tink.DeterministicAead; 23 import com.google.crypto.tink.InsecureSecretKeyAccess; 24 import com.google.crypto.tink.KeyTemplates; 25 import com.google.crypto.tink.KeysetHandle; 26 import com.google.crypto.tink.PublicKeySign; 27 import com.google.crypto.tink.PublicKeyVerify; 28 import com.google.crypto.tink.RegistryConfiguration; 29 import com.google.crypto.tink.TinkJsonProtoKeysetFormat; 30 import com.google.crypto.tink.daead.DeterministicAeadConfig; 31 import com.google.crypto.tink.testing.TestUtil; 32 import java.security.GeneralSecurityException; 33 import org.junit.BeforeClass; 34 import org.junit.experimental.theories.DataPoints; 35 import org.junit.experimental.theories.FromDataPoints; 36 import org.junit.experimental.theories.Theories; 37 import org.junit.experimental.theories.Theory; 38 import org.junit.runner.RunWith; 39 40 /** Unit tests for the Signature package. Uses only the public API. */ 41 @RunWith(Theories.class) 42 public final class SignatureTest { 43 44 @BeforeClass setUp()45 public static void setUp() throws Exception { 46 SignatureConfig.register(); 47 DeterministicAeadConfig.register(); // Needed for getPrimitiveFromNonSignatureKeyset_throws. 48 } 49 50 @DataPoints("templates") 51 public static final String[] TEMPLATES = 52 new String[] { 53 // Only use one key template from the RSA key managers because key generation is slow. 54 "RSA_SSA_PKCS1_3072_SHA256_F4", 55 "RSA_SSA_PSS_3072_SHA256_F4", 56 "ECDSA_P256", 57 "ECDSA_P256_RAW", 58 "ECDSA_P384_SHA384", 59 "ECDSA_P384_SHA512", 60 "ECDSA_P521", 61 "ED25519", 62 "ED25519_RAW", 63 }; 64 65 @Theory createSignVerify(@romDataPoints"templates") String templateName)66 public void createSignVerify(@FromDataPoints("templates") String templateName) 67 throws Exception { 68 if (TestUtil.isTsan()) { 69 // KeysetHandle.generateNew is too slow in Tsan. 70 return; 71 } 72 KeysetHandle privateHandle = KeysetHandle.generateNew(KeyTemplates.get(templateName)); 73 KeysetHandle publicHandle = privateHandle.getPublicKeysetHandle(); 74 75 PublicKeySign signer = 76 privateHandle.getPrimitive(RegistryConfiguration.get(), PublicKeySign.class); 77 PublicKeyVerify verifier = 78 publicHandle.getPrimitive(RegistryConfiguration.get(), PublicKeyVerify.class); 79 80 byte[] data = "data".getBytes(UTF_8); 81 byte[] sig = signer.sign(data); 82 verifier.verify(sig, data); 83 84 KeysetHandle otherPrivateHandle = KeysetHandle.generateNew(KeyTemplates.get(templateName)); 85 PublicKeyVerify otherVerifier = 86 otherPrivateHandle 87 .getPublicKeysetHandle() 88 .getPrimitive(RegistryConfiguration.get(), PublicKeyVerify.class); 89 assertThrows( 90 GeneralSecurityException.class, () -> otherVerifier.verify(sig, data)); 91 92 byte[] invalid = "invalid".getBytes(UTF_8); 93 byte[] empty = "".getBytes(UTF_8); 94 assertThrows(GeneralSecurityException.class, () -> verifier.verify(sig, invalid)); 95 assertThrows(GeneralSecurityException.class, () -> verifier.verify(invalid, data)); 96 assertThrows(GeneralSecurityException.class, () -> verifier.verify(empty, data)); 97 verifier.verify(signer.sign(empty), empty); 98 } 99 100 // Keyset with one private key for PublicKeySign, serialized in Tink's JSON format. 101 private static final String JSON_PRIVATE_KEYSET = "" 102 + "{" 103 + " \"primaryKeyId\": 775870498," 104 + " \"key\": [" 105 + " {" 106 + " \"keyData\": {" 107 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.EcdsaPrivateKey\"," 108 + " \"value\": \"GiA/E6s6KksNXrEd9hLdStvhsmdsONgpSODH/rZsBbBDehJMIiApA+NmYiv" 109 + "xRfhMuvTKZAwqETmn+WagBP/reucEjEvXkRog1AJ5GBzf+n27xnj9KcoGllF9NIFfQrDEP99FNH+Cne4" 110 + "SBhgCEAIIAw==\"," 111 + " \"keyMaterialType\": \"ASYMMETRIC_PRIVATE\"" 112 + " }," 113 + " \"status\": \"ENABLED\"," 114 + " \"keyId\": 775870498," 115 + " \"outputPrefixType\": \"TINK\"" 116 + " }" 117 + " ]" 118 + "}"; 119 120 // Keyset with the corresponding public key for PublicKeyVerify, serialized in Tink's JSON format. 121 private static final String JSON_PUBLIC_KEYSET = "" 122 + "{" 123 + " \"primaryKeyId\": 775870498," 124 + " \"key\": [" 125 + " {" 126 + " \"keyData\": {" 127 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.EcdsaPublicKey\"," 128 + " \"value\": \"IiApA+NmYivxRfhMuvTKZAwqETmn+WagBP/reucEjEvXkRog1AJ5GBzf+n2" 129 + "7xnj9KcoGllF9NIFfQrDEP99FNH+Cne4SBhgCEAIIAw==\"," 130 + " \"keyMaterialType\": \"ASYMMETRIC_PUBLIC\"" 131 + " }," 132 + " \"status\": \"ENABLED\"," 133 + " \"keyId\": 775870498," 134 + " \"outputPrefixType\": \"TINK\"" 135 + " }" 136 + " ]" 137 + "}"; 138 139 @Theory readKeysetEncryptDecrypt()140 public void readKeysetEncryptDecrypt() 141 throws Exception { 142 KeysetHandle privateHandle = 143 TinkJsonProtoKeysetFormat.parseKeyset(JSON_PRIVATE_KEYSET, InsecureSecretKeyAccess.get()); 144 KeysetHandle publicHandle = 145 TinkJsonProtoKeysetFormat.parseKeyset(JSON_PUBLIC_KEYSET, InsecureSecretKeyAccess.get()); 146 147 PublicKeySign signer = 148 privateHandle.getPrimitive(RegistryConfiguration.get(), PublicKeySign.class); 149 PublicKeyVerify verifier = 150 publicHandle.getPrimitive(RegistryConfiguration.get(), PublicKeyVerify.class); 151 152 byte[] data = "data".getBytes(UTF_8); 153 byte[] sig = signer.sign(data); 154 verifier.verify(sig, data); 155 } 156 157 // Keyset with multiple keys. The first key is the same as in JSON_PRIVATE_KEYSET. The second 158 // key is the primary key and will be used for signing. 159 private static final String JSON_PRIVATE_KEYSET_WITH_MULTIPLE_KEYS = 160 "" 161 + "{" 162 + " \"primaryKeyId\": 1641152230," 163 + " \"key\": [" 164 + " {" 165 + " \"keyData\": {" 166 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.EcdsaPrivateKey\"," 167 + " \"value\": \"GiA/E6s6KksNXrEd9hLdStvhsmdsONgpSODH/rZsBbBDehJMIiApA+NmYiv" 168 + "xRfhMuvTKZAwqETmn+WagBP/reucEjEvXkRog1AJ5GBzf+n27xnj9KcoGllF9NIFfQrDEP99FNH+Cne4" 169 + "SBhgCEAIIAw==\"," 170 + " \"keyMaterialType\": \"ASYMMETRIC_PRIVATE\"" 171 + " }," 172 + " \"status\": \"ENABLED\"," 173 + " \"keyId\": 775870498," 174 + " \"outputPrefixType\": \"TINK\"" 175 + " }," 176 + " {" 177 + " \"keyData\": {" 178 + " \"typeUrl\":" 179 + "\"type.googleapis.com/google.crypto.tink.RsaSsaPkcs1PrivateKey\"," 180 + " \"value\": \"QoACGwosE5u2kgqsgur5eBYUTK8slJ4zjjmXBI2xCKIixqtULDfgXh2ILuZ" 181 + "7y7Myt/fmjvA4QajmKMZOHFuf6h+Z1kQN+IpKxM64RhbCoaAEc+yH5Xr75V3/qzsPW1IxcM3WVmbLn+b" 182 + "gObk3snAB9sYS8ryL1YsexZcCoshmH3ImZ/egFx6c4opPUw1jYBdMon4V+RukubFm2RRgROZRw7CZh/N" 183 + "CqYEwzbdTvPgR+g/Kbruo6yLLY4Dksq9zsM8hlhNSPaGpCjzbmBsAwT6ayEyjusGWcVB79kDaI34Y3+7" 184 + "EZ2J/4nn1D07bJGCvWz60SIVRF58beeUrc+LONKAHllx00TqAAha2k6mwibOpjfrmGpgqMTKiYsqPmJX" 185 + "w+I8MaOprCzEovsnEyLrrWFpZytoaJEEZ7SBRKavV0S/B+mSc2fTfvsF2NynbHKB62z6A5ODl6YWeF0n" 186 + "yjM7NCcxNAce/iMUdZ1qcyOGsjTWDQnp0G2cgtU3AqDjKlvodrx87DxdJB8T/cLKPpEZMbtG4TDHw2zl" 187 + "jFtdrDj38JjDN6gR3zUKhtdz8qjPD5x5K5ePQ2oakI72AuXIqCZNjGSa7rs/T8Mnv+5Uqqh2SuSQ2KvR" 188 + "Fmts6it3WSMTrQZGQdhMB7rW1h5+LqioVjc1EQyMibFHUshSvjyKfw0Pvv7YKbvv606AoIgEygAKXsLn" 189 + "L7TxNSYbgG65K3g+4LVmkbwyTp4R6XM6ilZS8S2Ypqin5P3+xZefva2vu223pC9+yULO1FUU14zZR96+" 190 + "/BpGTt3O1Psi105hi0a/ATCz4RWTeydKzxu4WP4bNZ3KJ7KsbpRVjRxIOGer38t1Igl5MnVlOZSHmWHH" 191 + "nkYBqRiu+af2xWr+fJpvHF6MyoKZ7fZwFYVE8k6BiA7mjxf87IqRzLtKSHWxR75/Rxr74rErGvAdksGU" 192 + "b5YDtaoH2XRHA4pwPNPayvls0hKsdph9XsypYfM8VCTbBoR5eJWs9N0hCkE5Q74CHfzyi1y5jhXeeFn7" 193 + "Vb7CPcJJrqLUdlGpnKoAC7wKQXuC8RIg0zAwQXubmYng/q0IPrtdTsKAkc+neoZ79oxX4bK8TeJts10P" 194 + "WXvWRmlGiKG0NN9432C36ew4f8mSmZQvwsTjgpuQF/iRFh6Eq6jU4c39y+9clMI68nXAnIeA/Es16P3w" 195 + "iw0V2BW4tpSgzB4OwnWA8YRjCHEj2jA1jOg3DaMOKM0MpXHJRpNe6D4iJKwL3fUqZAeIllmaeHgczexJ" 196 + "ed3Nt8XrArZJEIwpQrxWxTU305RHSG2gaOENPTA3IG34ObNEbOrhxJ4SbjkT/o27rpVMEQMgA+MaCGXS" 197 + "kp7IPkkDMLuxpZyHd25ECjldiT1+tXvUwxGPzTEfGgSKAAv3LCIvMyivCnsG2257pZdE57CgvN/sPUDw" 198 + "ib2zmzSjyCWepLkYOecLgvJHDLUkzClKUm5w4KnCWBD4W6iWKJqRoY1qOKxlraOeKMYPnyIpDcOcb3jn" 199 + "bNxWs+QjM/BCxczjs00D7syvw2LJq4z/sD9Z8DE5e65nn9uzmLhnjukCS9MhPSesM3JIYSrK9m7jJ7Sp" 200 + "vbRpJq+1khyns9BUldhH8Fs680g4uj7XV25tRj4wbz68BQx4AuwvhAFAsVRjjHuEzaE+ic3QLM5BY+/g" 201 + "+dY73WplALotge0A/yTO2rmwS1OyCKmxUlAjO6cKoN6W7QSl7MVKUK/BL0sa2Cxy1CCMagAQQP/mjdL4" 202 + "LePycC+amQFUv3uIimL0YQ612IbaOAeJ50VM89293EQglGPB/PNBSV8BQVEe+TiTGAifI/5uFnzVBOjH" 203 + "oOoiRI/bmP3mX6HFGd81mWX6rV8BCSkelyRhwD96OLTiPv/57xIxYT/bvPmrCIADsGTqzQ2qQtVWAq60" 204 + "KnsTQtRIhcXQ0gDPuW4iJGqMQeOAm03ewcZkul68UmJjToyziP1Dcr2KLlGGVPghs3DzfHQnvm1xwIOE" 205 + "Tzv3JWXh0PCtKeTluoXILD7RDLp0mb5ieaMRCPBYMwI23BsMd6yWWf6KfPKOOOWNCzGVL+bC+VTvjueK" 206 + "Q/5tTcUvXIIeMXtgu6nWDOX3FQfMGDvSRcM7xoLe3P40vnYWHFUdpAEbRFhTRMpoDPgRXJCd8TLRSEHi" 207 + "eedCcOSMMghehAKdzxvoRM31DuPBSKYe1Qys0ApnSs51vZLHDGkOYGbcD6Q+NdmfoE3kY0k3r+vTKDVh" 208 + "+IE0QtY2HlXHOCs7VAR5HDsKIK2x/KtD6Cvf3R667bRItIZgdA6Bf+naAoxpcWwxDXSCWsmB26wa4hrC" 209 + "1qSSRsp0zB2p6vgqDkFz7e9tCR89kzWo+oRyVdAZk5gllPA6iBVsQ6xLdoN0FoPTAbKYXHricSMGYb5K" 210 + "mbHb6sAvpw147w0aOealtndgkuu1SS0XEgRKMBCIDAQABGoAE7PMXsNlwa3uE6iDnmhmoArzugzmnJRh" 211 + "ytBzcL4dGhrIOMwQncaHNfDPsTWyfjLha6Q0TfBPiDGm0Bq+/IygQM3WKofVHuH2J7+bt4WpS0ARSQbl" 212 + "fXiXazvYAD4j4LVtBE+TuBybGB/na2ui/G48452ip+FG5V7G6sEfkxis3ETgZtyTB6oDDXXaymMoGlic" 213 + "Gsuc66BWPRiko4OvnS8PRpi0yobdw65gtggDrrD/GS4H+FVq1kEOrVKFC4UZZYyaimYnl5IS1O9Pz1vm" 214 + "5epicWptFodAFo5N0CzK/hwwcocb02CuUgxONrS3Zypw+GxyMdgRI2P/Cpihm7USCOzNxjHEmNgt7Wuw" 215 + "tQChc4ZEdlZ1KXFXXEBZf6hwLNKk5Jh7MOmJfMSU9L9J1Tqkrfls268T0FEUmD0nciLRHoeqjaD9cWxa" 216 + "h89F6r1UuCo+LVsQp4y7g/qXmxUvLvFR6JPZwHx9iyTbVEe54/P2bcgbttEIYjqgs5FLt1cG6dqjKiFx" 217 + "lC8SLZJsMg1xpZNTVe7jpzX1Ot0nK8yY/UmLUrgq0AHH31N3L9a7vg6v/uI5kdWZZoASjBlVzLNgeBCo" 218 + "QGXwFdTNENeDYCAWXEgO65K1huq3UcoJjjvCTD0tlrdTNX7q915TS3e49xgJT3lB4TynAo2Fgs9OdZta" 219 + "ovVFKpiE5K6MSAggE\"," 220 + " \"keyMaterialType\": \"ASYMMETRIC_PRIVATE\"" 221 + " }," 222 + " \"status\": \"ENABLED\"," 223 + " \"keyId\": 1641152230," 224 + " \"outputPrefixType\": \"RAW\"" 225 + " }," 226 + " {" 227 + " \"keyData\": {" 228 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.EcdsaPrivateKey\"," 229 + " \"value\": \"GiBCX+pnT5vwku4z7jfD4OTgvRtft3S4KuYHovWsQrlTPhJMIiAzcsfCVUz" 230 + "GZ13oTmMLxBYd8wFM5G+dgCXMeF8tYXayrRogGOzqO4xtS0H4wl/5M/QUkLDnpnmt2TqIiQlFk0vAdck" 231 + "SBhgCEAIIAw==\"," 232 + " \"keyMaterialType\": \"ASYMMETRIC_PRIVATE\"" 233 + " }," 234 + " \"status\": \"ENABLED\"," 235 + " \"keyId\": 857170602," 236 + " \"outputPrefixType\": \"LEGACY\"" 237 + " }" 238 + " ]" 239 + "}"; 240 241 // Keyset with the public keys of the keys from JSON_PRIVATE_KEYSET_WITH_MULTIPLE_KEYS. 242 private static final String JSON_PUBLIC_KEYSET_WITH_MULTIPLE_KEYS = "" 243 + "{" 244 + " \"primaryKeyId\": 1641152230," 245 + " \"key\": [" 246 + " {" 247 + " \"keyData\": {" 248 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.EcdsaPublicKey\"," 249 + " \"value\": \"IiApA+NmYivxRfhMuvTKZAwqETmn+WagBP/reucEjEvXkRog1AJ5GBzf+n2" 250 + "7xnj9KcoGllF9NIFfQrDEP99FNH+Cne4SBhgCEAIIAw==\"," 251 + " \"keyMaterialType\": \"ASYMMETRIC_PUBLIC\"" 252 + " }," 253 + " \"status\": \"ENABLED\"," 254 + " \"keyId\": 775870498," 255 + " \"outputPrefixType\": \"TINK\"" 256 + " }," 257 + " {" 258 + " \"keyData\": {" 259 + " \"typeUrl\":" 260 + "\"type.googleapis.com/google.crypto.tink.RsaSsaPkcs1PublicKey\"," 261 + " \"value\": \"IgMBAAEagATs8xew2XBre4TqIOeaGagCvO6DOaclGHK0HNwvh0aGsg4zBCd" 262 + "xoc18M+xNbJ+MuFrpDRN8E+IMabQGr78jKBAzdYqh9Ue4fYnv5u3halLQBFJBuV9eJdrO9gAPiPgtW0E" 263 + "T5O4HJsYH+dra6L8bjzjnaKn4UblXsbqwR+TGKzcROBm3JMHqgMNddrKYygaWJway5zroFY9GKSjg6+d" 264 + "Lw9GmLTKht3DrmC2CAOusP8ZLgf4VWrWQQ6tUoULhRlljJqKZieXkhLU70/PW+bl6mJxam0Wh0AWjk3Q" 265 + "LMr+HDByhxvTYK5SDE42tLdnKnD4bHIx2BEjY/8KmKGbtRII7M3GMcSY2C3ta7C1AKFzhkR2VnUpcVdc" 266 + "QFl/qHAs0qTkmHsw6Yl8xJT0v0nVOqSt+WzbrxPQURSYPSdyItEeh6qNoP1xbFqHz0XqvVS4Kj4tWxCn" 267 + "jLuD+pebFS8u8VHok9nAfH2LJNtUR7nj8/ZtyBu20QhiOqCzkUu3Vwbp2qMqIXGULxItkmwyDXGlk1NV" 268 + "7uOnNfU63ScrzJj9SYtSuCrQAcffU3cv1ru+Dq/+4jmR1ZlmgBKMGVXMs2B4EKhAZfAV1M0Q14NgIBZc" 269 + "SA7rkrWG6rdRygmOO8JMPS2Wt1M1fur3XlNLd7j3GAlPeUHhPKcCjYWCz051m1qi9UUqmITkroxICCAQ" 270 + "=\"," 271 + " \"keyMaterialType\": \"ASYMMETRIC_PUBLIC\"" 272 + " }," 273 + " \"status\": \"ENABLED\"," 274 + " \"keyId\": 1641152230," 275 + " \"outputPrefixType\": \"RAW\"" 276 + " }," 277 + " {" 278 + " \"keyData\": {" 279 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.EcdsaPublicKey\"," 280 + " \"value\": \"IiAzcsfCVUzGZ13oTmMLxBYd8wFM5G+dgCXMeF8tYXayrRogGOzqO4xtS0H" 281 + "4wl/5M/QUkLDnpnmt2TqIiQlFk0vAdckSBhgCEAIIAw==\"," 282 + " \"keyMaterialType\": \"ASYMMETRIC_PUBLIC\"" 283 + " }," 284 + " \"status\": \"ENABLED\"," 285 + " \"keyId\": 857170602," 286 + " \"outputPrefixType\": \"LEGACY\"" 287 + " }" 288 + " ]" 289 + "}"; 290 291 @Theory multipleKeysReadKeysetWithEncryptDecrypt()292 public void multipleKeysReadKeysetWithEncryptDecrypt() 293 throws Exception { 294 KeysetHandle privateHandle = 295 TinkJsonProtoKeysetFormat.parseKeyset( 296 JSON_PRIVATE_KEYSET_WITH_MULTIPLE_KEYS, InsecureSecretKeyAccess.get()); 297 KeysetHandle publicHandle = 298 TinkJsonProtoKeysetFormat.parseKeyset( 299 JSON_PUBLIC_KEYSET_WITH_MULTIPLE_KEYS, InsecureSecretKeyAccess.get()); 300 301 PublicKeySign signer = 302 privateHandle.getPrimitive(RegistryConfiguration.get(), PublicKeySign.class); 303 PublicKeyVerify verifier = 304 publicHandle.getPrimitive(RegistryConfiguration.get(), PublicKeyVerify.class); 305 306 byte[] data = "data".getBytes(UTF_8); 307 byte[] sig = signer.sign(data); 308 verifier.verify(sig, data); 309 310 // Also test that verifier can verify signatures of a non-primary key. We use 311 // JSON_PRIVATE_KEYSET to sign with the first key. 312 KeysetHandle privateHandle1 = 313 TinkJsonProtoKeysetFormat.parseKeyset(JSON_PRIVATE_KEYSET, InsecureSecretKeyAccess.get()); 314 PublicKeySign signer1 = 315 privateHandle1.getPrimitive(RegistryConfiguration.get(), PublicKeySign.class); 316 317 byte[] data1 = "data1".getBytes(UTF_8); 318 byte[] sig1 = signer1.sign(data1); 319 verifier.verify(sig1, data1); 320 } 321 322 // A keyset with a valid DeterministicAead key. This keyset can't be used with the PublicKeySign 323 // or PublicKeyVerify. 324 private static final String JSON_DAEAD_KEYSET = 325 "" 326 + "{" 327 + " \"primaryKeyId\": 961932622," 328 + " \"key\": [" 329 + " {" 330 + " \"keyData\": {" 331 + " \"typeUrl\": \"type.googleapis.com/google.crypto.tink.AesSivKey\"," 332 + " \"keyMaterialType\": \"SYMMETRIC\"," 333 + " \"value\": \"EkCJ9r5iwc5uxq5ugFyrHXh5dijTa7qalWUgZ8Gf08RxNd545FjtLMYL7ObcaFtCS" 334 + "kvV2+7u6F2DN+kqUjAfkf2W\"" 335 + " }," 336 + " \"outputPrefixType\": \"TINK\"," 337 + " \"keyId\": 961932622," 338 + " \"status\": \"ENABLED\"" 339 + " }" 340 + " ]" 341 + "}"; 342 343 @Theory getPrimitiveFromNonSignatureKeyset_throws()344 public void getPrimitiveFromNonSignatureKeyset_throws() 345 throws Exception { 346 KeysetHandle handle = 347 TinkJsonProtoKeysetFormat.parseKeyset( 348 JSON_DAEAD_KEYSET, InsecureSecretKeyAccess.get()); 349 350 // Test that the keyset can create a DeterministicAead primitive, but neither PublicKeySign 351 // nor PublicKeyVerify primitives. 352 Object unused = handle.getPrimitive(RegistryConfiguration.get(), DeterministicAead.class); 353 assertThrows( 354 GeneralSecurityException.class, 355 () -> handle.getPrimitive(RegistryConfiguration.get(), PublicKeySign.class)); 356 assertThrows( 357 GeneralSecurityException.class, 358 () -> handle.getPrimitive(RegistryConfiguration.get(), PublicKeyVerify.class)); 359 } 360 } 361