Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c475cc7 authored by Alex Klyubin's avatar Alex Klyubin
Browse files

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
parent 738241f9
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -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<Integer> availableKeymasterDigests = getAvailableKeymasterSignatureDigests(
                        spec.getDigests(),
                        AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests());