Search in sources :

Example 96 with ProviderException

use of java.security.ProviderException in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreProvider method getAndroidKeyStorePublicKey.

@NonNull
public static AndroidKeyStorePublicKey getAndroidKeyStorePublicKey(@NonNull String alias, int uid, @NonNull @KeyProperties.KeyAlgorithmEnum String keyAlgorithm, @NonNull byte[] x509EncodedForm) {
    PublicKey publicKey;
    try {
        KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
        publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedForm));
    } catch (NoSuchAlgorithmException e) {
        throw new ProviderException("Failed to obtain " + keyAlgorithm + " KeyFactory", e);
    } catch (InvalidKeySpecException e) {
        throw new ProviderException("Invalid X.509 encoding of public key", e);
    }
    if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
        return new AndroidKeyStoreECPublicKey(alias, uid, (ECPublicKey) publicKey);
    } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
        return new AndroidKeyStoreRSAPublicKey(alias, uid, (RSAPublicKey) publicKey);
    } else {
        throw new ProviderException("Unsupported Android Keystore public key algorithm: " + keyAlgorithm);
    }
}
Also used : RSAPublicKey(java.security.interfaces.RSAPublicKey) ProviderException(java.security.ProviderException) NoSuchProviderException(java.security.NoSuchProviderException) RSAPublicKey(java.security.interfaces.RSAPublicKey) PublicKey(java.security.PublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) X509EncodedKeySpec(java.security.spec.X509EncodedKeySpec) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) KeyFactory(java.security.KeyFactory) NonNull(android.annotation.NonNull)

Example 97 with ProviderException

use of java.security.ProviderException in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreSecretKeyFactorySpi method getKeyInfo.

static KeyInfo getKeyInfo(KeyStore keyStore, String entryAlias, String keyAliasInKeystore, int keyUid) {
    KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
    int errorCode = keyStore.getKeyCharacteristics(keyAliasInKeystore, null, null, keyUid, keyCharacteristics);
    if (errorCode != KeyStore.NO_ERROR) {
        throw new ProviderException("Failed to obtain information about key." + " Keystore error: " + errorCode);
    }
    boolean insideSecureHardware;
    @KeyProperties.OriginEnum int origin;
    int keySize;
    @KeyProperties.PurposeEnum int purposes;
    String[] encryptionPaddings;
    String[] signaturePaddings;
    @KeyProperties.DigestEnum String[] digests;
    @KeyProperties.BlockModeEnum String[] blockModes;
    int keymasterSwEnforcedUserAuthenticators;
    int keymasterHwEnforcedUserAuthenticators;
    List<BigInteger> keymasterSecureUserIds;
    try {
        if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
            insideSecureHardware = true;
            origin = KeyProperties.Origin.fromKeymaster(keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
        } else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
            insideSecureHardware = false;
            origin = KeyProperties.Origin.fromKeymaster(keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
        } else {
            throw new ProviderException("Key origin not available");
        }
        long keySizeUnsigned = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
        if (keySizeUnsigned == -1) {
            throw new ProviderException("Key size not available");
        } else if (keySizeUnsigned > Integer.MAX_VALUE) {
            throw new ProviderException("Key too large: " + keySizeUnsigned + " bits");
        }
        keySize = (int) keySizeUnsigned;
        purposes = KeyProperties.Purpose.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PURPOSE));
        List<String> encryptionPaddingsList = new ArrayList<String>();
        List<String> signaturePaddingsList = new ArrayList<String>();
        // Keymaster stores both types of paddings in the same array -- we split it into two.
        for (int keymasterPadding : keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PADDING)) {
            try {
                @KeyProperties.EncryptionPaddingEnum String jcaPadding = KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
                encryptionPaddingsList.add(jcaPadding);
            } catch (IllegalArgumentException e) {
                try {
                    @KeyProperties.SignaturePaddingEnum String padding = KeyProperties.SignaturePadding.fromKeymaster(keymasterPadding);
                    signaturePaddingsList.add(padding);
                } catch (IllegalArgumentException e2) {
                    throw new ProviderException("Unsupported encryption padding: " + keymasterPadding);
                }
            }
        }
        encryptionPaddings = encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
        signaturePaddings = signaturePaddingsList.toArray(new String[signaturePaddingsList.size()]);
        digests = KeyProperties.Digest.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST));
        blockModes = KeyProperties.BlockMode.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_BLOCK_MODE));
        keymasterSwEnforcedUserAuthenticators = keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
        keymasterHwEnforcedUserAuthenticators = keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
        keymasterSecureUserIds = keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
    } catch (IllegalArgumentException e) {
        throw new ProviderException("Unsupported key characteristic", e);
    }
    Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
    Date keyValidityForOriginationEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
    Date keyValidityForConsumptionEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
    boolean userAuthenticationRequired = !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
    long userAuthenticationValidityDurationSeconds = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
    if (userAuthenticationValidityDurationSeconds > Integer.MAX_VALUE) {
        throw new ProviderException("User authentication timeout validity too long: " + userAuthenticationValidityDurationSeconds + " seconds");
    }
    boolean userAuthenticationRequirementEnforcedBySecureHardware = (userAuthenticationRequired) && (keymasterHwEnforcedUserAuthenticators != 0) && (keymasterSwEnforcedUserAuthenticators == 0);
    boolean userAuthenticationValidWhileOnBody = keyCharacteristics.hwEnforced.getBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
    boolean invalidatedByBiometricEnrollment = false;
    if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT) {
        // Fingerprint-only key; will be invalidated if the root SID isn't in the SID list.
        invalidatedByBiometricEnrollment = keymasterSecureUserIds != null && !keymasterSecureUserIds.isEmpty() && !keymasterSecureUserIds.contains(getGateKeeperSecureUserId());
    }
    return new KeyInfo(entryAlias, insideSecureHardware, origin, keySize, keyValidityStart, keyValidityForOriginationEnd, keyValidityForConsumptionEnd, purposes, encryptionPaddings, signaturePaddings, digests, blockModes, userAuthenticationRequired, (int) userAuthenticationValidityDurationSeconds, userAuthenticationRequirementEnforcedBySecureHardware, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment);
}
Also used : ProviderException(java.security.ProviderException) ArrayList(java.util.ArrayList) Date(java.util.Date) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) BigInteger(java.math.BigInteger)

