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