Search in sources :

Example 61 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class KeyStoreTest method testAesGcmEncryptSuccess.

public void testAesGcmEncryptSuccess() throws Exception {
    String name = "test";
    KeymasterArguments args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
    args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
    args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
    args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
    KeyCharacteristics outCharacteristics = new KeyCharacteristics();
    int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
    assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
    args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
    args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
    args.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 128);
    OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null);
    IBinder token = result.token;
    assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
    result = mKeyStore.update(token, null, new byte[] { 0x01, 0x02, 0x03, 0x04 });
    assertEquals("Update should succeed", KeyStore.NO_ERROR, result.resultCode);
    assertEquals("Finish should succeed", KeyStore.NO_ERROR, mKeyStore.finish(token, null, null).resultCode);
// TODO: Assert that an AEAD tag was returned by finish
}
Also used : IBinder(android.os.IBinder) KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) OperationResult(android.security.keymaster.OperationResult)

Example 62 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class KeyStoreTest method testGetKeyCharacteristicsSuccess.

public void testGetKeyCharacteristicsSuccess() throws Exception {
    mKeyStore.onUserPasswordChanged(TEST_PASSWD);
    String name = "test";
    KeyCharacteristics gen = generateRsaKey(name);
    KeyCharacteristics call = new KeyCharacteristics();
    int result = mKeyStore.getKeyCharacteristics(name, null, null, call);
    assertEquals("getKeyCharacteristics should succeed", KeyStore.NO_ERROR, result);
    mKeyStore.delete("test");
}
Also used : KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 63 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class KeyStoreTest method testGenerateRsaWithEntropy.

public void testGenerateRsaWithEntropy() throws Exception {
    byte[] entropy = new byte[] { 1, 2, 3, 4, 5 };
    String name = "test";
    KeymasterArguments args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
    args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
    args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
    args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
    KeyCharacteristics outCharacteristics = new KeyCharacteristics();
    int result = mKeyStore.generateKey(name, args, entropy, 0, outCharacteristics);
    assertEquals("generateKey should succeed", KeyStore.NO_ERROR, result);
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Example 64 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by DirtyUnicorns.

the class KeyStoreTest method testAuthNeeded.

public void testAuthNeeded() throws Exception {
    String name = "test";
    KeymasterArguments args = new KeymasterArguments();
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
    args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
    args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
    args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
    args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
    args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
    KeyCharacteristics outCharacteristics = new KeyCharacteristics();
    int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
    assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
    OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null);
    assertEquals("Begin should expect authorization", KeyStore.OP_AUTH_NEEDED, result.resultCode);
    IBinder token = result.token;
    result = mKeyStore.update(token, null, new byte[] { 0x01, 0x02, 0x03, 0x04 });
    assertEquals("Update should require authorization", KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED, result.resultCode);
}
Also used : IBinder(android.os.IBinder) KeymasterArguments(android.security.keymaster.KeymasterArguments) KeyCharacteristics(android.security.keymaster.KeyCharacteristics) OperationResult(android.security.keymaster.OperationResult)

Example 65 with KeyCharacteristics

use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by AOSPA.

the class AndroidKeyStoreSpi method setPrivateKeyEntry.

