From 7c475cc7c3f1159d5a8115382deb5332aca76144 Mon Sep 17 00:00:00 2001 From: Alex Klyubin Date: Fri, 12 Jun 2015 12:16:45 -0700 Subject: Fix Android Keystore KeyPairGenerator for RSA PSS keys. This fixes a bug where key pair generation fails for RSA signing keys which are not authorized for PKCS#1 signature padding, such as keys authorized only for the RSA PSS signature padding scheme. The issue was that the KeyPairGenerator was failing when attempting to sign the self-signed certificate (needed by Android Keystore) using PKCS#1 padding for which such keys are not authorized. The solution is to not attempt to sign these certificates and instead use a fake signature. Bug: 21809600 Change-Id: I4f04fcf78174937046d2534e0485c6940eae673f --- .../AndroidKeyStoreKeyPairGeneratorSpi.java | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'keystore/java') diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index 35af34fbf6b6..a6db228de485 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -703,6 +703,36 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } case KeymasterDefs.KM_ALGORITHM_RSA: { + // Check whether this key is authorized for PKCS#1 signature padding. + // We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle + // only supports RSA certificates signed using PKCS#1 padding scheme. The key needs + // to be authorized for PKCS#1 padding or padding NONE which means any padding. + boolean pkcs1SignaturePaddingSupported = false; + for (int keymasterPadding : KeyProperties.SignaturePadding.allToKeymaster( + spec.getSignaturePaddings())) { + if ((keymasterPadding == KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN) + || (keymasterPadding == KeymasterDefs.KM_PAD_NONE)) { + pkcs1SignaturePaddingSupported = true; + break; + } + } + if (!pkcs1SignaturePaddingSupported) { + // Keymaster doesn't distinguish between encryption padding NONE and signature + // padding NONE. In the Android Keystore API only encryption padding NONE is + // exposed. + for (int keymasterPadding : KeyProperties.EncryptionPadding.allToKeymaster( + spec.getEncryptionPaddings())) { + if (keymasterPadding == KeymasterDefs.KM_PAD_NONE) { + pkcs1SignaturePaddingSupported = true; + break; + } + } + } + if (!pkcs1SignaturePaddingSupported) { + // Key not authorized for PKCS#1 signature padding -- can't sign + return null; + } + Set availableKeymasterDigests = getAvailableKeymasterSignatureDigests( spec.getDigests(), AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests()); -- cgit v1.2.3-59-g8ed1b