Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.security;
     18 
     19 import android.app.KeyguardManager;
     20 import android.annotation.NonNull;
     21 import android.annotation.Nullable;
     22 import android.content.Context;
     23 import android.security.keystore.KeyGenParameterSpec;
     24 import android.security.keystore.KeyProperties;
     25 import android.text.TextUtils;
     26 
     27 import java.math.BigInteger;
     28 import java.security.NoSuchAlgorithmException;
     29 import java.security.PrivateKey;
     30 import java.security.cert.Certificate;
     31 import java.security.spec.AlgorithmParameterSpec;
     32 import java.util.Date;
     33 
     34 import javax.security.auth.x500.X500Principal;
     35 
     36 /**
     37  * This provides the required parameters needed for initializing the
     38  * {@code KeyPairGenerator} that works with
     39  * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
     40  * facility</a>. The Android KeyStore facility is accessed through a
     41  * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
     42  * provider. The {@code context} passed in may be used to pop up some UI to ask
     43  * the user to unlock or initialize the Android KeyStore facility.
     44  * <p>
     45  * After generation, the {@code keyStoreAlias} is used with the
     46  * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
     47  * interface to retrieve the {@link PrivateKey} and its associated
     48  * {@link Certificate} chain.
     49  * <p>
     50  * The KeyPair generator will create a self-signed certificate with the subject
     51  * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
     52  * Distinguished Name along with the other parameters specified with the
     53  * {@link Builder}.
     54  * <p>
     55  * The self-signed X.509 certificate may be replaced at a later time by a
     56  * certificate signed by a real Certificate Authority.
     57  *
     58  * @deprecated Use {@link KeyGenParameterSpec} instead.
     59  */
     60 @Deprecated
     61 public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     62 
     63     private final Context mContext;
     64 
     65     private final String mKeystoreAlias;
     66 
     67     private final String mKeyType;
     68 
     69     private final int mKeySize;
     70 
     71     private final AlgorithmParameterSpec mSpec;
     72 
     73     private final X500Principal mSubjectDN;
     74 
     75     private final BigInteger mSerialNumber;
     76 
     77     private final Date mStartDate;
     78 
     79     private final Date mEndDate;
     80 
     81     private final int mFlags;
     82 
     83     /**
     84      * Parameter specification for the "{@code AndroidKeyPairGenerator}"
     85      * instance of the {@link java.security.KeyPairGenerator} API. The
     86      * {@code context} passed in may be used to pop up some UI to ask the user
     87      * to unlock or initialize the Android keystore facility.
     88      * <p>
     89      * After generation, the {@code keyStoreAlias} is used with the
     90      * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
     91      * interface to retrieve the {@link PrivateKey} and its associated
     92      * {@link Certificate} chain.
     93      * <p>
     94      * The KeyPair generator will create a self-signed certificate with the
     95      * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name
     96      * and as its X.509v3 Issuer Distinguished Name, using the specified
     97      * {@code serialNumber}, and the validity date starting at {@code startDate}
     98      * and ending at {@code endDate}.
     99      *
    100      * @param context Android context for the activity
    101      * @param keyStoreAlias name to use for the generated key in the Android
    102      *            keystore
    103      * @param keyType key algorithm to use (RSA, DSA, EC)
    104      * @param keySize size of key to generate
    105      * @param spec the underlying key type parameters
    106      * @param subjectDN X.509 v3 Subject Distinguished Name
    107      * @param serialNumber X509 v3 certificate serial number
    108      * @param startDate the start of the self-signed certificate validity period
    109      * @param endDate the end date of the self-signed certificate validity
    110      *            period
    111      * @throws IllegalArgumentException when any argument is {@code null} or
    112      *             {@code endDate} is before {@code startDate}.
    113      * @hide should be built with KeyPairGeneratorSpecBuilder
    114      */
    115     public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
    116             AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
    117             Date startDate, Date endDate, int flags) {
    118         if (context == null) {
    119             throw new IllegalArgumentException("context == null");
    120         } else if (TextUtils.isEmpty(keyStoreAlias)) {
    121             throw new IllegalArgumentException("keyStoreAlias must not be empty");
    122         } else if (subjectDN == null) {
    123             throw new IllegalArgumentException("subjectDN == null");
    124         } else if (serialNumber == null) {
    125             throw new IllegalArgumentException("serialNumber == null");
    126         } else if (startDate == null) {
    127             throw new IllegalArgumentException("startDate == null");
    128         } else if (endDate == null) {
    129             throw new IllegalArgumentException("endDate == null");
    130         } else if (endDate.before(startDate)) {
    131             throw new IllegalArgumentException("endDate < startDate");
    132         }
    133 
    134         if (endDate.before(startDate)) {
    135             throw new IllegalArgumentException("endDate < startDate");
    136         }
    137 
    138         mContext = context;
    139         mKeystoreAlias = keyStoreAlias;
    140         mKeyType = keyType;
    141         mKeySize = keySize;
    142         mSpec = spec;
    143         mSubjectDN = subjectDN;
    144         mSerialNumber = serialNumber;
    145         mStartDate = startDate;
    146         mEndDate = endDate;
    147         mFlags = flags;
    148     }
    149 
    150     /**
    151      * Gets the Android context used for operations with this instance.
    152      */
    153     public Context getContext() {
    154         return mContext;
    155     }
    156 
    157     /**
    158      * Returns the alias that will be used in the {@code java.security.KeyStore}
    159      * in conjunction with the {@code AndroidKeyStore}.
    160      */
    161     public String getKeystoreAlias() {
    162         return mKeystoreAlias;
    163     }
    164 
    165     /**
    166      * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See
    167      * {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
    168      */
    169     @Nullable
    170     public @KeyProperties.KeyAlgorithmEnum String getKeyType() {
    171         return mKeyType;
    172     }
    173 
    174     /**
    175      * Returns the key size specified by this parameter. For instance, for RSA
    176      * this will return the modulus size and for EC it will return the field
    177      * size.
    178      */
    179     public int getKeySize() {
    180         return mKeySize;
    181     }
    182 
    183     /**
    184      * Returns the {@link AlgorithmParameterSpec} that will be used for creation
    185      * of the key pair.
    186      */
    187     @NonNull
    188     public AlgorithmParameterSpec getAlgorithmParameterSpec() {
    189         return mSpec;
    190     }
    191 
    192     /**
    193      * Gets the subject distinguished name to be used on the X.509 certificate
    194      * that will be put in the {@link java.security.KeyStore}.
    195      */
    196     @NonNull
    197     public X500Principal getSubjectDN() {
    198         return mSubjectDN;
    199     }
    200 
    201     /**
    202      * Gets the serial number to be used on the X.509 certificate that will be
    203      * put in the {@link java.security.KeyStore}.
    204      */
    205     @NonNull
    206     public BigInteger getSerialNumber() {
    207         return mSerialNumber;
    208     }
    209 
    210     /**
    211      * Gets the start date to be used on the X.509 certificate that will be put
    212      * in the {@link java.security.KeyStore}.
    213      */
    214     @NonNull
    215     public Date getStartDate() {
    216         return mStartDate;
    217     }
    218 
    219     /**
    220      * Gets the end date to be used on the X.509 certificate that will be put in
    221      * the {@link java.security.KeyStore}.
    222      */
    223     @NonNull
    224     public Date getEndDate() {
    225         return mEndDate;
    226     }
    227 
    228     /**
    229      * @hide
    230      */
    231     public int getFlags() {
    232         return mFlags;
    233     }
    234 
    235     /**
    236      * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair
    237      * with the secure lock screen credential (e.g., password, PIN, or pattern).
    238      *
    239      * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password,
    240      * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be
    241      * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device
    242      * Administrator). Finally, this key cannot be used until the user unlocks the secure lock
    243      * screen after boot.
    244      *
    245      * @see KeyguardManager#isDeviceSecure()
    246      */
    247     public boolean isEncryptionRequired() {
    248         return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
    249     }
    250 
    251     /**
    252      * Builder class for {@link KeyPairGeneratorSpec} objects.
    253      * <p>
    254      * This will build a parameter spec for use with the
    255      * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
    256      * facility</a>.
    257      * <p>
    258      * The required fields must be filled in with the builder.
    259      * <p>
    260      * Example:
    261      *
    262      * <pre class="prettyprint">
    263      * Calendar start = Calendar.getInstance();
    264      * Calendar end = Calendar.getInstance();
    265      * end.add(Calendar.YEAR, 1);
    266      *
    267      * KeyPairGeneratorSpec spec =
    268      *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
    269      *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerialNumber(BigInteger.valueOf(1337))
    270      *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
    271      * </pre>
    272      *
    273      *  @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
    274      */
    275     @Deprecated
    276     public final static class Builder {
    277         private final Context mContext;
    278 
    279         private String mKeystoreAlias;
    280 
    281         private String mKeyType;
    282 
    283         private int mKeySize = -1;
    284 
    285         private AlgorithmParameterSpec mSpec;
    286 
    287         private X500Principal mSubjectDN;
    288 
    289         private BigInteger mSerialNumber;
    290 
    291         private Date mStartDate;
    292 
    293         private Date mEndDate;
    294 
    295         private int mFlags;
    296 
    297         /**
    298          * Creates a new instance of the {@code Builder} with the given
    299          * {@code context}. The {@code context} passed in may be used to pop up
    300          * some UI to ask the user to unlock or initialize the Android KeyStore
    301          * facility.
    302          */
    303         public Builder(@NonNull Context context) {
    304             if (context == null) {
    305                 throw new NullPointerException("context == null");
    306             }
    307             mContext = context;
    308         }
    309 
    310         /**
    311          * Sets the alias to be used to retrieve the key later from a
    312          * {@link java.security.KeyStore} instance using the
    313          * {@code AndroidKeyStore} provider.
    314          */
    315         @NonNull
    316         public Builder setAlias(@NonNull String alias) {
    317             if (alias == null) {
    318                 throw new NullPointerException("alias == null");
    319             }
    320             mKeystoreAlias = alias;
    321             return this;
    322         }
    323 
    324         /**
    325          * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be
    326          * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
    327          *
    328          */
    329         @NonNull
    330         public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
    331                 throws NoSuchAlgorithmException {
    332             if (keyType == null) {
    333                 throw new NullPointerException("keyType == null");
    334             } else {
    335                 try {
    336                     KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType);
    337                 } catch (IllegalArgumentException e) {
    338                     throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
    339                 }
    340             }
    341             mKeyType = keyType;
    342             return this;
    343         }
    344 
    345         /**
    346          * Sets the key size for the keypair to be created. For instance, for a
    347          * key type of RSA this will set the modulus size and for a key type of
    348          * EC it will select a curve with a matching field size.
    349          */
    350         @NonNull
    351         public Builder setKeySize(int keySize) {
    352             if (keySize < 0) {
    353                 throw new IllegalArgumentException("keySize < 0");
    354             }
    355             mKeySize = keySize;
    356             return this;
    357         }
    358 
    359         /**
    360          * Sets the algorithm-specific key generation parameters. For example, for RSA keys
    361          * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
    362          */
    363         public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
    364             if (spec == null) {
    365                 throw new NullPointerException("spec == null");
    366             }
    367             mSpec = spec;
    368             return this;
    369         }
    370 
    371         /**
    372          * Sets the subject used for the self-signed certificate of the
    373          * generated key pair.
    374          */
    375         @NonNull
    376         public Builder setSubject(@NonNull X500Principal subject) {
    377             if (subject == null) {
    378                 throw new NullPointerException("subject == null");
    379             }
    380             mSubjectDN = subject;
    381             return this;
    382         }
    383 
    384         /**
    385          * Sets the serial number used for the self-signed certificate of the
    386          * generated key pair.
    387          */
    388         @NonNull
    389         public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
    390             if (serialNumber == null) {
    391                 throw new NullPointerException("serialNumber == null");
    392             }
    393             mSerialNumber = serialNumber;
    394             return this;
    395         }
    396 
    397         /**
    398          * Sets the start of the validity period for the self-signed certificate
    399          * of the generated key pair.
    400          */
    401         @NonNull
    402         public Builder setStartDate(@NonNull Date startDate) {
    403             if (startDate == null) {
    404                 throw new NullPointerException("startDate == null");
    405             }
    406             mStartDate = startDate;
    407             return this;
    408         }
    409 
    410         /**
    411          * Sets the end of the validity period for the self-signed certificate
    412          * of the generated key pair.
    413          */
    414         @NonNull
    415         public Builder setEndDate(@NonNull Date endDate) {
    416             if (endDate == null) {
    417                 throw new NullPointerException("endDate == null");
    418             }
    419             mEndDate = endDate;
    420             return this;
    421         }
    422 
    423         /**
    424          * Indicates that this key pair must be encrypted at rest. This will protect the key pair
    425          * with the secure lock screen credential (e.g., password, PIN, or pattern).
    426          *
    427          * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
    428          * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will
    429          * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a
    430          * Device Administrator). Finally, this key pair cannot be used until the user unlocks the
    431          * secure lock screen after boot.
    432          *
    433          * @see KeyguardManager#isDeviceSecure()
    434          */
    435         @NonNull
    436         public Builder setEncryptionRequired() {
    437             mFlags |= KeyStore.FLAG_ENCRYPTED;
    438             return this;
    439         }
    440 
    441         /**
    442          * Builds the instance of the {@code KeyPairGeneratorSpec}.
    443          *
    444          * @throws IllegalArgumentException if a required field is missing
    445          * @return built instance of {@code KeyPairGeneratorSpec}
    446          */
    447         @NonNull
    448         public KeyPairGeneratorSpec build() {
    449             return new KeyPairGeneratorSpec(mContext,
    450                     mKeystoreAlias,
    451                     mKeyType,
    452                     mKeySize,
    453                     mSpec,
    454                     mSubjectDN,
    455                     mSerialNumber,
    456                     mStartDate,
    457                     mEndDate,
    458                     mFlags);
    459         }
    460     }
    461 }
    462