1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.keystore.cts; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertSame; 24 import static org.junit.Assert.assertTrue; 25 import static org.junit.Assert.fail; 26 27 import android.content.Context; 28 import android.keystore.cts.util.EmptyArray; 29 import android.keystore.cts.util.ImportedKey; 30 import android.keystore.cts.util.StrictModeDetector; 31 import android.keystore.cts.util.TestUtils; 32 import android.security.keystore.KeyInfo; 33 import android.security.keystore.KeyPermanentlyInvalidatedException; 34 import android.security.keystore.KeyProperties; 35 import android.security.keystore.KeyProtection; 36 37 import androidx.test.InstrumentationRegistry; 38 import androidx.test.runner.AndroidJUnit4; 39 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 import java.security.InvalidKeyException; 44 import java.security.KeyFactory; 45 import java.security.KeyPair; 46 import java.security.KeyStore; 47 import java.security.PrivateKey; 48 import java.security.Provider; 49 import java.security.Provider.Service; 50 import java.security.PublicKey; 51 import java.security.Security; 52 import java.security.Signature; 53 import java.security.SignatureException; 54 import java.util.Arrays; 55 import java.util.Collection; 56 import java.util.Date; 57 import java.util.HashSet; 58 import java.util.Locale; 59 import java.util.Map; 60 import java.util.Set; 61 import java.util.TreeMap; 62 63 /** 64 * Tests for algorithm-agnostic functionality of {@code Signature} implementations backed by Android 65 * Keystore. 66 */ 67 @RunWith(AndroidJUnit4.class) 68 public class SignatureTest { 69 70 static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME; 71 72 static final String[] EXPECTED_SIGNATURE_ALGORITHMS = { 73 "NONEwithRSA", 74 "MD5withRSA", 75 "SHA1withRSA", 76 "SHA224withRSA", 77 "SHA256withRSA", 78 "SHA384withRSA", 79 "SHA512withRSA", 80 "SHA1withRSA/PSS", 81 "SHA224withRSA/PSS", 82 "SHA256withRSA/PSS", 83 "SHA384withRSA/PSS", 84 "SHA512withRSA/PSS", 85 "NONEwithECDSA", 86 "SHA1withECDSA", 87 "SHA224withECDSA", 88 "SHA256withECDSA", 89 "SHA384withECDSA", 90 "SHA512withECDSA" 91 }; 92 93 private static final Map<String, String> SIG_ALG_TO_CANONICAL_NAME_CASE_INSENSITIVE = 94 new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); 95 static { 96 // For an unknown legacy reason, libcore's ProviderTest#test_Provider_getServices insists 97 // that a Service with algorithm "ECDSA" be exposed, despite the RI not exposing any such 98 // services. Thus, our provider has to expose the "ECDSA" service whose actual proper 99 // name is SHA1withECDSA. 100 SIG_ALG_TO_CANONICAL_NAME_CASE_INSENSITIVE.put("ECDSA", "SHA1withECDSA"); 101 } 102 103 private static final byte[] SHORT_MSG_KAT_MESSAGE = 104 HexEncoding.decode("ec174729c4f5c570ba0de4c424cdcbf0362a7718039464"); 105 private static final byte[] LONG_MSG_KAT_SEED = SHORT_MSG_KAT_MESSAGE; 106 private static final int LONG_MSG_KAT_SIZE_BYTES = 3 * 1024 * 1024 + 123; 107 108 private static final Map<String, byte[]> SHORT_MSG_KAT_SIGNATURES = 109 new TreeMap<String, byte[]>(String.CASE_INSENSITIVE_ORDER); 110 static { 111 // From RI 112 SHORT_MSG_KAT_SIGNATURES.put("NONEwithECDSA", HexEncoding.decode( 113 "304402201ea57c2fb571991639d103bfec658ee7f359b60664e400a5834cfc20d28b588902202433f5" 114 + "eb07d2b03bf8d238ea256ea399d0913a6cfcae2c3b00e2efd50aebc967")); 115 SHORT_MSG_KAT_SIGNATURES.put("SHA1withECDSA", HexEncoding.decode( 116 "30440220742d71a013564ab196789322b9231ac5ff26460c2d6b1ab8ccb45eec254cc8ba0220780a86" 117 + "5ddc2334fae23d563e3142b04660c2ab1b875c4ff8c557a1d1accc43e1")); 118 SHORT_MSG_KAT_SIGNATURES.put("SHA224withECDSA", HexEncoding.decode( 119 "304502200f74966078b34317daa69e487c3163dbb4e0391cd74191cc3e95b33fc60966e3022100ebdc" 120 + "be19c516d550609f73fb37557a406e397bc1725a1baba50cdfc3537bd377")); 121 SHORT_MSG_KAT_SIGNATURES.put("SHA256withECDSA", HexEncoding.decode( 122 "304402204443b560d888beeae729155b0d9410fef2ec78607d9166af6144346fba8ce45d02205b0727" 123 + "bfa630050f1395c8bcf46c614c14eb15f2a6abbd3bc7c0e83b41819281")); 124 SHORT_MSG_KAT_SIGNATURES.put("SHA384withECDSA", HexEncoding.decode( 125 "3045022025ade03446ce95aa525a51aedd16baf12a2b8b9c1f4c87224c38e48c84cbbbf8022100ad21" 126 + "8424c3671bc1513e1da7e7186dbc6bf67bec434c95863a48e79f53684971")); 127 SHORT_MSG_KAT_SIGNATURES.put("SHA512withECDSA", HexEncoding.decode( 128 "3045022100969e8fed2dc4ddcdf341368e057efe4e3a00eda66bbb127dec31bb0144c5334602201087" 129 + "2b7f9ab9c06a07053e0641e6adc18a87a1d7807550a19e872e78e5c7f0dd")); 130 131 // From RI 132 SHORT_MSG_KAT_SIGNATURES.put("NONEwithRSA", HexEncoding.decode( 133 "257d0704e514ead29a5c45576adb2d5a7d7738e6a83b5d6463a5306788015d14580fee340e78e00d39" 134 + "f56ae616083ac929e5daf9eeab40b908eb05d0cd1036d9e92799587df0d4c5304c9b27f913e1c891" 135 + "919eff0df3b5d9c0d8cc4cd843795840799cc0353192c3868b3f8cad96d04bb566ca53e1146aa2a3" 136 + "4b890ce917680bbdea1dee417a89630224d2ee79d66d38c7c77e50b45e1dd1b8b63eb98ecd60426b" 137 + "c9fb30917e78ae4dd7cbfa9475f9be53bf45e7032add52681553679252f4f74de77831c95ea69f30" 138 + "2f0fd28867de058728455e3537680c86a001236e70c7680c78b4dc98942d233b968635a0debccb41" 139 + "fbc17ece7172631f5ab6d578d70eb0")); 140 SHORT_MSG_KAT_SIGNATURES.put("MD5withRSA", HexEncoding.decode( 141 "1e1edefc9a6a4e61fcef0d4b202cc2b53ab9043b1a0b21117d122d4c5399182998ec66608e1ab13513" 142 + "08fbb23f92d5d970f7fb1a0691f8d1e682ff4f5e394ef2dfcbdc2de5c2c33372aec9a0c7fba982c5" 143 + "c0f1a5f65677d9294d54a2e613cc0e5feb919135e883827da0e1c222bf31336afa63a837c57c0b70" 144 + "70ceb8a24492a42afa6750cc9fe3a9586aa15507a65410db973a4b26734624d323dc700928717789" 145 + "fb1f970d57326eef49e012fcebcfbbfd18fb4d6feff03587d0f2b0a556fe467437a44a2283ea5027" 146 + "6efda4fd427365687960e0c289c5853a7b300ff081511a2f52899e6f6a569b30e07adfd52e9d9d7e" 147 + "ab33999da0da1dd16d4e88bd980fcd")); 148 SHORT_MSG_KAT_SIGNATURES.put("SHA1withRSA", HexEncoding.decode( 149 "280977b4ee18cbe27d3e452c9b90174f5d81dd518018ce52ff1cd1e8d4d0626afca85be14a43fa3b76" 150 + "a80e818b4bc10abc62180fa15619d78be98ccd8fa642ea05355aa84f2924e041c2b594b1cf31d42b" 151 + "f11c78dd3cbb6cc2cbfe151792985e6e5cf73c2e600a38f31e26e84c3e4a434f67a625fefe712d17" 152 + "b34125ea91d333cfe1c4ac914b6c411b08e64700885325e07510c4f49ef3648252736f17d3ae7705" 153 + "0054ceb07ab04b5ecaa5fc4556328bad4f97eba37f9bf079506e0eb136c9eadf9e466ccb18d65b4d" 154 + "ef2ba3ca5c2f33354a2040dfb646423f96ba43d1d8f3dcf91c0c2c14e7958159d2ac3ebc0b6b87e6" 155 + "6efbdda046ce8a766fecc3f905d6ff")); 156 SHORT_MSG_KAT_SIGNATURES.put("SHA224withRSA", HexEncoding.decode( 157 "490af9e685ef44da9528d9271d00e09a3e688012bf3f63fd924a06cb4db747a28cdf924c2d51620165" 158 + "33985abf4b91d64c17ff7e2b4f0de5a28375dddf556cd9e5dcebd112f766f07cb867e8d5710ce79a" 159 + "1c3d5244cbd16618b0fedc2b9015d51a98d453747fb320b97995ea9579adbc8bf6042b2f4252cef1" 160 + "787207fefaf4b9c7212fe0ff8b22ae12ffc888f0a1e6923455577e82b58608dabc2acba05be693ff" 161 + "ae7da263d6c83cb13d59a083f177578d11030f8974bdb301f6135ecd5ec18dd68dc453c5963e94b6" 162 + "2d89bcda0ff63ac7394030f79b59139e1d51573f0d4a1e85d22502c9b0d29412f7eb277fb42fa4db" 163 + "18875baffa7719b700e4830edbcd6f")); 164 SHORT_MSG_KAT_SIGNATURES.put("SHA256withRSA", HexEncoding.decode( 165 "1f1adcd6edbf4c50777c932db6e99a577853fbc9c71c692e921291c5aa73eb0155e30c8d4f3aff828f" 166 + "2040c84e10b1ba729ccc23899650451022fcd3574df5454b01112adec5f01565b578bbc7c32810c9" 167 + "407106054ad8f4f640b589ddef264d028ad906536d61c8053ef0dba8e10ca2e30a9dd6ccc9a9ec3e" 168 + "76c10d36029820865b2d01095987af4a29369ffc6f70fa7e1de2b8e28f41894df4225cf966454096" 169 + "7fb7ecff443948c8a0ee6a1be51e0f8e8887ff512dbdc4fc81636e69ae698000ce3899c2ec999b68" 170 + "691adfb53092380264b27d91bd64561fee9d2e622919cf6b472fd764dc2065ae6a67df2c7b5ec855" 171 + "099bdb6bb104ee41fa129c9da99745")); 172 SHORT_MSG_KAT_SIGNATURES.put("SHA384withRSA", HexEncoding.decode( 173 "3b5e8baa62803569642fa8c3255249709c9f1d69bd31f7b531d5071c07cd9bac29273097666d96b2e3" 174 + "2db13529b6414be5aee0c8a90c3f3b2a5c815f37fac16a3527fa45903f847416ed218eee2fef5b87" 175 + "5f0c97576f58b3467e83497c1cdeea44d0ea151e9c4d27b85eef75d612b1fc16731859738e95bdf1" 176 + "2f2098ebd501d8493c66585e8545fb13d736f7dbbb530fb06f6f157cd10c332ca498b379336efdaf" 177 + "a8f940552da2dbb047c33e87f699068eaadd6d47c92a299f35483ba3ae09f7e52a205f202c1af997" 178 + "c9bdc40f423b3767292c7fcea3eaf338a76f9db07a53d7f8d084bf1ceac38ec0509e442b1283cd8f" 179 + "013c4c7a9189fe4ef9ab00c80cb470")); 180 SHORT_MSG_KAT_SIGNATURES.put("SHA512withRSA", HexEncoding.decode( 181 "23eb7577d2ffefed10780c2a26f79f64abe08203e900db2333413f30bbc81f800857857c8b0e02c3e8" 182 + "8fe3cf5514130d6216ef7c4a86b1012594c7cb07a293159b92bf40291224386a84e607e0a8389c8a" 183 + "a0c45cc553037517c52f61fe0ea51dba184e890db7d9517760724c038018330c0a9450c280430e6f" 184 + "9e4cdd4545c3f6684485cd6e27203735ff4be76420071920b18c54d98c0e3eb7ae7d1f01f5171ace" 185 + "87885c6185f66d947d51a441a756bc953458f7d3a1714226899562478ebf91ab18d8e7556a966661" 186 + "31de37bc2e399b366877f53c1d88f93c989aeb64a43f0f6cbc2a29587230f7e3e90ea18868d79584" 187 + "3e62b49f5df78e355b437ec2f882f9")); 188 189 // From Bouncy Castle 190 SHORT_MSG_KAT_SIGNATURES.put("SHA1withRSA/PSS", HexEncoding.decode( 191 "17e483781695067a25bc7cb204429a8754af36032038460e1938c28cd058025b14d2cffe5d3da39e76" 192 + "6542014e5419f1d4c4d7d8e3ebcd2221dde04d24bbbad657f6782b7a0fada3c3ea595bc21054b0ab" 193 + "d1eb1ada86276ed31dbcce58be7407cbbb924d595fbf44f2bb6e3eab92296076e291439107e67912" 194 + "b4fac3a27ff84af7cd2db1385a8340b2e49c7c2ec96a6b657a1641da80799cb88734cca35a2b3a2c" 195 + "4af832a34ac8d3134ccc8b61150dc1b64391888a3a84bdb5184b48e8509e8ba726ba8847e4ca0640" 196 + "ce615e3adf5248ce08adb6484f6f29caf6c65308ec6351d97369ae005a7c762f76f0ddc0becc3e45" 197 + "529aa9c8391473e392c9a60c2d0834")); 198 SHORT_MSG_KAT_SIGNATURES.put("SHA224withRSA/PSS", HexEncoding.decode( 199 "3b7641a49e7766ed879f2b0e33ceb3d935678a7deffbd855a97abf00a65c981814ac54a71150b2ffea" 200 + "d5db83aa96d0939267b3c5e2fcf958e9c6fdf7d90908e6139f7f330a16dc625d8268ffd324659f6c" 201 + "e36798ef3b71a92f1d2237e3ce1e281aacc1d5370ae63c9b75e7134ad15cca1410746bf259ac4519" 202 + "c407877503900ec8f3b71edce727e9d0275c9cd48385f89ce76ed17a2bf246578f183bb6577d6942" 203 + "2056c7d9145528fc8ca036926a9fafe819f37c1a4a0a69b17f3d4b0a116106f94a5d2a5f8ce6981c" 204 + "d6e5c2f858dcb0823e725fffe6be14ca882c81fa993bebda549fcf983eb7f8a87eccd545951dcdc9" 205 + "d8055ae4f4067de997cfd89952c905")); 206 SHORT_MSG_KAT_SIGNATURES.put("SHA256withRSA/PSS", HexEncoding.decode( 207 "6f0f744fa8e813b4c7caa0c395c1aa8aee0d61e621b4daae305c759b5b5972311ad691f8867821efba" 208 + "d57995cc8ff38f33393293e94e1c484e94de4816b0fd986f5710a02d80e62461cc6f87f1f3742268" 209 + "c28a54870f290d136aa629cbe00a1bf243fab1674c04cd5910a786b2ac5e71d9c6f4c41daa4c584d" 210 + "46ba7ee768d2d2559be587a7b2009f3b7497d556a0da8a8ae80ce91152c81ffba62720d36b699d1f" 211 + "157137ff7ee7239fc4baf611d01582346e201900f7a4f2617cdf574653e124fb895c6cb76d4ed5a8" 212 + "aca97d1e408e8011eba649d5617bae8b27c1b946dcff7b29151d8632ad128f22907e8b83b9149e16" 213 + "fbb9e9b87600a2f90c1fd6dc164c52")); 214 SHORT_MSG_KAT_SIGNATURES.put("SHA384withRSA/PSS", HexEncoding.decode( 215 "8e57992362ad4b0487a707b2f8811d953f5aaf800978859981e7dcddad6f9f411fb162859115577c53" 216 + "7a3524e26bf069508185848d6e29e7da1f9660a49771533e43853e02232314afd2928a1ff1824345" 217 + "a5a90309a59d213ff6a4d04520f95a976342e6ac529ec6a6821157f4fee3bdae30d836d3ab44386d" 218 + "3914e6aacd6a6a63e1d63b4d9bfb93b343b6c1f28d60042ffbe1e46fb692a381456e84b3328dbcae" 219 + "ed6fc577cb1c5f86a38c5c34d439eeee7e798edc9f2bcd4fc217b1630e45b8df67def2c2cdb9fea0" 220 + "5d67aa6cce6e9a72e9a114e2e620a54c05755e32685ffc7e50487c3cd00888c09492fad8c461c338" 221 + "e7d099b275deaf184b7d6689385f7c")); 222 SHORT_MSG_KAT_SIGNATURES.put("SHA512withRSA/PSS", HexEncoding.decode( 223 "7a40f9f2797beda0702df0520c7138269295a0f0328aab4eba123ebf178ea4abc745ed42d3b175dc70" 224 + "c8dcc98f46f2234b392dbb3e939f30888715c4fbb47fbb5bb7c0557c140c579f48226710e5b3da0d" 225 + "9511337cde5626df586b4004100dd45490e5f8ae23307b5d1054c97e9ef58f9c385ca55b6db4f58d" 226 + "2e19bc8ca9d8c2b4922fb3325b6fb61fc40a359e9196aa9388845b136d2790d71410e20371dcf0a7" 227 + "0425ee1854c5c3d7de976b28de0ee9b1048ed99b2a957edc97466cc4c87e36224fd323605228f61a" 228 + "1aad30253b0698f9a358491138027d325d46bdfdf72171c57a2dab0a9cddaad8e170b8275c172e42" 229 + "33b29ed81c0f4de9fe9f0670106aad")); 230 } 231 232 private static final Map<String, byte[]> LONG_MSG_KAT_SIGNATURES = 233 new TreeMap<String, byte[]>(String.CASE_INSENSITIVE_ORDER); 234 static { 235 // From RI 236 LONG_MSG_KAT_SIGNATURES.put("NONEwithECDSA", HexEncoding.decode( 237 "304502206e4039608a66ce118821eeca3e2af7f530f51d1ce8089685a13f49010e3cd58b02210083a5" 238 + "fe62a171f1b1d775fad712128a223d6b63336e0248783652474221cb3193")); 239 LONG_MSG_KAT_SIGNATURES.put("SHA1withECDSA", HexEncoding.decode( 240 "3044022075f09bb5c87d883c088ca2ad263bbe1754ab614f727465bc43695d3521eaccf80220460e4e" 241 + "32421e6f4398cd9b7fbb31a1d1f2961f26b9783620f6413f0e6f7efb84")); 242 LONG_MSG_KAT_SIGNATURES.put("SHA224withECDSA", HexEncoding.decode( 243 "3045022100d6b24250b7d3cbd329913705f4990cfd1000f338f7332a44f07d7731bd8e1ff602200565" 244 + "0951e14d0d21c4344a449843ef65ac3a3f831dc7f304c0fa068c996f7d34")); 245 LONG_MSG_KAT_SIGNATURES.put("SHA256withECDSA", HexEncoding.decode( 246 "30440220501946a2c373e8da19b36e3c7718e3f2f2f16395d5026ac4fbbc7b2d53f9f21a0220347d7a" 247 + "46685282f308bacd5fb25ae92b351228ea39082784789696580f27eed1")); 248 LONG_MSG_KAT_SIGNATURES.put("SHA384withECDSA", HexEncoding.decode( 249 "30450220576836de4ab94a869e867b2360a71dc5a0b3351ea1c896b163206db7c3507dc2022100c1a6" 250 + "719052a175e023bca7f3b9bb7a379fc6b51864cb28a195076d2f3c79ed2e")); 251 LONG_MSG_KAT_SIGNATURES.put("SHA512withECDSA", HexEncoding.decode( 252 "304402204ca46bac4e43e8694d1af38854c96024a4e9bcc55c6904c1f8fea0d1927f69f7022054662e" 253 + "84b4d16b9f7e8164f4896212dec3c7c1e7fd108f69b0dff5bc15399eeb")); 254 255 // From RI 256 LONG_MSG_KAT_SIGNATURES.put("MD5withRSA", HexEncoding.decode( 257 "7040f3e0d95f4d22719d26e5e684dbcd5ed52ab4a7c5aa51b938b2c060c79eb600f9c9771c2fcda7e3" 258 + "55e7c7b5e2ba9fe9a2a3621881c0fe51702781ffcde6ce7013218c04bb05988346c2bed99afb97a8" 259 + "113fb50697adf93791c9129e938040f91178e35d6f323cfa515ea6d2112e8cce1302201b51333794" 260 + "4a5c425cecc8181842ace89163d84784599ea688060ad0d61ac92b673feabe01ae5e6b85d8b5e8f0" 261 + "519aea3c29781e82df9153404d027d75df8370658898ed348acf4e13fd8f79c8a545881fbbf585e1" 262 + "c666be3805e808819e2cc730379f35a207f9e0e646c7ab6d598c75b1901f0c5ca7099e34f7f01579" 263 + "3b57dfb5c2a32e8423bfed6215f9d0")); 264 LONG_MSG_KAT_SIGNATURES.put("SHA1withRSA", HexEncoding.decode( 265 "187d7689206c9dd03861009c6cb62c7752fd2bbc354f0bea4e76059fe582744c80027175112a3df4b6" 266 + "3b4a5626ed3051192e3c9b6d906497472f6df81171064b59114ff5d7c60f66943549634461cfadd8" 267 + "a033cba2b8781fb7936ea1ca0043da119856a21e533afa999f095cf87604bb33a14e8f82fab01998" 268 + "9ef3133e8069708670645ddd5cdc86bbe19fbf672b409fb6d7cae2f913814cd3dc8d5ae8e4037ccf" 269 + "4a3ef97db8c8a08516716258c4b767607c51dfb289d90af014d3cfc64dbadb2135ed59728b78fda0" 270 + "823fe7e68e84280c283d21ab660364a9bf035afa9a7262bade87057a63aa1d7e2c09bb9dd037bcbd" 271 + "7b98356793bc32be81623833c6ab62")); 272 LONG_MSG_KAT_SIGNATURES.put("SHA224withRSA", HexEncoding.decode( 273 "31ff68ddfafcf3ff6e651c93649bf9cc06f4138493317606d8676a8676f9d9f3a1d5e418358f79d143" 274 + "a922a3cfc5e1ad6765dc829b556c9019a6d9389144cc6a7571011c024c0514891970508dac5f0d26" 275 + "f26b536cf3e4511b5e72cd9f60590b387d8a351a9f28839a1c5be5272cb75a9062aa313f3d095074" 276 + "6d0a21d4f8c9a94d3bb4715c3ef0207cf1335653161a8f78972329f3ec2fa5cfe05318221cb1f535" 277 + "8151dde5410f6c36f32287a2d5e76bf36134d7103fc6810a1bb8627de37d6b9efde347242d08b0b6" 278 + "2b1d73bacd243ccc8546536080b42a82b7162afeb4151315746a14b64e45226c9f5b35cf1577fc6b" 279 + "f5c882b71deb7f0e375db5c0196446")); 280 LONG_MSG_KAT_SIGNATURES.put("SHA256withRSA", HexEncoding.decode( 281 "529c70877dedf3eb1abda98a2f2b0fc899e1edece70da79f8f8bbceb98de5c85263bef2ef8a7322624" 282 + "5ed2767045ea6965f35cb53e6ac1d6c62e8007a79962507d3e01c77d4e96674344438519adae67d9" 283 + "6357da5c4527969c939fd86f3b8685338c2be4bf6f1f85527b11fcaa4708f925e8bb9b877bda179b" 284 + "d1b45153ef22834cf593ecc5b6eca3deddbe5d05894e4e5707d71bc35ea879ccb6e8ffc32e0cdc5e" 285 + "88a30eef7a608d9ea80b5cefec2aa493a3b1354ad20e88ab1f8bfda3bd9961e10f0736d1bc090d57" 286 + "b93fbce3e6e2fc99e67c7b466188d1615b4150c206472e48a9253b7549cebf6c7cbb558b54e10b73" 287 + "c8b1747c18d1890a24d0a835ee710a")); 288 LONG_MSG_KAT_SIGNATURES.put("SHA384withRSA", HexEncoding.decode( 289 "5dd3553bc594c541937dac9a8ac119407712da7564816bcdc0ca4e14bc6059b9f9bd72e99be8a3df3e" 290 + "0a3c4e8ed643db9ed528b43a396dba470ad3307815bd7c75fa5b08775a378cc4203341379087dcb3" 291 + "62a5e9f5c979744e4498a6aafd1b1a8069caf4ef437f2743754861fcc96d67a0f1dd3397bb65ede3" 292 + "18d2b3628eb2c3ec5db8a3e21fbbe2629f1030641e420963abc4da99e24dd497337c8149a52d97da" 293 + "7176c0767d72e18f8c9a49e6808509837f719fd16ba27b19a2b32bd19b9b14818e0b9be81062be77" 294 + "4fb1b3105a1528170822391915a5cd12b8e79aaab7943c34094da4c4f8d56f52177db953d3bf7846" 295 + "f0e5f22f2311054a1daba4fec6b589")); 296 LONG_MSG_KAT_SIGNATURES.put("SHA512withRSA", HexEncoding.decode( 297 "971d6350337866fbcb48c49446c50cac1995b822cfec8f2a3e2c8206158a2ddfc8fc7b38f5174b3288" 298 + "91489e7b379829bac5e48cd41e9713ea7e2dc9c61cf90d255387d31818d2f161ec5c3a977b4ce121" 299 + "62fb11ede30d1e63c0fbba8a4094e6ad39e64176a033e7130bbed71a67ff1713b45f0bedeb1ee532" 300 + "15690f169452c061cd7d15e71cc754a2f233f5647af8373d2b583e98e4242c0a0581e0ce2b22e15a" 301 + "443b0ff23d516ed39664f8b8ab5ca98a44af500407941fae97f37cb1becbcbff453608cb94a176d9" 302 + "e702947fff80bc8d1e9bcdef2b7bbe681e15327cee50a72649aed0d730df7b3c9c31b165416d9c9f" 303 + "1fcb04edbf96514f5758b9e90ebc0e")); 304 305 // From Bouncy Castle 306 LONG_MSG_KAT_SIGNATURES.put("SHA1withRSA/PSS", HexEncoding.decode( 307 "54a2050b22f6182b65d790da80ea16bfbc34b0c7e564d1a3ce4450e9b7785d9eaa14814dee8699977a" 308 + "e8da5cfb3c55c9a623ca55abcc0ef4b3b515ce31d49a78db442f9db270d35a179baf71057fe8d6d2" 309 + "d3f7e4fd5f5c80e11dc059c72a1a0373f527d88089c230525f895ee19e45f5547572083418c9e542" 310 + "5ff44e407500d1c49159484f38e4b00523c2fa45b7b9b38a2c1ad676b36f02a06db6fca52bd79ba1" 311 + "94d5062f5035a12a1f026ac216789844a5da0caa4d481386a12ca635c06b877515ce3782d9189d87" 312 + "d1ff5ec6ec7c39437071c8db7d1c2702205da4cfb01805ca7fec5595dba2234602ca5347d30538cb" 313 + "4b5286c151609afcca890a6276d5e8")); 314 LONG_MSG_KAT_SIGNATURES.put("SHA224withRSA/PSS", HexEncoding.decode( 315 "7e95c1e4f700ceaf9ce72fd3f9f245ba80f2e1341341c49521779c8a79004f9c534297441330b9df36" 316 + "bb23467eb560e5e5538612cecc27953336a0d4d8044d5a80f6bcef5299830215258c574d271ea6cd" 317 + "7117c2723189385435b0f06951ff3d6a700b23bc7ed3298cfb6aa65e8f540717d57f8b55290a4862" 318 + "034d9f73e8d9cb6ae7fa55a8b4c127535b5690122d6405cb0c9a313808327cfd4fb763eae875acd1" 319 + "b60e1920ecf1116102cc5f7d776ed88e666962f759258d6f5454c29cb99b8f9ccad07d209671b607" 320 + "014d19009e392bfb08247acf7f354458dc51196d84b492798dd829b7300c7591d42c58f21bd2c3d1" 321 + "e5ce0a0d3e0aa8aa4b090b6a619fc6")); 322 LONG_MSG_KAT_SIGNATURES.put("SHA256withRSA/PSS", HexEncoding.decode( 323 "5a8c0ae593a6714207b3ad83398b38b93da18cfda73139ea9f02c88a989368ae6901357194a873dd2e" 324 + "8cd1bb86d1f81fbc8bf725538dc2ad60759f8caab6a98a6baa6014874a92d4b92ed72e73f2721ba2" 325 + "86e545924860d27210b53f9308c4fec622fdfca7dd6d51a5b092184114e9dcf57636cdabaca17b49" 326 + "70cd5e93ce12c30af6d09d6964c5ad173095ea000529620d94a25b4cc977deefd25cc810a7b11cd5" 327 + "e5b71c9276b0bd33c53db01304b359a4a88f3fe8bc3335669f7609b0f6da17e49ad87f38468fa2c6" 328 + "8134ba6df407207559355b6e486a745009931796ab0567c9bd61788073aa00113b324fa25bd32b4d" 329 + "3521e98e0b4905c6dce30d70387a2e")); 330 LONG_MSG_KAT_SIGNATURES.put("SHA384withRSA/PSS", HexEncoding.decode( 331 "7913f13dc399adb07cd96c1bb484f999d047efcd96501c92477d2234a1da94db9c6fd65a8031bd3040" 332 + "82d90ef4a4f388e670795d144ef72a160583d4a2c805415542fa16ffd8760d2f28bdc82f63db0900" 333 + "a3554bc9175dafa1899249abd49591216ba2965a4862d0f59d8b8c8d1042ed7ac43a3a15650d578a" 334 + "2ea53696e462f757b326b7f0f7610fb9934aee7d954a45ca03ef66464a5611433e1224d05f783cd1" 335 + "935eff90015140cb35e15f2bbf491a0d6342ccef57e453f3462412c5ff4dfdc44527ea76c6b05b1d" 336 + "1330869aec1b2f41e7d975eba6b056e7c2f75dd73b1eff6d853b9507f410279b02f9244b656a1aca" 337 + "befcc5e1167df3a49c4a7d8479c30f")); 338 LONG_MSG_KAT_SIGNATURES.put("SHA512withRSA/PSS", HexEncoding.decode( 339 "43ffefe9c96014312679a2e3803eb7c58a2a4ab8bb659c12fec7fb574c82aed673e21ed86ac309cf6c" 340 + "e567e47b7c6c83dcd72e3ee946067c2004689420528174d028e3d32b2b306bcbcb6a9c8e8b83918f" 341 + "7415d792f9d6417769def3316ed61898443d3ffa4dc160e5b5ecf4a11a9dfed6b4a7aa65f0f2c653" 342 + "4f7e514aed73be441609ffca29207b4ced249058543fd6e13a02ef42babe2cdf4aaba66b42e9d47f" 343 + "c79b4ed54fbc28d9d732f2e468d43f0ca1de6fd5312fad2c4e3eaf3e9586bca6a8bab24b4dfab8b3" 344 + "9a4057c8ed27024b61b425036bea5e23689cd9db2450be47ec2c30bb6707740c70a53b3e7a1c7ecf" 345 + "f04e3de1460e60e9be7a42b1ddff0c")); 346 } 347 348 private static final long DAY_IN_MILLIS = TestUtils.DAY_IN_MILLIS; 349 getContext()350 private Context getContext() { 351 return InstrumentationRegistry.getInstrumentation().getTargetContext(); 352 } 353 354 @Test testAlgorithmList()355 public void testAlgorithmList() { 356 // Assert that Android Keystore Provider exposes exactly the expected signature algorithms. 357 // We don't care whether the algorithms are exposed via aliases, as long as the canonical 358 // names of algorithms are accepted. 359 // If the Provider exposes extraneous algorithms, it'll be caught because it'll have to 360 // expose at least one Service for such an algorithm, and this Service's algorithm will 361 // not be in the expected set. 362 363 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 364 Set<Service> services = provider.getServices(); 365 Set<String> actualSigAlgsLowerCase = new HashSet<String>(); 366 Set<String> expectedSigAlgsLowerCase = new HashSet<String>( 367 Arrays.asList(TestUtils.toLowerCase(EXPECTED_SIGNATURE_ALGORITHMS))); 368 //TODO(b/233037333): Move this value to the EXPECTED_SIGNATURE_ALGORITHMS array, once 369 //we have confirmed key import is working for Ed25519 and have a key to import. 370 expectedSigAlgsLowerCase.add("ed25519"); 371 for (Service service : services) { 372 if ("Signature".equalsIgnoreCase(service.getType())) { 373 String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US); 374 if (!expectedSigAlgsLowerCase.contains(algLowerCase)) { 375 // Unexpected algorithm -- check whether it's an alias for an expected one 376 String canonicalAlgorithm = 377 SIG_ALG_TO_CANONICAL_NAME_CASE_INSENSITIVE.get(algLowerCase); 378 if (canonicalAlgorithm != null) { 379 // Use the canonical name instead 380 algLowerCase = canonicalAlgorithm.toLowerCase(); 381 } 382 } 383 actualSigAlgsLowerCase.add(algLowerCase); 384 } 385 } 386 387 TestUtils.assertContentsInAnyOrder(actualSigAlgsLowerCase, 388 expectedSigAlgsLowerCase.toArray(new String[0])); 389 } 390 391 @Test testAndroidKeyStoreKeysHandledByAndroidKeyStoreProviderWhenSigning()392 public void testAndroidKeyStoreKeysHandledByAndroidKeyStoreProviderWhenSigning() 393 throws Exception { 394 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 395 assertNotNull(provider); 396 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 397 try { 398 KeyPair keyPair = importDefaultKatKeyPair(sigAlgorithm).getKeystoreBackedKeyPair(); 399 Signature signature = Signature.getInstance(sigAlgorithm); 400 signature.initSign(keyPair.getPrivate()); 401 assertSame(provider, signature.getProvider()); 402 } catch (Throwable e) { 403 throw new RuntimeException(sigAlgorithm + " failed", e); 404 } 405 } 406 } 407 408 @Test testAndroidKeyStorePublicKeysAcceptedByHighestPriorityProviderWhenVerifying()409 public void testAndroidKeyStorePublicKeysAcceptedByHighestPriorityProviderWhenVerifying() 410 throws Exception { 411 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 412 assertNotNull(provider); 413 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 414 try { 415 KeyPair keyPair = importDefaultKatKeyPair(sigAlgorithm).getKeystoreBackedKeyPair(); 416 Signature signature = Signature.getInstance(sigAlgorithm); 417 signature.initVerify(keyPair.getPublic()); 418 } catch (Throwable e) { 419 throw new RuntimeException(sigAlgorithm + " failed", e); 420 } 421 } 422 } 423 424 @Test testValidSignatureGeneratedForEmptyMessage()425 public void testValidSignatureGeneratedForEmptyMessage() 426 throws Exception { 427 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 428 assertNotNull(provider); 429 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 430 for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) { 431 if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm( 432 sigAlgorithm, key.getOriginalSigningKey())) { 433 continue; 434 } 435 try { 436 KeyPair keyPair = key.getKeystoreBackedKeyPair(); 437 438 // Generate a signature 439 Signature signature = Signature.getInstance(sigAlgorithm, provider); 440 signature.initSign(keyPair.getPrivate()); 441 byte[] sigBytes = signature.sign(); 442 443 // Assert that it verifies using our own Provider 444 signature.initVerify(keyPair.getPublic()); 445 assertTrue(signature.verify(sigBytes)); 446 } catch (Throwable e) { 447 throw new RuntimeException( 448 "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e); 449 } 450 } 451 } 452 } 453 454 @Test testValidSignatureGeneratedForEmptyMessageByLimitedUseKey()455 public void testValidSignatureGeneratedForEmptyMessageByLimitedUseKey() 456 throws Exception { 457 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 458 assertNotNull(provider); 459 int maxUsageCount = 2; 460 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 461 for (ImportedKey key : importLimitedUseKatKeyPairsForSigning(getContext(), sigAlgorithm, maxUsageCount)) { 462 if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm( 463 sigAlgorithm, key.getOriginalSigningKey())) { 464 continue; 465 } 466 try { 467 KeyPair keyPair = key.getKeystoreBackedKeyPair(); 468 KeyFactory keyFactory = KeyFactory.getInstance( 469 keyPair.getPrivate().getAlgorithm(), "AndroidKeyStore"); 470 KeyInfo info = keyFactory.getKeySpec(keyPair.getPrivate(), KeyInfo.class); 471 assertEquals(maxUsageCount, info.getRemainingUsageCount()); 472 473 // The first usage of the limited use key. 474 // Generate a signature 475 Signature signature = Signature.getInstance(sigAlgorithm, provider); 476 signature.initSign(keyPair.getPrivate()); 477 byte[] sigBytes = signature.sign(); 478 // Assert that it verifies using our own Provider 479 signature.initVerify(keyPair.getPublic()); 480 assertTrue(signature.verify(sigBytes)); 481 482 // After using the key, the remaining usage count should be decreased. But this 483 // will not be reflected unless we loads the key entry again. 484 info = keyFactory.getKeySpec(keyPair.getPrivate(), KeyInfo.class); 485 assertEquals(maxUsageCount, info.getRemainingUsageCount()); 486 487 // Reloads the key entry again, the remaining usage count is decreased. 488 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 489 keyStore.load(null); 490 KeyStore.PrivateKeyEntry entry = 491 (KeyStore.PrivateKeyEntry) keyStore.getEntry(key.getAlias(), null); 492 info = keyFactory.getKeySpec(entry.getPrivateKey(), KeyInfo.class); 493 assertEquals(maxUsageCount - 1, info.getRemainingUsageCount()); 494 495 // The second usage of the limited use key. 496 signature.initSign(keyPair.getPrivate()); 497 signature.sign(); 498 499 // After the usage of limited use key is exhausted, the key will be deleted. 500 try { 501 signature.initSign(keyPair.getPrivate()); 502 } catch (KeyPermanentlyInvalidatedException expected) {} 503 } catch (Throwable e) { 504 throw new RuntimeException( 505 "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e); 506 } 507 } 508 } 509 } 510 511 @Test testEmptySignatureDoesNotVerify()512 public void testEmptySignatureDoesNotVerify() 513 throws Exception { 514 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 515 assertNotNull(provider); 516 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 517 for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) { 518 if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm( 519 sigAlgorithm, key.getOriginalSigningKey())) { 520 continue; 521 } 522 try { 523 KeyPair keyPair = key.getKeystoreBackedKeyPair(); 524 Signature signature = Signature.getInstance(sigAlgorithm, provider); 525 signature.initVerify(keyPair.getPublic()); 526 assertFalse(signature.verify(EmptyArray.BYTE)); 527 } catch (Throwable e) { 528 throw new RuntimeException( 529 "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e); 530 } 531 } 532 } 533 } 534 535 @Test testSignatureGeneratedByAndroidKeyStoreVerifiesByAndroidKeyStore()536 public void testSignatureGeneratedByAndroidKeyStoreVerifiesByAndroidKeyStore() 537 throws Exception { 538 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 539 assertNotNull(provider); 540 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 541 for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) { 542 if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm( 543 sigAlgorithm, key.getOriginalSigningKey())) { 544 continue; 545 } 546 try { 547 KeyPair keyPair = key.getKeystoreBackedKeyPair(); 548 549 // Generate a signature 550 Signature signature = Signature.getInstance(sigAlgorithm, provider); 551 signature.initSign(keyPair.getPrivate()); 552 byte[] message = "This is a test".getBytes("UTF-8"); 553 signature.update(message); 554 byte[] sigBytes = signature.sign(); 555 556 // Assert that it verifies using our own Provider 557 assertSignatureVerifiesOneShot( 558 sigAlgorithm, provider, keyPair.getPublic(), message, sigBytes); 559 } catch (Throwable e) { 560 throw new RuntimeException( 561 "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e); 562 } 563 } 564 } 565 } 566 567 @Test testSignatureGeneratedByAndroidKeyStoreVerifiesByHighestPriorityProvider()568 public void testSignatureGeneratedByAndroidKeyStoreVerifiesByHighestPriorityProvider() 569 throws Exception { 570 Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME); 571 assertNotNull(keystoreProvider); 572 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 573 for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) { 574 if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm( 575 sigAlgorithm, key.getOriginalSigningKey())) { 576 continue; 577 } 578 Provider verificationProvider = null; 579 try { 580 PrivateKey keystorePrivateKey = key.getKeystoreBackedKeyPair().getPrivate(); 581 582 // Generate a signature 583 Signature signature = Signature.getInstance(sigAlgorithm, keystoreProvider); 584 signature.initSign(keystorePrivateKey); 585 byte[] message = "This is a test".getBytes("UTF-8"); 586 signature.update(message); 587 byte[] sigBytes = signature.sign(); 588 589 // Assert that it verifies using whatever Provider is chosen by JCA by default 590 // for this signature algorithm and public key. 591 PublicKey publicKey = key.getOriginalKeyPair().getPublic(); 592 try { 593 signature = Signature.getInstance(sigAlgorithm); 594 signature.initVerify(publicKey); 595 verificationProvider = signature.getProvider(); 596 } catch (InvalidKeyException e) { 597 // No providers support verifying signatures using this algorithm and key. 598 continue; 599 } 600 assertSignatureVerifiesOneShot( 601 sigAlgorithm, verificationProvider, publicKey, message, sigBytes); 602 } catch (Throwable e) { 603 throw new RuntimeException( 604 "Failed for " + sigAlgorithm + " with key " + key.getAlias() 605 + ", verification provider: " + verificationProvider, 606 e); 607 } 608 } 609 } 610 } 611 612 @Test testSignatureGeneratedByHighestPriorityProviderVerifiesByAndroidKeyStore()613 public void testSignatureGeneratedByHighestPriorityProviderVerifiesByAndroidKeyStore() 614 throws Exception { 615 616 Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME); 617 assertNotNull(keystoreProvider); 618 for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 619 for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) { 620 if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm( 621 sigAlgorithm, key.getOriginalSigningKey())) { 622 continue; 623 } 624 Provider signingProvider = null; 625 try { 626 PrivateKey privateKey = key.getOriginalKeyPair().getPrivate(); 627 628 // Generate a signature 629 Signature signature; 630 try { 631 signature = Signature.getInstance(sigAlgorithm); 632 signature.initSign(privateKey); 633 signingProvider = signature.getProvider(); 634 } catch (InvalidKeyException e) { 635 // No providers support signing using this algorithm and key. 636 continue; 637 } 638 byte[] message = "This is a test".getBytes("UTF-8"); 639 signature.update(message); 640 byte[] sigBytes = signature.sign(); 641 642 // Assert that the signature verifies using the Android Keystore provider. 643 PublicKey keystorePublicKey = key.getKeystoreBackedKeyPair().getPublic(); 644 assertSignatureVerifiesOneShot( 645 sigAlgorithm, keystoreProvider, keystorePublicKey, message, sigBytes); 646 } catch (Throwable e) { 647 throw new RuntimeException( 648 "Failed for " + sigAlgorithm + " with key " + key.getAlias() 649 + ", signing provider: " + signingProvider, 650 e); 651 } 652 } 653 } 654 } 655 656 @Test testSmallMsgKat()657 public void testSmallMsgKat() throws Exception { 658 byte[] message = SHORT_MSG_KAT_MESSAGE; 659 660 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 661 assertNotNull(provider); 662 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 663 try { 664 byte[] goodSigBytes = SHORT_MSG_KAT_SIGNATURES.get(algorithm); 665 assertNotNull(goodSigBytes); 666 KeyPair keyPair = importDefaultKatKeyPair(algorithm).getKeystoreBackedKeyPair(); 667 // Assert that AndroidKeyStore provider can verify the known good signature. 668 assertSignatureVerifiesOneShot( 669 algorithm, provider, keyPair.getPublic(), message, goodSigBytes); 670 assertSignatureVerifiesFedOneByteAtATime( 671 algorithm, provider, keyPair.getPublic(), message, goodSigBytes); 672 assertSignatureVerifiesFedUsingFixedSizeChunks( 673 algorithm, provider, keyPair.getPublic(), message, goodSigBytes, 3); 674 675 byte[] messageWithBitFlip = message.clone(); 676 messageWithBitFlip[messageWithBitFlip.length / 2] ^= 1; 677 assertSignatureDoesNotVerifyOneShot( 678 algorithm, provider, keyPair.getPublic(), messageWithBitFlip, goodSigBytes); 679 680 byte[] goodSigWithBitFlip = goodSigBytes.clone(); 681 goodSigWithBitFlip[goodSigWithBitFlip.length / 2] ^= 1; 682 assertSignatureDoesNotVerifyOneShot( 683 algorithm, provider, keyPair.getPublic(), message, goodSigWithBitFlip); 684 685 // Sign the message in one go 686 Signature signature = Signature.getInstance(algorithm, provider); 687 signature.initSign(keyPair.getPrivate()); 688 signature.update(message); 689 byte[] generatedSigBytes = signature.sign(); 690 boolean deterministicSignatureScheme = 691 algorithm.toLowerCase().endsWith("withrsa"); 692 if (deterministicSignatureScheme) { 693 assertArrayEquals(goodSigBytes, generatedSigBytes); 694 } else { 695 if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) { 696 fail("Generated signature expected to be between " 697 + (goodSigBytes.length - 2) + " and " 698 + (goodSigBytes.length + 2) + " bytes long, but was: " 699 + generatedSigBytes.length + " bytes: " 700 + HexEncoding.encode(generatedSigBytes)); 701 } 702 703 // Assert that the signature verifies using our own Provider 704 assertSignatureVerifiesOneShot( 705 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes); 706 assertSignatureVerifiesFedOneByteAtATime( 707 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes); 708 assertSignatureVerifiesFedUsingFixedSizeChunks( 709 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes, 710 3); 711 712 // Assert that the signature verifies using whatever Provider is chosen by JCA 713 // by default for this signature algorithm and public key. 714 assertSignatureVerifiesOneShot( 715 algorithm, keyPair.getPublic(), message, generatedSigBytes); 716 } 717 718 // Sign the message by feeding it into the Signature one byte at a time 719 signature = Signature.getInstance(signature.getAlgorithm(), provider); 720 signature.initSign(keyPair.getPrivate()); 721 for (int i = 0; i < message.length; i++) { 722 signature.update(message[i]); 723 } 724 generatedSigBytes = signature.sign(); 725 if (deterministicSignatureScheme) { 726 assertArrayEquals(goodSigBytes, generatedSigBytes); 727 } else { 728 if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) { 729 fail("Generated signature expected to be between " 730 + (goodSigBytes.length - 2) + " and " 731 + (goodSigBytes.length + 2) + " bytes long, but was: " 732 + generatedSigBytes.length + " bytes: " 733 + HexEncoding.encode(generatedSigBytes)); 734 } 735 // Assert that the signature verifies using our own Provider 736 assertSignatureVerifiesOneShot( 737 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes); 738 assertSignatureVerifiesFedOneByteAtATime( 739 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes); 740 assertSignatureVerifiesFedUsingFixedSizeChunks( 741 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes, 742 3); 743 744 // Assert that the signature verifies using whatever Provider is chosen by JCA 745 // by default for this signature algorithm and public key. 746 assertSignatureVerifiesOneShot( 747 algorithm, keyPair.getPublic(), message, generatedSigBytes); 748 } 749 } catch (Throwable e) { 750 throw new RuntimeException("Failed for " + algorithm, e); 751 } 752 } 753 } 754 755 @Test testLongMsgKat()756 public void testLongMsgKat() throws Exception { 757 StrictModeDetector strict = new StrictModeDetector(getContext()); 758 byte[] message = TestUtils.generateLargeKatMsg(LONG_MSG_KAT_SEED, LONG_MSG_KAT_SIZE_BYTES); 759 760 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 761 assertNotNull(provider); 762 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 763 try { 764 KeyPair keyPair = importDefaultKatKeyPair(algorithm).getKeystoreBackedKeyPair(); 765 String digest = TestUtils.getSignatureAlgorithmDigest(algorithm); 766 String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(algorithm); 767 if ((KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest)) 768 && (!KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm))) { 769 // This algorithm does not accept large messages 770 Signature signature = Signature.getInstance(algorithm, provider); 771 signature.initSign(keyPair.getPrivate()); 772 try { 773 signature.update(message); 774 byte[] sigBytes = signature.sign(); 775 fail("Unexpectedly generated signature (" + sigBytes.length + "): " 776 + HexEncoding.encode(sigBytes)); 777 } catch (SignatureException expected) {} 778 779 // Bogus signature generated using SHA-256 digest -- shouldn't because the 780 // message is too long (and should not be digested/hashed) and because the 781 // signature uses the wrong digest/hash. 782 byte[] sigBytes = SHORT_MSG_KAT_SIGNATURES.get( 783 "SHA256" + algorithm.substring("NONE".length())); 784 assertNotNull(sigBytes); 785 signature = Signature.getInstance(algorithm, provider); 786 signature.initVerify(keyPair.getPublic()); 787 try { 788 signature.update(message); 789 if (signature.verify(sigBytes)) { 790 fail(); 791 } 792 } catch (SignatureException expected) {} 793 continue; 794 } 795 796 byte[] goodSigBytes = LONG_MSG_KAT_SIGNATURES.get(algorithm); 797 assertNotNull(goodSigBytes); 798 799 // Assert that AndroidKeyStore provider can verify the known good signature. 800 assertSignatureVerifiesOneShot( 801 algorithm, provider, keyPair.getPublic(), message, goodSigBytes); 802 assertSignatureVerifiesFedUsingFixedSizeChunks( 803 algorithm, provider, keyPair.getPublic(), message, goodSigBytes, 718871); 804 805 // Sign the message in one go 806 strict.clear(); 807 Signature signature = Signature.getInstance(algorithm, provider); 808 signature.initSign(keyPair.getPrivate()); 809 signature.update(message); 810 byte[] generatedSigBytes = signature.sign(); 811 strict.check("signature with " + algorithm); 812 String paddingScheme = TestUtils.getSignatureAlgorithmPadding(algorithm); 813 boolean deterministicSignatureScheme = 814 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase(paddingScheme); 815 if (deterministicSignatureScheme) { 816 assertArrayEquals(goodSigBytes, generatedSigBytes); 817 } else { 818 if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) { 819 fail("Generated signature expected to be between " 820 + (goodSigBytes.length - 2) + " and " 821 + (goodSigBytes.length + 2) + " bytes long, but was: " 822 + generatedSigBytes.length + " bytes: " 823 + HexEncoding.encode(generatedSigBytes)); 824 } 825 826 // Assert that the signature verifies using our own Provider 827 assertSignatureVerifiesOneShot( 828 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes); 829 assertSignatureVerifiesFedUsingFixedSizeChunks( 830 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes, 831 718871); 832 833 // Assert that the signature verifies using whatever Provider is chosen by JCA 834 // by default for this signature algorithm and public key. 835 assertSignatureVerifiesOneShot( 836 algorithm, keyPair.getPublic(), message, generatedSigBytes); 837 } 838 839 // Sign the message by feeding it into the Signature one byte at a time 840 generatedSigBytes = generateSignatureFedUsingFixedSizeChunks( 841 algorithm, provider, keyPair.getPrivate(), message, 444307); 842 if (deterministicSignatureScheme) { 843 assertArrayEquals(goodSigBytes, generatedSigBytes); 844 } else { 845 if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) { 846 fail("Generated signature expected to be between " 847 + (goodSigBytes.length - 2) + " and " 848 + (goodSigBytes.length + 2) + " bytes long, but was: " 849 + generatedSigBytes.length + " bytes: " 850 + HexEncoding.encode(generatedSigBytes)); 851 } 852 // Assert that the signature verifies using our own Provider 853 assertSignatureVerifiesOneShot( 854 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes); 855 assertSignatureVerifiesFedUsingFixedSizeChunks( 856 algorithm, provider, keyPair.getPublic(), message, generatedSigBytes, 857 718871); 858 859 // Assert that the signature verifies using whatever Provider is chosen by JCA 860 // by default for this signature algorithm and public key. 861 assertSignatureVerifiesOneShot( 862 algorithm, keyPair.getPublic(), message, generatedSigBytes); 863 } 864 } catch (Throwable e) { 865 throw new RuntimeException("Failed for " + algorithm, e); 866 } 867 } 868 } 869 870 @Test testInitVerifySucceedsDespiteMissingAuthorizations()871 public void testInitVerifySucceedsDespiteMissingAuthorizations() throws Exception { 872 KeyProtection spec = new KeyProtection.Builder(0).build(); 873 874 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 875 try { 876 assertInitVerifySucceeds(algorithm, spec); 877 } catch (Throwable e) { 878 throw new RuntimeException("Failed for " + algorithm, e); 879 } 880 } 881 } 882 883 @Test testInitSignFailsWhenNotAuthorizedToSign()884 public void testInitSignFailsWhenNotAuthorizedToSign() throws Exception { 885 int badPurposes = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT 886 | KeyProperties.PURPOSE_VERIFY; 887 888 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 889 try { 890 KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm); 891 assertInitSignSucceeds(algorithm, good); 892 assertInitSignThrowsInvalidKeyException(algorithm, 893 TestUtils.buildUpon(good, badPurposes).build()); 894 } catch (Throwable e) { 895 throw new RuntimeException("Failed for " + algorithm, e); 896 } 897 } 898 } 899 900 @Test testInitVerifyIgnoresThatNotAuthorizedToVerify()901 public void testInitVerifyIgnoresThatNotAuthorizedToVerify() throws Exception { 902 int badPurposes = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT 903 | KeyProperties.PURPOSE_SIGN; 904 905 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 906 try { 907 KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm); 908 assertInitVerifySucceeds(algorithm, good); 909 assertInitVerifySucceeds(algorithm, 910 TestUtils.buildUpon(good, badPurposes).build()); 911 } catch (Throwable e) { 912 throw new RuntimeException("Failed for " + algorithm, e); 913 } 914 } 915 } 916 917 @Test testInitSignFailsWhenDigestNotAuthorized()918 public void testInitSignFailsWhenDigestNotAuthorized() throws Exception { 919 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 920 try { 921 KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm); 922 assertInitSignSucceeds(algorithm, good); 923 924 String digest = TestUtils.getSignatureAlgorithmDigest(algorithm); 925 String badDigest = 926 (KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest)) 927 ? KeyProperties.DIGEST_SHA384 : KeyProperties.DIGEST_SHA256; 928 assertInitSignThrowsInvalidKeyException(algorithm, 929 TestUtils.buildUpon(good).setDigests(badDigest).build()); 930 931 // Check that digest NONE is not treated as ANY. 932 if (!KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest)) { 933 assertInitSignThrowsInvalidKeyException(algorithm, 934 TestUtils.buildUpon(good) 935 .setDigests(KeyProperties.DIGEST_NONE) 936 .build()); 937 } 938 } catch (Throwable e) { 939 throw new RuntimeException("Failed for " + algorithm, e); 940 } 941 } 942 } 943 944 @Test testInitVerifyIgnoresThatDigestNotAuthorized()945 public void testInitVerifyIgnoresThatDigestNotAuthorized() throws Exception { 946 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 947 try { 948 KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm); 949 assertInitVerifySucceeds(algorithm, good); 950 951 String digest = TestUtils.getSignatureAlgorithmDigest(algorithm); 952 String badDigest = 953 (KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest)) 954 ? KeyProperties.DIGEST_SHA384 : KeyProperties.DIGEST_SHA256; 955 assertInitVerifySucceeds(algorithm, 956 TestUtils.buildUpon(good).setDigests(badDigest).build()); 957 } catch (Throwable e) { 958 throw new RuntimeException("Failed for " + algorithm, e); 959 } 960 } 961 } 962 963 @Test testInitSignFailsWhenPaddingNotAuthorized()964 public void testInitSignFailsWhenPaddingNotAuthorized() throws Exception { 965 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 966 try { 967 String paddingScheme = TestUtils.getSignatureAlgorithmPadding(algorithm); 968 String badPaddingScheme; 969 if (paddingScheme == null) { 970 // No padding scheme used by this algorithm -- ignore. 971 continue; 972 } else if (KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase( 973 paddingScheme)) { 974 badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PSS; 975 } else if (KeyProperties.SIGNATURE_PADDING_RSA_PSS.equalsIgnoreCase( 976 paddingScheme)) { 977 badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PKCS1; 978 } else { 979 throw new IllegalArgumentException("Unsupported algorithm: " + algorithm); 980 } 981 982 KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm); 983 assertInitSignSucceeds(algorithm, good); 984 assertInitSignThrowsInvalidKeyException(algorithm, 985 TestUtils.buildUpon(good).setSignaturePaddings(badPaddingScheme).build()); 986 } catch (Throwable e) { 987 throw new RuntimeException("Failed for " + algorithm, e); 988 } 989 } 990 } 991 992 @Test testInitVerifyIgnoresThatPaddingNotAuthorized()993 public void testInitVerifyIgnoresThatPaddingNotAuthorized() throws Exception { 994 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 995 try { 996 String paddingScheme = TestUtils.getSignatureAlgorithmPadding(algorithm); 997 String badPaddingScheme; 998 if (paddingScheme == null) { 999 // No padding scheme used by this algorithm -- ignore. 1000 continue; 1001 } else if (KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase( 1002 paddingScheme)) { 1003 badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PSS; 1004 } else if (KeyProperties.SIGNATURE_PADDING_RSA_PSS.equalsIgnoreCase( 1005 paddingScheme)) { 1006 badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PKCS1; 1007 } else { 1008 throw new IllegalArgumentException("Unsupported algorithm: " + algorithm); 1009 } 1010 1011 KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm); 1012 assertInitVerifySucceeds(algorithm, good); 1013 assertInitVerifySucceeds(algorithm, 1014 TestUtils.buildUpon(good).setSignaturePaddings(badPaddingScheme).build()); 1015 } catch (Throwable e) { 1016 throw new RuntimeException("Failed for " + algorithm, e); 1017 } 1018 } 1019 } 1020 1021 @Test testInitSignFailsWhenKeyNotYetValid()1022 public void testInitSignFailsWhenKeyNotYetValid() throws Exception { 1023 Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS); 1024 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 1025 try { 1026 KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm); 1027 assertInitSignSucceeds(algorithm, good); 1028 assertInitSignThrowsInvalidKeyException(algorithm, 1029 TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build()); 1030 } catch (Throwable e) { 1031 throw new RuntimeException("Failed for " + algorithm, e); 1032 } 1033 } 1034 } 1035 1036 @Test testInitVerifyIgnoresThatKeyNotYetValid()1037 public void testInitVerifyIgnoresThatKeyNotYetValid() throws Exception { 1038 Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS); 1039 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 1040 try { 1041 KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm); 1042 assertInitVerifySucceeds(algorithm, good); 1043 assertInitVerifySucceeds(algorithm, 1044 TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build()); 1045 } catch (Throwable e) { 1046 throw new RuntimeException("Failed for " + algorithm, e); 1047 } 1048 } 1049 } 1050 1051 @Test testInitSignFailsWhenKeyNoLongerValidForOrigination()1052 public void testInitSignFailsWhenKeyNoLongerValidForOrigination() throws Exception { 1053 Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS); 1054 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 1055 try { 1056 KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm); 1057 assertInitSignSucceeds(algorithm, good); 1058 assertInitSignThrowsInvalidKeyException(algorithm, 1059 TestUtils.buildUpon(good) 1060 .setKeyValidityForOriginationEnd(badEndDate) 1061 .build()); 1062 } catch (Throwable e) { 1063 throw new RuntimeException("Failed for " + algorithm, e); 1064 } 1065 } 1066 } 1067 1068 @Test testInitVerifyIgnoresThatKeyNoLongerValidForOrigination()1069 public void testInitVerifyIgnoresThatKeyNoLongerValidForOrigination() throws Exception { 1070 Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS); 1071 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 1072 try { 1073 KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm); 1074 assertInitVerifySucceeds(algorithm, good); 1075 assertInitVerifySucceeds(algorithm, 1076 TestUtils.buildUpon(good) 1077 .setKeyValidityForOriginationEnd(badEndDate) 1078 .build()); 1079 } catch (Throwable e) { 1080 throw new RuntimeException("Failed for " + algorithm, e); 1081 } 1082 } 1083 } 1084 1085 @Test testInitSignIgnoresThatKeyNoLongerValidForConsumption()1086 public void testInitSignIgnoresThatKeyNoLongerValidForConsumption() throws Exception { 1087 Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS); 1088 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 1089 try { 1090 KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm); 1091 assertInitSignSucceeds(algorithm, good); 1092 assertInitSignSucceeds(algorithm, 1093 TestUtils.buildUpon(good) 1094 .setKeyValidityForConsumptionEnd(badEndDate) 1095 .build()); 1096 } catch (Throwable e) { 1097 throw new RuntimeException("Failed for " + algorithm, e); 1098 } 1099 } 1100 } 1101 1102 @Test testInitVerifyIgnoresThatKeyNoLongerValidForConsumption()1103 public void testInitVerifyIgnoresThatKeyNoLongerValidForConsumption() throws Exception { 1104 Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS); 1105 for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) { 1106 try { 1107 KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm); 1108 assertInitVerifySucceeds(algorithm, good); 1109 assertInitVerifySucceeds(algorithm, 1110 TestUtils.buildUpon(good) 1111 .setKeyValidityForConsumptionEnd(badEndDate) 1112 .build()); 1113 } catch (Throwable e) { 1114 throw new RuntimeException("Failed for " + algorithm, e); 1115 } 1116 } 1117 } 1118 assertInitVerifySucceeds( String signatureAlgorithm, KeyProtection keyProtection)1119 private void assertInitVerifySucceeds( 1120 String signatureAlgorithm, 1121 KeyProtection keyProtection) throws Exception { 1122 int[] resIds = getDefaultKeyAndCertResIds(signatureAlgorithm); 1123 assertInitVerifySucceeds( 1124 signatureAlgorithm, 1125 resIds[0], 1126 resIds[1], 1127 keyProtection); 1128 } 1129 assertInitVerifySucceeds( String signatureAlgorithm, int privateKeyResId, int certResId, KeyProtection keyProtection)1130 private void assertInitVerifySucceeds( 1131 String signatureAlgorithm, 1132 int privateKeyResId, 1133 int certResId, 1134 KeyProtection keyProtection) throws Exception { 1135 PublicKey publicKey = TestUtils.importIntoAndroidKeyStore( 1136 "test1", getContext(), privateKeyResId, certResId, keyProtection) 1137 .getKeystoreBackedKeyPair() 1138 .getPublic(); 1139 Signature signature = Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME); 1140 signature.initVerify(publicKey); 1141 } 1142 assertInitSignSucceeds( String signatureAlgorithm, KeyProtection keyProtection)1143 private void assertInitSignSucceeds( 1144 String signatureAlgorithm, 1145 KeyProtection keyProtection) throws Exception { 1146 int[] resIds = getDefaultKeyAndCertResIds(signatureAlgorithm); 1147 assertInitSignSucceeds( 1148 signatureAlgorithm, 1149 resIds[0], 1150 resIds[1], 1151 keyProtection); 1152 } 1153 assertInitSignSucceeds( String signatureAlgorithm, int privateKeyResId, int certResId, KeyProtection keyProtection)1154 private void assertInitSignSucceeds( 1155 String signatureAlgorithm, 1156 int privateKeyResId, 1157 int certResId, 1158 KeyProtection keyProtection) throws Exception { 1159 PrivateKey privateKey = TestUtils.importIntoAndroidKeyStore( 1160 "test1", getContext(), privateKeyResId, certResId, keyProtection) 1161 .getKeystoreBackedKeyPair() 1162 .getPrivate(); 1163 Signature signature = Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME); 1164 signature.initSign(privateKey); 1165 } 1166 assertInitSignThrowsInvalidKeyException( String signatureAlgorithm, KeyProtection keyProtection)1167 private void assertInitSignThrowsInvalidKeyException( 1168 String signatureAlgorithm, 1169 KeyProtection keyProtection) throws Exception { 1170 assertInitSignThrowsInvalidKeyException(null, signatureAlgorithm, keyProtection); 1171 } 1172 assertInitSignThrowsInvalidKeyException( String message, String signatureAlgorithm, KeyProtection keyProtection)1173 private void assertInitSignThrowsInvalidKeyException( 1174 String message, 1175 String signatureAlgorithm, 1176 KeyProtection keyProtection) throws Exception { 1177 int[] resIds = getDefaultKeyAndCertResIds(signatureAlgorithm); 1178 assertInitSignThrowsInvalidKeyException( 1179 message, 1180 signatureAlgorithm, 1181 resIds[0], 1182 resIds[1], 1183 keyProtection); 1184 } 1185 assertInitSignThrowsInvalidKeyException( String message, String signatureAlgorithm, int privateKeyResId, int certResId, KeyProtection keyProtection)1186 private void assertInitSignThrowsInvalidKeyException( 1187 String message, 1188 String signatureAlgorithm, 1189 int privateKeyResId, 1190 int certResId, 1191 KeyProtection keyProtection) throws Exception { 1192 PrivateKey privateKey = TestUtils.importIntoAndroidKeyStore( 1193 "test1", getContext(), privateKeyResId, certResId, keyProtection) 1194 .getKeystoreBackedKeyPair() 1195 .getPrivate(); 1196 Signature signature = Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME); 1197 try { 1198 signature.initSign(privateKey); 1199 fail(message); 1200 } catch (InvalidKeyException expected) {} 1201 } 1202 getDefaultKeyAndCertResIds(String signatureAlgorithm)1203 static int[] getDefaultKeyAndCertResIds(String signatureAlgorithm) { 1204 String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm); 1205 if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { 1206 return new int[] {R.raw.ec_key1_pkcs8, R.raw.ec_key1_cert}; 1207 } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { 1208 return new int[] {R.raw.rsa_key1_pkcs8, R.raw.rsa_key1_cert}; 1209 } else { 1210 throw new IllegalArgumentException("Unknown key algorithm: " + keyAlgorithm); 1211 } 1212 } 1213 importDefaultKatKeyPair(String signatureAlgorithm)1214 private ImportedKey importDefaultKatKeyPair(String signatureAlgorithm) throws Exception { 1215 String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm); 1216 KeyProtection importParams = 1217 TestUtils.getMinimalWorkingImportParametersForSigningingWith(signatureAlgorithm); 1218 if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { 1219 return TestUtils.importIntoAndroidKeyStore( 1220 "testEc", 1221 getContext(), 1222 R.raw.ec_key1_pkcs8, 1223 R.raw.ec_key1_cert, 1224 importParams); 1225 } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { 1226 return TestUtils.importIntoAndroidKeyStore( 1227 "testRsa", 1228 getContext(), 1229 R.raw.rsa_key1_pkcs8, 1230 R.raw.rsa_key1_cert, 1231 importParams); 1232 } else { 1233 throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm); 1234 } 1235 } 1236 assertSignatureVerifiesOneShot( String algorithm, PublicKey publicKey, byte[] message, byte[] signature)1237 private void assertSignatureVerifiesOneShot( 1238 String algorithm, 1239 PublicKey publicKey, 1240 byte[] message, 1241 byte[] signature) throws Exception { 1242 assertSignatureVerifiesOneShot(algorithm, null, publicKey, message, signature); 1243 } 1244 assertSignatureVerifiesOneShot( String algorithm, Provider provider, PublicKey publicKey, byte[] message, byte[] signature)1245 private void assertSignatureVerifiesOneShot( 1246 String algorithm, 1247 Provider provider, 1248 PublicKey publicKey, 1249 byte[] message, 1250 byte[] signature) throws Exception { 1251 Signature sig = (provider != null) 1252 ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm); 1253 sig.initVerify(publicKey); 1254 sig.update(message); 1255 if (!sig.verify(signature)) { 1256 fail("Signature did not verify. algorithm: " + algorithm 1257 + ", provider: " + sig.getProvider().getName() 1258 + ", signature (" + signature.length + " bytes): " 1259 + HexEncoding.encode(signature)); 1260 } 1261 } 1262 assertSignatureDoesNotVerifyOneShot( String algorithm, Provider provider, PublicKey publicKey, byte[] message, byte[] signature)1263 private void assertSignatureDoesNotVerifyOneShot( 1264 String algorithm, 1265 Provider provider, 1266 PublicKey publicKey, 1267 byte[] message, 1268 byte[] signature) throws Exception { 1269 Signature sig = (provider != null) 1270 ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm); 1271 sig.initVerify(publicKey); 1272 sig.update(message); 1273 if (sig.verify(signature)) { 1274 fail("Signature verified unexpectedly. algorithm: " + algorithm 1275 + ", provider: " + sig.getProvider().getName() 1276 + ", signature (" + signature.length + " bytes): " 1277 + HexEncoding.encode(signature)); 1278 } 1279 } 1280 assertSignatureVerifiesFedOneByteAtATime( String algorithm, Provider provider, PublicKey publicKey, byte[] message, byte[] signature)1281 private void assertSignatureVerifiesFedOneByteAtATime( 1282 String algorithm, 1283 Provider provider, 1284 PublicKey publicKey, 1285 byte[] message, 1286 byte[] signature) throws Exception { 1287 Signature sig = (provider != null) 1288 ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm); 1289 sig.initVerify(publicKey); 1290 for (int i = 0; i < message.length; i++) { 1291 sig.update(message[i]); 1292 } 1293 if (!sig.verify(signature)) { 1294 fail("Signature did not verify. algorithm: " + algorithm 1295 + ", provider: " + sig.getProvider().getName() 1296 + ", signature (" + signature.length + " bytes): " 1297 + HexEncoding.encode(signature)); 1298 } 1299 } 1300 generateSignatureFedUsingFixedSizeChunks( String algorithm, Provider expectedProvider, PrivateKey privateKey, byte[] message, int chunkSizeBytes)1301 private byte[] generateSignatureFedUsingFixedSizeChunks( 1302 String algorithm, 1303 Provider expectedProvider, 1304 PrivateKey privateKey, 1305 byte[] message, 1306 int chunkSizeBytes) throws Exception { 1307 Signature signature = Signature.getInstance(algorithm); 1308 signature.initSign(privateKey); 1309 assertSame(expectedProvider, signature.getProvider()); 1310 int messageRemaining = message.length; 1311 int messageOffset = 0; 1312 while (messageRemaining > 0) { 1313 int actualChunkSizeBytes = Math.min(chunkSizeBytes, messageRemaining); 1314 signature.update(message, messageOffset, actualChunkSizeBytes); 1315 messageOffset += actualChunkSizeBytes; 1316 messageRemaining -= actualChunkSizeBytes; 1317 } 1318 return signature.sign(); 1319 } 1320 assertSignatureVerifiesFedUsingFixedSizeChunks( String algorithm, Provider provider, PublicKey publicKey, byte[] message, byte[] signature, int chunkSizeBytes)1321 private void assertSignatureVerifiesFedUsingFixedSizeChunks( 1322 String algorithm, 1323 Provider provider, 1324 PublicKey publicKey, 1325 byte[] message, 1326 byte[] signature, 1327 int chunkSizeBytes) throws Exception { 1328 Signature sig = (provider != null) 1329 ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm); 1330 sig.initVerify(publicKey); 1331 int messageRemaining = message.length; 1332 int messageOffset = 0; 1333 while (messageRemaining > 0) { 1334 int actualChunkSizeBytes = Math.min(chunkSizeBytes, messageRemaining); 1335 sig.update(message, messageOffset, actualChunkSizeBytes); 1336 messageOffset += actualChunkSizeBytes; 1337 messageRemaining -= actualChunkSizeBytes; 1338 } 1339 if (!sig.verify(signature)) { 1340 fail("Signature did not verify. algorithm: " + algorithm 1341 + ", provider: " + sig.getProvider().getName() 1342 + ", signature (" + signature.length + " bytes): " 1343 + HexEncoding.encode(signature)); 1344 } 1345 } 1346 getMinimalWorkingImportParamsForSigning(String algorithm)1347 private static KeyProtection getMinimalWorkingImportParamsForSigning(String algorithm) { 1348 return TestUtils.getMinimalWorkingImportParametersForSigningingWith(algorithm); 1349 } 1350 getMinimalWorkingImportParamsForVerifying( @uppressWarnings"unused") String algorithm)1351 private static KeyProtection getMinimalWorkingImportParamsForVerifying( 1352 @SuppressWarnings("unused") String algorithm) { 1353 // No need to authorize anything because verification does not use the private key. 1354 // Operations using public keys do not need authorization. 1355 return new KeyProtection.Builder(0).build(); 1356 } 1357 importKatKeyPairsForSigning( Context context, String signatureAlgorithm)1358 static Collection<ImportedKey> importKatKeyPairsForSigning( 1359 Context context, String signatureAlgorithm) throws Exception { 1360 String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm); 1361 KeyProtection importParams = 1362 TestUtils.getMinimalWorkingImportParametersForSigningingWith(signatureAlgorithm); 1363 if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { 1364 return ECDSASignatureTest.importKatKeyPairs(context, importParams); 1365 } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { 1366 return RSASignatureTest.importKatKeyPairs(context, importParams); 1367 } else { 1368 throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm); 1369 } 1370 } 1371 importLimitedUseKatKeyPairsForSigning( Context context, String signatureAlgorithm, int maxUsageCount)1372 static Collection<ImportedKey> importLimitedUseKatKeyPairsForSigning( 1373 Context context, String signatureAlgorithm, int maxUsageCount) throws Exception { 1374 String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm); 1375 KeyProtection importParams = 1376 TestUtils.getMinimalWorkingImportParametersWithLimitedUsageForSigningingWith( 1377 signatureAlgorithm, maxUsageCount); 1378 if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { 1379 return ECDSASignatureTest.importKatKeyPairs(context, importParams); 1380 } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { 1381 return RSASignatureTest.importKatKeyPairs(context, importParams); 1382 } else { 1383 throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm); 1384 } 1385 } 1386 } 1387