summaryrefslogtreecommitdiffstats
path: root/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java
blob: 20db41b3f84e0777ffd3e215c8c0d5dce44eae83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.security.keystore;

import android.security.Credentials;
import android.security.KeyStore;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * {@link KeyFactorySpi} backed by Android KeyStore.
 *
 * @hide
 */
public class AndroidKeyStoreKeyFactorySpi extends KeyFactorySpi {

    private final KeyStore mKeyStore = KeyStore.getInstance();

    @Override
    protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpecClass)
            throws InvalidKeySpecException {
        if (keySpecClass == null) {
            throw new InvalidKeySpecException("keySpecClass == null");
        }
        if (!(key instanceof AndroidKeyStorePrivateKey)) {
            throw new InvalidKeySpecException("Only Android KeyStore private keys supported: " +
                    ((key != null) ? key.getClass().getName() : "null"));
        }
        if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpecClass)) {
            throw new InvalidKeySpecException(
                    "Key material export of Android KeyStore keys is not supported");
        }
        if (!KeyInfo.class.equals(keySpecClass)) {
            throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
        }
        String keyAliasInKeystore = ((AndroidKeyStoreKey) key).getAlias();
        String entryAlias;
        if (keyAliasInKeystore.startsWith(Credentials.USER_PRIVATE_KEY)) {
            entryAlias = keyAliasInKeystore.substring(Credentials.USER_PRIVATE_KEY.length());
        } else {
            throw new InvalidKeySpecException("Invalid key alias: " + keyAliasInKeystore);
        }

        @SuppressWarnings("unchecked")
        T result = (T) AndroidKeyStoreSecretKeyFactorySpi.getKeyInfo(
                mKeyStore, entryAlias, keyAliasInKeystore);
        return result;
    }

    @Override
    protected PrivateKey engineGeneratePrivate(KeySpec spec) throws InvalidKeySpecException {
        throw new UnsupportedOperationException(
                "To generate a key pair in Android KeyStore, use KeyPairGenerator initialized with"
                + " " + KeyGenParameterSpec.class.getName());
    }

    @Override
    protected PublicKey engineGeneratePublic(KeySpec spec) throws InvalidKeySpecException {
        throw new UnsupportedOperationException(
                "To generate a key pair in Android KeyStore, use KeyPairGenerator initialized with"
                + " " + KeyGenParameterSpec.class.getName());
    }

    @Override
    protected Key engineTranslateKey(Key arg0) throws InvalidKeyException {
        throw new UnsupportedOperationException(
                "To import a key into Android KeyStore, use KeyStore.setEntry with "
                + KeyProtection.class.getName());
    }
}