TrustedRootCertificates.java revision 57ca3da24f26164104aecbcebf345cfcfac17a66
1/* 2 * Copyright (C) 2018 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 17package android.security.keystore.recovery; 18 19import static android.security.keystore.recovery.X509CertificateParsingUtils.decodeBase64Cert; 20 21import android.annotation.NonNull; 22import android.util.ArrayMap; 23 24import java.security.cert.CertificateException; 25import java.security.cert.X509Certificate; 26import java.util.Map; 27 28/** 29 * Trusted root certificates for use by the 30 * {@link android.security.keystore.recovery.RecoveryController}. These certificates are used to 31 * verify the public keys of remote secure hardware modules. This is to prevent AOSP backing up keys 32 * to untrusted devices. 33 * 34 * @hide 35 */ 36public final class TrustedRootCertificates { 37 38 public static final String GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_ALIAS = 39 "GoogleCloudKeyVaultServiceV1"; 40 /** 41 * Certificate used for client-side end-to-end encryption tests. 42 * When recovery controller is initialized with the certificate, recovery snapshots will only 43 * contain application keys started with {@link INSECURE_KEY_ALIAS}. 44 * Recovery snapshot will only be created if device is unlocked with password started with 45 * {@link #INSECURE_PASSWORD_PREFIX}. 46 * 47 * @hide 48 */ 49 public static final String TEST_ONLY_INSECURE_CERTIFICATE_ALIAS = 50 "TEST_ONLY_INSECURE_CERTIFICATE_ALIAS"; 51 52 /** 53 * TODO: Add insecure certificate to TestApi. 54 * @hide 55 */ 56 public static @NonNull X509Certificate getTestOnlyInsecureCertificate() { 57 return parseBase64Certificate(TEST_ONLY_INSECURE_CERTIFICATE_BASE64); 58 } 59 /** 60 * Keys, which alias starts with the prefix are not protected if 61 * recovery agent uses {@link #TEST_ONLY_INSECURE_CERTIFICATE_ALIAS} root certificate. 62 * @hide 63 */ 64 public static final String INSECURE_KEY_ALIAS_PREFIX = 65 "INSECURE_KEY_ALIAS_KEY_MATERIAL_IS_NOT_PROTECTED_"; 66 /** 67 * Prefix for insecure passwords with length 14. 68 * Passwords started with the prefix are not protected if recovery agent uses 69 * {@link #TEST_ONLY_INSECURE_CERTIFICATE_ALIAS} root certificate. 70 * @hide 71 */ 72 public static final String INSECURE_PASSWORD_PREFIX = 73 "INSECURE_PSWD_"; 74 75 private static final String GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_BASE64 = "" 76 + "MIIFJjCCAw6gAwIBAgIJAIobXsJlzhNdMA0GCSqGSIb3DQEBDQUAMCAxHjAcBgNV" 77 + "BAMMFUdvb2dsZSBDcnlwdEF1dGhWYXVsdDAeFw0xODAyMDIxOTM5MTRaFw0zODAx" 78 + "MjgxOTM5MTRaMCAxHjAcBgNVBAMMFUdvb2dsZSBDcnlwdEF1dGhWYXVsdDCCAiIw" 79 + "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2OT5i40/H7LINg/lq/0G0hR65P" 80 + "Q4Mud3OnuVt6UIYV2T18+v6qW1yJd5FcnND/ZKPau4aUAYklqJuSVjOXQD0BjgS2" 81 + "98Xa4dSn8Ci1rUR+5tdmrxqbYUdT2ZvJIUMMR6fRoqi+LlAbKECrV+zYQTyLU68w" 82 + "V66hQpAButjJKiZzkXjmKLfJ5IWrNEn17XM988rk6qAQn/BYCCQGf3rQuJeksGmA" 83 + "N1lJOwNYxmWUyouVwqwZthNEWqTuEyBFMkAT+99PXW7oVDc7oU5cevuihxQWNTYq" 84 + "viGB8cck6RW3cmqrDSaJF/E+N0cXFKyYC7FDcggt6k3UrxNKTuySdDEa8+2RTQqU" 85 + "Y9npxBlQE+x9Ig56OI1BG3bSBsGdPgjpyHadZeh2tgk+oqlGsSsum24YxaxuSysT" 86 + "Qfcu/XhyfUXavfmGrBOXerTzIl5oBh/F5aHTV85M2tYEG0qsPPvSpZAWtdJ/2rca" 87 + "OxvhwOL+leZKr8McjXVR00lBsRuKXX4nTUMwya09CO3QHFPFZtZvqjy2HaMOnVLQ" 88 + "I6b6dHEfmsHybzVOe3yPEoFQSU9UhUdmi71kwwoanPD3j9fJHmXTx4PzYYBRf1ZE" 89 + "o+uPgMPk7CDKQFZLjnR40z1uzu3O8aZ3AKZzP+j7T4XQKJLQLmllKtPgLgNdJyib" 90 + "2Glg7QhXH/jBTL6hAgMBAAGjYzBhMB0GA1UdDgQWBBSbZfrqOYH54EJpkdKMZjMc" 91 + "z/Hp+DAfBgNVHSMEGDAWgBSbZfrqOYH54EJpkdKMZjMcz/Hp+DAPBgNVHRMBAf8E" 92 + "BTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQ0FAAOCAgEAKh9nm/vW" 93 + "glMWp3vcCwWwJW286ecREDlI+CjGh5h+f2N4QRrXd/tKE3qQJWCqGx8sFfIUjmI7" 94 + "KYdsC2gyQ2cA2zl0w7pB2QkuqE6zVbnh1D17Hwl19IMyAakFaM9ad4/EoH7oQmqX" 95 + "nF/f5QXGZw4kf1HcgKgoCHWXjqR8MqHOcXR8n6WFqxjzJf1jxzi6Yo2dZ7PJbnE6" 96 + "+kHIJuiCpiHL75v5g1HM41gT3ddFFSrn88ThNPWItT5Z8WpFjryVzank2Yt02LLl" 97 + "WqZg9IC375QULc5B58NMnaiVJIDJQ8zoNgj1yaxqtUMnJX570lotO2OXe4ec9aCQ" 98 + "DIJ84YLM/qStFdeZ9416E80dchskbDG04GuVJKlzWjxAQNMRFhyaPUSBTLLg+kwP" 99 + "t9+AMmc+A7xjtFQLZ9fBYHOBsndJOmeSQeYeckl+z/1WQf7DdwXn/yijon7mxz4z" 100 + "cCczfKwTJTwBh3wR5SQr2vQm7qaXM87qxF8PCAZrdZaw5I80QwkgTj0WTZ2/GdSw" 101 + "d3o5SyzzBAjpwtG+4bO/BD9h9wlTsHpT6yWOZs4OYAKU5ykQrncI8OyavMggArh3" 102 + "/oM58v0orUWINtIc2hBlka36PhATYQiLf+AiWKnwhCaaHExoYKfQlMtXBodNvOK8" 103 + "xqx69x05q/qbHKEcTHrsss630vxrp1niXvA="; 104 105 private static final String TEST_ONLY_INSECURE_CERTIFICATE_BASE64 = "" 106 + "MIIFMDCCAxigAwIBAgIJAIZ9/G8KQie9MA0GCSqGSIb3DQEBDQUAMCUxIzAhBgNV" 107 + "BAMMGlRlc3QgT25seSBVbnNlY3VyZSBSb290IENBMB4XDTE4MDMyODAwMzIyM1oX" 108 + "DTM4MDMyMzAwMzIyM1owJTEjMCEGA1UEAwwaVGVzdCBPbmx5IFVuc2VjdXJlIFJv" 109 + "b3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGxFNzAEyzSPmw" 110 + "E5gfuBXdXq++bl9Ep62V7Xn1UiejvmS+pRHT39pf/M7sl4Zr9ezanJTrFvf9+B85" 111 + "VGehdsD32TgfEjThcqaoQCI6pKkHYsUo7FZ5n+G3eE8oabWRZJMVo3QDjnnFYp7z" 112 + "20vnpjDofI2oQyxHcb/1yep+ca1+4lIvbUp/ybhNFqhRXAMcDXo7pyH38eUQ1JdK" 113 + "Q/QlBbShpFEqx1Y6KilKfTDf7Wenqr67LkaEim//yLZjlHzn/BpuRTrpo+XmJZx1" 114 + "P9CX9LGOXTtmsaCcYgD4yijOvV8aEsIJaf1kCIO558oH0oQc+0JG5aXeLN7BDlyZ" 115 + "vH0RdSx5nQLS9kj2I6nthOw/q00/L+S6A0m5jyNZOAl1SY78p+wO0d9eHbqQzJwf" 116 + "EsSq3qGAqlgQyyjp6oxHBqT9hZtN4rxw+iq0K1S4kmTLNF1FvmIB1BE+lNvvoGdY" 117 + "5G0b6Pe4R5JFn9LV3C3PEmSYnae7iG0IQlKmRADIuvfJ7apWAVanJPJAAWh2Akfp" 118 + "8Uxr02cHoY6o7vsEhJJOeMkipaBHThESm/XeFVubQzNfZ9gjQnB9ZX2v+lyj+WYZ" 119 + "SAz3RuXx6TlLrmWccMpQDR1ibcgyyjLUtX3kwZl2OxmJXitjuD7xlxvAXYob15N+" 120 + "K4xKHgxUDrbt2zU/tY0vgepAUg/xbwIDAQABo2MwYTAdBgNVHQ4EFgQUwyeNpYgs" 121 + "XXYvh9z0/lFrja7sV+swHwYDVR0jBBgwFoAUwyeNpYgsXXYvh9z0/lFrja7sV+sw" 122 + "DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQENBQAD" 123 + "ggIBAGuOsvMN5SD3RIQnMJtBpcHNrxun+QFjPZFlYCLfIPrUkHpn5O1iIIq8tVLd" 124 + "2V+12VKnToUEANsYBD3MP8XjP+6GZ7ZQ2rwLGvUABKSX4YXvmjEEXZUZp0y3tIV4" 125 + "kUDlbACzguPneZDp5Qo7YWH4orgqzHkn0sD/ikO5XrAqmzc245ewJlrf+V11mjcu" 126 + "ELfDrEejpPhi7Hk/ZNR0ftP737Hs/dNoCLCIaVNgYzBZhgo4kd220TeJu2ttW0XZ" 127 + "ldyShtpcOmyWKBgVseixR6L/3sspPHyAPXkSuRo0Eh1xvzDKCg9ttb0qoacTlXMF" 128 + "GkBpNzmVq67NWFGGa9UElift1mv6RfktPCAGZ+Ai8xUiKAUB0Eookpt/8gX9Senq" 129 + "yP/jMxkxXmHWxUu8+KnLvj6WLrfftuuD7u3cfc7j5kkrheDz3O4h4477GnqL5wdo" 130 + "9DuEsNc4FxJVz8Iy8RS6cJuW4pihYpM1Tyn7uopLnImpYzEY+R5aQqqr+q/A1diq" 131 + "ogbEKPH6oUiqJUwq3nD70gPBUKJmIzS4vLwLouqUHEm1k/MgHV/BkEU0uVHszPFa" 132 + "XUMMCHb0iT9P8LuZ7Ajer3SR/0TRVApCrk/6OV68e+6k/OFpM5kcZnNMD5ANyBri" 133 + "Tsz3NrDwSw4i4+Dsfh6A9dB/cEghw4skLaBxnQLQIgVeqCzK"; 134 135 /** 136 * The X509 certificate of the trusted root CA cert for the recoverable key store service. 137 * 138 * TODO: Change it to the production certificate root CA before the final launch. 139 */ 140 private static final X509Certificate GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_CERTIFICATE = 141 parseBase64Certificate(GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_BASE64); 142 143 private static final int NUMBER_OF_ROOT_CERTIFICATES = 1; 144 145 private static final ArrayMap<String, X509Certificate> ALL_ROOT_CERTIFICATES = 146 constructRootCertificateMap(); 147 148 /** 149 * Returns all available root certificates, keyed by alias. 150 */ 151 public static @NonNull Map<String, X509Certificate> getRootCertificates() { 152 return new ArrayMap(ALL_ROOT_CERTIFICATES); 153 } 154 155 /** 156 * Gets a root certificate referenced by the given {@code alias}. 157 * 158 * @param alias the alias of the certificate 159 * @return the certificate referenced by the alias, or null if such a certificate doesn't exist. 160 */ 161 public static @NonNull X509Certificate getRootCertificate(String alias) { 162 return ALL_ROOT_CERTIFICATES.get(alias); 163 } 164 165 private static ArrayMap<String, X509Certificate> constructRootCertificateMap() { 166 ArrayMap<String, X509Certificate> certificates = 167 new ArrayMap<>(NUMBER_OF_ROOT_CERTIFICATES); 168 certificates.put( 169 GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_ALIAS, 170 GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_CERTIFICATE); 171 return certificates; 172 } 173 174 private static X509Certificate parseBase64Certificate(String base64Certificate) { 175 try { 176 return decodeBase64Cert(base64Certificate); 177 } catch (CertificateException e) { 178 // Should not happen 179 throw new RuntimeException(e); 180 } 181 } 182 183 // Statics only 184 private TrustedRootCertificates() {} 185} 186