Search in sources :

Example 66 with ProviderException

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

the class KeyStoreCryptoOperationChunkedStreamer method flush.

public byte[] flush() throws KeyStoreException {
    if (mBufferedLength <= 0) {
        return EmptyArray.BYTE;
    }
    // Keep invoking the update operation with remaining buffered data until either all of the
    // buffered data is consumed or until update fails to consume anything.
    ByteArrayOutputStream bufferedOutput = null;
    while (mBufferedLength > 0) {
        byte[] chunk = ArrayUtils.subarray(mBuffered, mBufferedOffset, mBufferedLength);
        OperationResult opResult = mKeyStoreStream.update(chunk);
        if (opResult == null) {
            throw new KeyStoreConnectException();
        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
            throw KeyStore.getKeyStoreException(opResult.resultCode);
        }
        if (opResult.inputConsumed <= 0) {
            // Nothing was consumed. Break out of the loop to avoid an infinite loop.
            break;
        }
        if (opResult.inputConsumed >= chunk.length) {
            // All of the input was consumed
            mBuffered = EmptyArray.BYTE;
            mBufferedOffset = 0;
            mBufferedLength = 0;
        } else {
            // Some of the input was not consumed
            mBuffered = chunk;
            mBufferedOffset = opResult.inputConsumed;
            mBufferedLength = chunk.length - opResult.inputConsumed;
        }
        if (opResult.inputConsumed > chunk.length) {
            throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR, "Keystore consumed more input than provided. Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed);
        }
        if ((opResult.output != null) && (opResult.output.length > 0)) {
            // Some output was produced by this update operation
            if (bufferedOutput == null) {
                // No output buffered yet.
                if (mBufferedLength == 0) {
                    // No more output will be produced by this flush operation
                    mProducedOutputSizeBytes += opResult.output.length;
                    return opResult.output;
                } else {
                    // More output might be produced by this flush operation -- buffer output.
                    bufferedOutput = new ByteArrayOutputStream();
                }
            }
            // Buffer the output from this update operation
            try {
                bufferedOutput.write(opResult.output);
            } catch (IOException e) {
                throw new ProviderException("Failed to buffer output", e);
            }
        }
    }
    if (mBufferedLength > 0) {
        throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH, "Keystore failed to consume last " + ((mBufferedLength != 1) ? (mBufferedLength + " bytes") : "byte") + " of input");
    }
    byte[] result = (bufferedOutput != null) ? bufferedOutput.toByteArray() : EmptyArray.BYTE;
    mProducedOutputSizeBytes += result.length;
    return result;
}
Also used : ProviderException(java.security.ProviderException) OperationResult(android.security.keymaster.OperationResult) ByteArrayOutputStream(java.io.ByteArrayOutputStream) KeyStoreException(android.security.KeyStoreException) IOException(java.io.IOException)

Example 67 with ProviderException

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

the class KeymasterUtils method addUserAuthArgs.

/**
     * Adds keymaster arguments to express the key's authorization policy supported by user
     * authentication.
     *
     * @param userAuthenticationRequired whether user authentication is required to authorize the
     *        use of the key.
     * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user
     *        authentication is valid as authorization for using the key or {@code -1} if every
     *        use of the key needs authorization.
     *
     * @throws IllegalStateException if user authentication is required but the system is in a wrong
     *         state (e.g., secure lock screen not set up) for generating or importing keys that
     *         require user authentication.
     */
public static void addUserAuthArgs(KeymasterArguments args, boolean userAuthenticationRequired, int userAuthenticationValidityDurationSeconds, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment) {
    if (!userAuthenticationRequired) {
        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
        return;
    }
    if (userAuthenticationValidityDurationSeconds == -1) {
        // Every use of this key needs to be authorized by the user. This currently means
        // fingerprint-only auth.
        FingerprintManager fingerprintManager = KeyStore.getApplicationContext().getSystemService(FingerprintManager.class);
        // TODO: Restore USE_FINGERPRINT permission check in
        // FingerprintManager.getAuthenticatorId once the ID is no longer needed here.
        long fingerprintOnlySid = (fingerprintManager != null) ? fingerprintManager.getAuthenticatorId() : 0;
        if (fingerprintOnlySid == 0) {
            throw new IllegalStateException("At least one fingerprint must be enrolled to create keys requiring user" + " authentication for every use");
        }
        long sid;
        if (invalidatedByBiometricEnrollment) {
            // The fingerprint-only SID will change on fingerprint enrollment or removal of all,
            // enrolled fingerprints, invalidating the key.
            sid = fingerprintOnlySid;
        } else {
            // The root SID will *not* change on fingerprint enrollment, or removal of all
            // enrolled fingerprints, allowing the key to remain valid.
            sid = getRootSid();
        }
        args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid));
        args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
        if (userAuthenticationValidWhileOnBody) {
            throw new ProviderException("Key validity extension while device is on-body is not " + "supported for keys requiring fingerprint authentication");
        }
    } else {
        // The key is authorized for use for the specified amount of time after the user has
        // authenticated. Whatever unlocks the secure lock screen should authorize this key.
        long rootSid = getRootSid();
        args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(rootSid));
        args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
        args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, userAuthenticationValidityDurationSeconds);
        if (userAuthenticationValidWhileOnBody) {
            args.addBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
        }
    }
}
Also used : ProviderException(java.security.ProviderException) FingerprintManager(android.hardware.fingerprint.FingerprintManager)