Example 98 with ProviderException

use of java.security.ProviderException in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreSignatureSpiBase method engineVerify.

@Override
protected final boolean engineVerify(byte[] signature) throws SignatureException {
    if (mCachedException != null) {
        throw new SignatureException(mCachedException);
    }
    try {
        ensureKeystoreOperationInitialized();
    } catch (InvalidKeyException e) {
        throw new SignatureException(e);
    }
    boolean verified;
    try {
        byte[] output = mMessageStreamer.doFinal(EmptyArray.BYTE, 0, 0, signature, // no additional entropy needed -- verification is deterministic
        null);
        if (output.length != 0) {
            throw new ProviderException("Signature verification unexpected produced output: " + output.length + " bytes");
        }
        verified = true;
    } catch (KeyStoreException e) {
        switch(e.getErrorCode()) {
            case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
                verified = false;
                break;
            default:
                throw new SignatureException(e);
        }
    }
    resetWhilePreservingInitState();
    return verified;
}
Also used : ProviderException(java.security.ProviderException) SignatureException(java.security.SignatureException) KeyStoreException(android.security.KeyStoreException) InvalidKeyException(java.security.InvalidKeyException)

Example 99 with ProviderException

use of java.security.ProviderException in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreSpi method setSecretKeyEntry.

private void setSecretKeyEntry(String entryAlias, SecretKey key, java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
    if ((param != null) && (!(param instanceof KeyProtection))) {
        throw new KeyStoreException("Unsupported protection parameter class: " + param.getClass().getName() + ". Supported: " + KeyProtection.class.getName());
    }
    KeyProtection params = (KeyProtection) param;
    if (key instanceof AndroidKeyStoreSecretKey) {
        // KeyStore-backed secret key. It cannot be duplicated into another entry and cannot
        // overwrite its own entry.
        String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias();
        if (keyAliasInKeystore == null) {
            throw new KeyStoreException("KeyStore-backed secret key does not have an alias");
        }
        if (!keyAliasInKeystore.startsWith(Credentials.USER_SECRET_KEY)) {
            throw new KeyStoreException("KeyStore-backed secret key has invalid alias: " + keyAliasInKeystore);
        }
        String keyEntryAlias = keyAliasInKeystore.substring(Credentials.USER_SECRET_KEY.length());
        if (!entryAlias.equals(keyEntryAlias)) {
            throw new KeyStoreException("Can only replace KeyStore-backed keys with same" + " alias: " + entryAlias + " != " + keyEntryAlias);
        }
        // This is the entry where this key is already stored. No need to do anything.
        if (params != null) {
            throw new KeyStoreException("Modifying KeyStore-backed key using protection" + " parameters not supported");
        }
        return;
    }
    if (params == null) {
        throw new KeyStoreException("Protection parameters must be specified when importing a symmetric key");
    }
    // Not a KeyStore-backed secret key -- import its key material into keystore.
    String keyExportFormat = key.getFormat();
    if (keyExportFormat == null) {
        throw new KeyStoreException("Only secret keys that export their key material are supported");
    } else if (!"RAW".equals(keyExportFormat)) {
        throw new KeyStoreException("Unsupported secret key material export format: " + keyExportFormat);
    }
    byte[] keyMaterial = key.getEncoded();
    if (keyMaterial == null) {
        throw new KeyStoreException("Key did not export its key material despite supporting" + " RAW format export");
    }
    KeymasterArguments args = new KeymasterArguments();
    try {
        int keymasterAlgorithm = KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(key.getAlgorithm());
        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
        int[] keymasterDigests;
        if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
            // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
            // implies SHA-256 digest). Because keymaster HMAC key is authorized only for one
            // digest, we don't let import parameters override the digest implied by the key.
            // If the parameters specify digests at all, they must specify only one digest, the
            // only implied by key algorithm.
            int keymasterImpliedDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm());
            if (keymasterImpliedDigest == -1) {
                throw new ProviderException("HMAC key algorithm digest unknown for key algorithm " + key.getAlgorithm());
            }
            keymasterDigests = new int[] { keymasterImpliedDigest };
            if (params.isDigestsSpecified()) {
                // Digest(s) explicitly specified in params -- check that the list consists of
                // exactly one digest, the one implied by key algorithm.
                int[] keymasterDigestsFromParams = KeyProperties.Digest.allToKeymaster(params.getDigests());
                if ((keymasterDigestsFromParams.length != 1) || (keymasterDigestsFromParams[0] != keymasterImpliedDigest)) {
                    throw new KeyStoreException("Unsupported digests specification: " + Arrays.asList(params.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(keymasterImpliedDigest) + " supported for HMAC key algorithm " + key.getAlgorithm());
                }
            }
        } else {
            // Key algorithm does not imply a digest.
            if (params.isDigestsSpecified()) {
                keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests());
            } else {
                keymasterDigests = EmptyArray.INT;
            }
        }
        args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
        @KeyProperties.PurposeEnum int purposes = params.getPurposes();
        int[] keymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
        if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (params.isRandomizedEncryptionRequired())) {
            for (int keymasterBlockMode : keymasterBlockModes) {
                if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(keymasterBlockMode)) {
                    throw new KeyStoreException("Randomized encryption (IND-CPA) required but may be violated by" + " block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See KeyProtection documentation.");
                }
            }
        }
        args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
        args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
        if (params.getSignaturePaddings().length > 0) {
            throw new KeyStoreException("Signature paddings not supported for symmetric keys");
        }
        int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(params.getEncryptionPaddings());
        args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
        KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds(), params.isUserAuthenticationValidWhileOnBody(), params.isInvalidatedByBiometricEnrollment());
        KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(args, keymasterAlgorithm, keymasterBlockModes, keymasterDigests);
        args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart());
        args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, params.getKeyValidityForOriginationEnd());
        args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, params.getKeyValidityForConsumptionEnd());
        if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!params.isRandomizedEncryptionRequired())) {
            // Permit caller-provided IV when encrypting with this key
            args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
        }
    } catch (IllegalArgumentException | IllegalStateException e) {
        throw new KeyStoreException(e);
    }
    Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid);
    String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias;
    int errorCode = mKeyStore.importKey(keyAliasInKeystore, args, KeymasterDefs.KM_KEY_FORMAT_RAW, keyMaterial, mUid, // flags
    0, new KeyCharacteristics());
    if (errorCode != KeyStore.NO_ERROR) {
        throw new KeyStoreException("Failed to import secret key. Keystore error code: " + errorCode);
    }
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments) ProviderException(java.security.ProviderException) KeyStoreException(java.security.KeyStoreException) KeyProtection(android.security.keystore.KeyProtection) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 100 with ProviderException