private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain, java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
    int flags = 0;
    KeyProtection spec;
    if (param == null) {
        spec = getLegacyKeyProtectionParameter(key);
    } else if (param instanceof KeyStoreParameter) {
        spec = getLegacyKeyProtectionParameter(key);
        KeyStoreParameter legacySpec = (KeyStoreParameter) param;
        if (legacySpec.isEncryptionRequired()) {
            flags = KeyStore.FLAG_ENCRYPTED;
        }
    } else if (param instanceof KeyProtection) {
        spec = (KeyProtection) param;
    } else {
        throw new KeyStoreException("Unsupported protection parameter class:" + param.getClass().getName() + ". Supported: " + KeyProtection.class.getName() + ", " + KeyStoreParameter.class.getName());
    }
    // Make sure the chain exists since this is a PrivateKey
    if ((chain == null) || (chain.length == 0)) {
        throw new KeyStoreException("Must supply at least one Certificate with PrivateKey");
    }
    // Do chain type checking.
    X509Certificate[] x509chain = new X509Certificate[chain.length];
    for (int i = 0; i < chain.length; i++) {
        if (!"X.509".equals(chain[i].getType())) {
            throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #" + i);
        }
        if (!(chain[i] instanceof X509Certificate)) {
            throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #" + i);
        }
        x509chain[i] = (X509Certificate) chain[i];
    }
    final byte[] userCertBytes;
    try {
        userCertBytes = x509chain[0].getEncoded();
    } catch (CertificateEncodingException e) {
        throw new KeyStoreException("Failed to encode certificate #0", e);
    }
    /*
         * If we have a chain, store it in the CA certificate slot for this
         * alias as concatenated DER-encoded certificates. These can be
         * deserialized by {@link CertificateFactory#generateCertificates}.
         */
    final byte[] chainBytes;
    if (chain.length > 1) {
        /*
             * The chain is passed in as {user_cert, ca_cert_1, ca_cert_2, ...}
             * so we only need the certificates starting at index 1.
             */
        final byte[][] certsBytes = new byte[x509chain.length - 1][];
        int totalCertLength = 0;
        for (int i = 0; i < certsBytes.length; i++) {
            try {
                certsBytes[i] = x509chain[i + 1].getEncoded();
                totalCertLength += certsBytes[i].length;
            } catch (CertificateEncodingException e) {
                throw new KeyStoreException("Failed to encode certificate #" + i, e);
            }
        }
        /*
             * Serialize this into one byte array so we can later call
             * CertificateFactory#generateCertificates to recover them.
             */
        chainBytes = new byte[totalCertLength];
        int outputOffset = 0;
        for (int i = 0; i < certsBytes.length; i++) {
            final int certLength = certsBytes[i].length;
            System.arraycopy(certsBytes[i], 0, chainBytes, outputOffset, certLength);
            outputOffset += certLength;
            certsBytes[i] = null;
        }
    } else {
        chainBytes = null;
    }
    final String pkeyAlias;
    if (key instanceof AndroidKeyStorePrivateKey) {
        pkeyAlias = ((AndroidKeyStoreKey) key).getAlias();
    } else {
        pkeyAlias = null;
    }
    byte[] pkcs8EncodedPrivateKeyBytes;
    KeymasterArguments importArgs;
    final boolean shouldReplacePrivateKey;
    if (pkeyAlias != null && pkeyAlias.startsWith(Credentials.USER_PRIVATE_KEY)) {
        final String keySubalias = pkeyAlias.substring(Credentials.USER_PRIVATE_KEY.length());
        if (!alias.equals(keySubalias)) {
            throw new KeyStoreException("Can only replace keys with same alias: " + alias + " != " + keySubalias);
        }
        shouldReplacePrivateKey = false;
        importArgs = null;
        pkcs8EncodedPrivateKeyBytes = null;
    } else {
        shouldReplacePrivateKey = true;
        // Make sure the PrivateKey format is the one we support.
        final String keyFormat = key.getFormat();
        if ((keyFormat == null) || (!"PKCS#8".equals(keyFormat))) {
            throw new KeyStoreException("Unsupported private key export format: " + keyFormat + ". Only private keys which export their key material in PKCS#8 format are" + " supported.");
        }
        // Make sure we can actually encode the key.
        pkcs8EncodedPrivateKeyBytes = key.getEncoded();
        if (pkcs8EncodedPrivateKeyBytes == null) {
            throw new KeyStoreException("Private key did not export any key material");
        }
        importArgs = new KeymasterArguments();
        try {
            importArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(key.getAlgorithm()));
            @KeyProperties.PurposeEnum int purposes = spec.getPurposes();
            importArgs.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
            if (spec.isDigestsSpecified()) {
                importArgs.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeyProperties.Digest.allToKeymaster(spec.getDigests()));
            }
            importArgs.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes()));
            int[] keymasterEncryptionPaddings = KeyProperties.EncryptionPadding.allToKeymaster(spec.getEncryptionPaddings());
            if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (spec.isRandomizedEncryptionRequired())) {
                for (int keymasterPadding : keymasterEncryptionPaddings) {
                    if (!KeymasterUtils.isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(keymasterPadding)) {
                        throw new KeyStoreException("Randomized encryption (IND-CPA) required but is violated by" + " encryption padding mode: " + KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding) + ". See KeyProtection documentation.");
                    }
                }
            }
            importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
            importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
            KeymasterUtils.addUserAuthArgs(importArgs, spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds(), spec.isUserAuthenticationValidWhileOnBody(), spec.isInvalidatedByBiometricEnrollment());
            importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart());
            importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, spec.getKeyValidityForOriginationEnd());
            importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, spec.getKeyValidityForConsumptionEnd());
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new KeyStoreException(e);
        }
    }
    boolean success = false;
    try {
        // Store the private key, if necessary
        if (shouldReplacePrivateKey) {
            // Delete the stored private key and any related entries before importing the
            // provided key
            Credentials.deleteAllTypesForAlias(mKeyStore, alias, mUid);
            KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
            int errorCode = mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, importArgs, KeymasterDefs.KM_KEY_FORMAT_PKCS8, pkcs8EncodedPrivateKeyBytes, mUid, flags, resultingKeyCharacteristics);
            if (errorCode != KeyStore.NO_ERROR) {
                throw new KeyStoreException("Failed to store private key", KeyStore.getKeyStoreException(errorCode));
            }
        } else {
            // Keep the stored private key around -- delete all other entry types
            Credentials.deleteCertificateTypesForAlias(mKeyStore, alias, mUid);
            Credentials.deleteSecretKeyTypeForAlias(mKeyStore, alias, mUid);
        }
        // Store the leaf certificate
        int errorCode = mKeyStore.insert(Credentials.USER_CERTIFICATE + alias, userCertBytes, mUid, flags);
        if (errorCode != KeyStore.NO_ERROR) {
            throw new KeyStoreException("Failed to store certificate #0", KeyStore.getKeyStoreException(errorCode));
        }
        // Store the certificate chain
        errorCode = mKeyStore.insert(Credentials.CA_CERTIFICATE + alias, chainBytes, mUid, flags);
        if (errorCode != KeyStore.NO_ERROR) {
            throw new KeyStoreException("Failed to store certificate chain", KeyStore.getKeyStoreException(errorCode));
        }
        success = true;
    } finally {
        if (!success) {
            if (shouldReplacePrivateKey) {
                Credentials.deleteAllTypesForAlias(mKeyStore, alias, mUid);
            } else {
                Credentials.deleteCertificateTypesForAlias(mKeyStore, alias, mUid);
                Credentials.deleteSecretKeyTypeForAlias(mKeyStore, alias, mUid);
            }
        }
    }
}
Also used : KeymasterArguments(android.security.keymaster.KeymasterArguments) CertificateEncodingException(java.security.cert.CertificateEncodingException) KeyStoreException(java.security.KeyStoreException) KeyProtection(android.security.keystore.KeyProtection) X509Certificate(java.security.cert.X509Certificate) KeyStoreParameter(android.security.KeyStoreParameter) KeyCharacteristics(android.security.keymaster.KeyCharacteristics)

Aggregations

KeyCharacteristics (android.security.keymaster.KeyCharacteristics)85 KeymasterArguments (android.security.keymaster.KeymasterArguments)50 ProviderException (java.security.ProviderException)20 IBinder (android.os.IBinder)15 OperationResult (android.security.keymaster.OperationResult)15 NonNull (android.annotation.NonNull)10 KeyProtection (android.security.keystore.KeyProtection)10 InvalidKeyException (java.security.InvalidKeyException)10 KeyStoreException (java.security.KeyStoreException)10 UnrecoverableKeyException (java.security.UnrecoverableKeyException)10 KeyStoreParameter (android.security.KeyStoreParameter)5 ExportResult (android.security.keymaster.ExportResult)5 KeymasterBlob (android.security.keymaster.KeymasterBlob)5 KeyGenParameterSpec (android.security.keystore.KeyGenParameterSpec)5 BigInteger (java.math.BigInteger)5 PrivateKey (java.security.PrivateKey)5 CertificateEncodingException (java.security.cert.CertificateEncodingException)5 X509Certificate (java.security.cert.X509Certificate)5 ArrayList (java.util.ArrayList)5 Date (java.util.Date)5