Example 68 with ProviderException

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

the class AndroidKeyStoreKeyPairGeneratorSpi method getAttestationChain.

private Iterable<byte[]> getAttestationChain(String privateKeyAlias, KeyPair keyPair, KeymasterArguments args) throws ProviderException {
    KeymasterCertificateChain outChain = new KeymasterCertificateChain();
    int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain);
    if (errorCode != KeyStore.NO_ERROR) {
        throw new ProviderException("Failed to generate attestation certificate chain", KeyStore.getKeyStoreException(errorCode));
    }
    Collection<byte[]> chain = outChain.getCertificates();
    if (chain.size() < 2) {
        throw new ProviderException("Attestation certificate chain contained " + chain.size() + " entries. At least two are required.");
    }
    return chain;
}
Also used : ProviderException(java.security.ProviderException) KeymasterCertificateChain(android.security.keymaster.KeymasterCertificateChain)

Example 69 with ProviderException

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

the class AndroidKeyStoreKeyPairGeneratorSpi method initAlgorithmSpecificParameters.

private void initAlgorithmSpecificParameters() throws InvalidAlgorithmParameterException {
    AlgorithmParameterSpec algSpecificSpec = mSpec.getAlgorithmParameterSpec();
    switch(mKeymasterAlgorithm) {
        case KeymasterDefs.KM_ALGORITHM_RSA:
            {
                BigInteger publicExponent = null;
                if (algSpecificSpec instanceof RSAKeyGenParameterSpec) {
                    RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) algSpecificSpec;
                    if (mKeySizeBits == -1) {
                        mKeySizeBits = rsaSpec.getKeysize();
                    } else if (mKeySizeBits != rsaSpec.getKeysize()) {
                        throw new InvalidAlgorithmParameterException("RSA key size must match " + " between " + mSpec + " and " + algSpecificSpec + ": " + mKeySizeBits + " vs " + rsaSpec.getKeysize());
                    }
                    publicExponent = rsaSpec.getPublicExponent();
                } else if (algSpecificSpec != null) {
                    throw new InvalidAlgorithmParameterException("RSA may only use RSAKeyGenParameterSpec");
                }
                if (publicExponent == null) {
                    publicExponent = RSAKeyGenParameterSpec.F4;
                }
                if (publicExponent.compareTo(BigInteger.ZERO) < 1) {
                    throw new InvalidAlgorithmParameterException("RSA public exponent must be positive: " + publicExponent);
                }
                if (publicExponent.compareTo(KeymasterArguments.UINT64_MAX_VALUE) > 0) {
                    throw new InvalidAlgorithmParameterException("Unsupported RSA public exponent: " + publicExponent + ". Maximum supported value: " + KeymasterArguments.UINT64_MAX_VALUE);
                }
                mRSAPublicExponent = publicExponent;
                break;
            }
        case KeymasterDefs.KM_ALGORITHM_EC:
            if (algSpecificSpec instanceof ECGenParameterSpec) {
                ECGenParameterSpec ecSpec = (ECGenParameterSpec) algSpecificSpec;
                String curveName = ecSpec.getName();
                Integer ecSpecKeySizeBits = SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.get(curveName.toLowerCase(Locale.US));
                if (ecSpecKeySizeBits == null) {
                    throw new InvalidAlgorithmParameterException("Unsupported EC curve name: " + curveName + ". Supported: " + SUPPORTED_EC_NIST_CURVE_NAMES);
                }
                if (mKeySizeBits == -1) {
                    mKeySizeBits = ecSpecKeySizeBits;
                } else if (mKeySizeBits != ecSpecKeySizeBits) {
                    throw new InvalidAlgorithmParameterException("EC key size must match " + " between " + mSpec + " and " + algSpecificSpec + ": " + mKeySizeBits + " vs " + ecSpecKeySizeBits);
                }
            } else if (algSpecificSpec != null) {
                throw new InvalidAlgorithmParameterException("EC may only use ECGenParameterSpec");
            }
            break;
        default:
            throw new ProviderException("Unsupported algorithm: " + mKeymasterAlgorithm);
    }
}
Also used : BigInteger(java.math.BigInteger) ASN1Integer(com.android.org.bouncycastle.asn1.ASN1Integer) DERInteger(com.android.org.bouncycastle.asn1.DERInteger) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) ProviderException(java.security.ProviderException) ECGenParameterSpec(java.security.spec.ECGenParameterSpec) BigInteger(java.math.BigInteger) RSAKeyGenParameterSpec(java.security.spec.RSAKeyGenParameterSpec) DERBitString(com.android.org.bouncycastle.asn1.DERBitString) AlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec)

Example 70 with ProviderException

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

the class AndroidKeyStoreKeyPairGeneratorSpi method generateKeystoreKeyPair.

private void generateKeystoreKeyPair(final String privateKeyAlias, KeymasterArguments args, byte[] additionalEntropy, final int flags) throws ProviderException {
    KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
    int errorCode = mKeyStore.generateKey(privateKeyAlias, args, additionalEntropy, mEntryUid, flags, resultingKeyCharacteristics);
    if (errorCode != KeyStore.NO_ERROR) {
        throw new ProviderException("Failed to generate key pair", KeyStore.getKeyStoreException(errorCode));
    }
}
Also used : ProviderException(java.security.ProviderException) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

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