use of java.security.ProviderException in project android_frameworks_base by DirtyUnicorns.

the class AndroidKeyStoreUnauthenticatedAESCipherSpi method engineGetParameters.

@Nullable
@Override
protected final AlgorithmParameters engineGetParameters() {
    if (!mIvRequired) {
        return null;
    }
    if ((mIv != null) && (mIv.length > 0)) {
        try {
            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
            params.init(new IvParameterSpec(mIv));
            return params;
        } catch (NoSuchAlgorithmException e) {
            throw new ProviderException("Failed to obtain AES AlgorithmParameters", e);
        } catch (InvalidParameterSpecException e) {
            throw new ProviderException("Failed to initialize AES AlgorithmParameters with an IV", e);
        }
    }
    return null;
}
Also used : ProviderException(java.security.ProviderException) IvParameterSpec(javax.crypto.spec.IvParameterSpec) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidParameterSpecException(java.security.spec.InvalidParameterSpecException) AlgorithmParameters(java.security.AlgorithmParameters) Nullable(android.annotation.Nullable)

Aggregations

ProviderException (java.security.ProviderException)128 KeymasterArguments (android.security.keymaster.KeymasterArguments)30 InvalidKeyException (java.security.InvalidKeyException)26 OperationResult (android.security.keymaster.OperationResult)25 KeyStoreException (android.security.KeyStoreException)20 KeyCharacteristics (android.security.keymaster.KeyCharacteristics)20 DERBitString (com.android.org.bouncycastle.asn1.DERBitString)15 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)15 BigInteger (java.math.BigInteger)13 IOException (java.io.IOException)12 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)12 ASN1Integer (com.android.org.bouncycastle.asn1.ASN1Integer)10 DERInteger (com.android.org.bouncycastle.asn1.DERInteger)10 ByteArrayOutputStream (java.io.ByteArrayOutputStream)10 RSAKeyGenParameterSpec (java.security.spec.RSAKeyGenParameterSpec)10 GeneralSecurityException (java.security.GeneralSecurityException)6 KeyStoreException (java.security.KeyStoreException)6 NoSuchProviderException (java.security.NoSuchProviderException)6 KeymasterCertificateChain (android.security.keymaster.KeymasterCertificateChain)5 KeyProtection (android.security.keystore.KeyProtection)5