diff options
author | Hai Shalom <haishalom@google.com> | 2020-07-22 17:13:55 -0700 |
---|---|---|
committer | Hai Shalom <haishalom@google.com> | 2020-07-28 21:59:12 +0000 |
commit | c47516c563f23da2a1c0785b3959b33f77340d31 (patch) | |
tree | 84c886c4c88007dfd0feee60b013bf08fc16da08 /service | |
parent | 9b3fb0d1c18c2559c1ad5a7be9de3ad5ce3c12c9 (diff) |
[WPA3-Enterprise] Improve the security and robustness of profiles
Updated the logic with more robust checks that enforce checks on
all CA certificates in the list and on the user certificate as well.
Bug: 161939357
Test: atest WifiKeyStoreTest
Test: Connect to WPA3-Enterprise 192-bit ECDSA and RSA networks
Test: Connect to WPA2-Enterprise network
Change-Id: I8e6becb66f245ee36a9b4e62569784f567412a33
Merged-In: I8e6becb66f245ee36a9b4e62569784f567412a33
(cherry picked from commit 555ee293678a085f6240156eb1728709dd7bd73e)
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/WifiKeyStore.java | 129 |
1 files changed, 94 insertions, 35 deletions
diff --git a/service/java/com/android/server/wifi/WifiKeyStore.java b/service/java/com/android/server/wifi/WifiKeyStore.java index 70daa0d55..c248d2269 100644 --- a/service/java/com/android/server/wifi/WifiKeyStore.java +++ b/service/java/com/android/server/wifi/WifiKeyStore.java @@ -30,6 +30,7 @@ import com.android.server.wifi.util.ArrayUtils; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.Principal; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; @@ -276,52 +277,110 @@ public class WifiKeyStore { // For WPA3-Enterprise 192-bit networks, set the SuiteBCipher field based on the // CA certificate type. Suite-B requires SHA384, reject other certs. if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)) { - // Read the first CA certificate, and initialize - Certificate caCert = null; + // Read the CA certificates, and initialize + String[] caAliases = config.enterpriseConfig.getCaCertificateAliases(); + + if (caAliases == null || caAliases.length == 0) { + Log.e(TAG, "No CA aliases in profile"); + return false; + } + + int caCertType = -1; + int prevCaCertType = -1; + for (String caAlias : caAliases) { + Certificate caCert = null; + try { + caCert = mKeyStore.getCertificate(caAlias); + } catch (KeyStoreException e) { + Log.e(TAG, "Failed to get Suite-B certificate", e); + } + if (caCert == null || !(caCert instanceof X509Certificate)) { + Log.e(TAG, "Failed reading CA certificate for Suite-B"); + return false; + } + + // Confirm that the CA certificate is compatible with Suite-B requirements + caCertType = getSuiteBCipherFromCert((X509Certificate) caCert); + if (caCertType < 0) { + return false; + } + if (prevCaCertType != -1) { + if (prevCaCertType != caCertType) { + Log.e(TAG, "Incompatible CA certificates"); + return false; + } + } + prevCaCertType = caCertType; + } + + Certificate clientCert = null; try { - caCert = mKeyStore.getCertificate(config.enterpriseConfig.getCaCertificateAlias()); + clientCert = mKeyStore.getCertificate(config.enterpriseConfig + .getClientCertificateAlias()); } catch (KeyStoreException e) { - Log.e(TAG, "Failed to get Suite-B certificate", e); + Log.e(TAG, "Failed to get Suite-B client certificate", e); } - if (caCert == null || !(caCert instanceof X509Certificate)) { - Log.e(TAG, "Failed reading CA certificate for Suite-B"); + if (clientCert == null || !(clientCert instanceof X509Certificate)) { + Log.e(TAG, "Failed reading client certificate for Suite-B"); return false; } - X509Certificate x509CaCert = (X509Certificate) caCert; - String sigAlgOid = x509CaCert.getSigAlgOID(); - if (mVerboseLoggingEnabled) { - Log.d(TAG, "Signature algorithm: " + sigAlgOid); + + int clientCertType = getSuiteBCipherFromCert((X509Certificate) clientCert); + if (clientCertType < 0) { + return false; } - config.allowedSuiteBCiphers.clear(); - // Wi-Fi alliance requires the use of both ECDSA secp384r1 and RSA 3072 certificates - // in WPA3-Enterprise 192-bit security networks, which are also known as Suite-B-192 - // networks, even though NSA Suite-B-192 mandates ECDSA only. The use of the term - // Suite-B was already coined in the IEEE 802.11-2016 specification for - // AKM 00-0F-AC but the test plan for WPA3-Enterprise 192-bit for APs mandates - // support for both RSA and ECDSA, and for STAs it mandates ECDSA and optionally - // RSA. In order to be compatible with all WPA3-Enterprise 192-bit deployments, - // we are supporting both types here. - if (sigAlgOid.equals("1.2.840.113549.1.1.12")) { - // sha384WithRSAEncryption - config.allowedSuiteBCiphers.set( - WifiConfiguration.SuiteBCipher.ECDHE_RSA); - if (mVerboseLoggingEnabled) { - Log.d(TAG, "Selecting Suite-B RSA"); - } - } else if (sigAlgOid.equals("1.2.840.10045.4.3.3")) { - // ecdsa-with-SHA384 - config.allowedSuiteBCiphers.set( - WifiConfiguration.SuiteBCipher.ECDHE_ECDSA); - if (mVerboseLoggingEnabled) { - Log.d(TAG, "Selecting Suite-B ECDSA"); - } + if (clientCertType == caCertType) { + config.allowedSuiteBCiphers.clear(); + config.allowedSuiteBCiphers.set(clientCertType); } else { - Log.e(TAG, "Invalid CA certificate type for Suite-B: " - + sigAlgOid); + Log.e(TAG, "Client certificate for Suite-B is incompatible with the CA " + + "certificate"); return false; } } return true; } + + /** + * Get the Suite-B cipher from the certificate + * + * @param x509Certificate Certificate to process + * @return WifiConfiguration.SuiteBCipher.ECDHE_RSA if the certificate OID matches the Suite-B + * requirements for RSA certificates, WifiConfiguration.SuiteBCipher.ECDHE_ECDSA if the + * certificate OID matches the Suite-B requirements for ECDSA certificates, or -1 otherwise. + */ + private int getSuiteBCipherFromCert(X509Certificate x509Certificate) { + String sigAlgOid = x509Certificate.getSigAlgOID(); + if (mVerboseLoggingEnabled) { + Principal p = x509Certificate.getSubjectX500Principal(); + if (p != null && !TextUtils.isEmpty(p.getName())) { + Log.d(TAG, "Checking cert " + p.getName()); + } + } + + // Wi-Fi alliance requires the use of both ECDSA secp384r1 and RSA 3072 certificates + // in WPA3-Enterprise 192-bit security networks, which are also known as Suite-B-192 + // networks, even though NSA Suite-B-192 mandates ECDSA only. The use of the term + // Suite-B was already coined in the IEEE 802.11-2016 specification for + // AKM 00-0F-AC but the test plan for WPA3-Enterprise 192-bit for APs mandates + // support for both RSA and ECDSA, and for STAs it mandates ECDSA and optionally + // RSA. In order to be compatible with all WPA3-Enterprise 192-bit deployments, + // we are supporting both types here. + if (sigAlgOid.equals("1.2.840.113549.1.1.12")) { + // sha384WithRSAEncryption + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Found Suite-B RSA certificate"); + } + return WifiConfiguration.SuiteBCipher.ECDHE_RSA; + } else if (sigAlgOid.equals("1.2.840.10045.4.3.3")) { + // ecdsa-with-SHA384 + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Found Suite-B ECDSA certificate"); + } + return WifiConfiguration.SuiteBCipher.ECDHE_ECDSA; + } + Log.e(TAG, "Invalid certificate type for Suite-B: " + sigAlgOid); + return -1; + } } |