diff options
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; + } } |