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.content.Context;
     20 import android.text.TextUtils;
     21 
     22 import java.math.BigInteger;
     23 import java.security.PrivateKey;
     24 import java.security.cert.Certificate;
     25 import java.security.spec.AlgorithmParameterSpec;
     26 import java.util.Date;
     27 
     28 import javax.security.auth.x500.X500Principal;
     29 
     30 /**
     31  * This provides the required parameters needed for initializing the
     32  * {@code KeyPairGenerator} that works with
     33  * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore
     34  * facility</a>. The Android KeyStore facility is accessed through a
     35  * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
     36  * provider. The {@code context} passed in may be used to pop up some UI to ask
     37  * the user to unlock or initialize the Android KeyStore facility.
     38  * <p>
     39  * After generation, the {@code keyStoreAlias} is used with the
     40  * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
     41  * interface to retrieve the {@link PrivateKey} and its associated
     42  * {@link Certificate} chain.
     43  * <p>
     44  * The KeyPair generator will create a self-signed certificate with the subject
     45  * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
     46  * Distinguished Name along with the other parameters specified with the
     47  * {@link Builder}.
     48  * <p>
     49  * The self-signed X.509 certificate may be replaced at a later time by a
     50  * certificate signed by a real Certificate Authority.
     51  */
     52 public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     53     private final String mKeystoreAlias;
     54 
     55     private final Context mContext;
     56 
     57     private final X500Principal mSubjectDN;
     58 
     59     private final BigInteger mSerialNumber;
     60 
     61     private final Date mStartDate;
     62 
     63     private final Date mEndDate;
     64 
     65     private final int mFlags;
     66 
     67     /**
     68      * Parameter specification for the "{@code AndroidKeyPairGenerator}"
     69      * instance of the {@link java.security.KeyPairGenerator} API. The
     70      * {@code context} passed in may be used to pop up some UI to ask the user
     71      * to unlock or initialize the Android keystore facility.
     72      * <p>
     73      * After generation, the {@code keyStoreAlias} is used with the
     74      * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
     75      * interface to retrieve the {@link PrivateKey} and its associated
     76      * {@link Certificate} chain.
     77      * <p>
     78      * The KeyPair generator will create a self-signed certificate with the
     79      * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name
     80      * and as its X.509v3 Issuer Distinguished Name, using the specified
     81      * {@code serialNumber}, and the validity date starting at {@code startDate}
     82      * and ending at {@code endDate}.
     83      *
     84      * @param context Android context for the activity
     85      * @param keyStoreAlias name to use for the generated key in the Android
     86      *            keystore
     87      * @param subjectDN X.509 v3 Subject Distinguished Name
     88      * @param serialNumber X509 v3 certificate serial number
     89      * @param startDate the start of the self-signed certificate validity period
     90      * @param endDate the end date of the self-signed certificate validity
     91      *            period
     92      * @throws IllegalArgumentException when any argument is {@code null} or
     93      *             {@code endDate} is before {@code startDate}.
     94      * @hide should be built with KeyPairGeneratorSpecBuilder
     95      */
     96     public KeyPairGeneratorSpec(Context context, String keyStoreAlias,
     97             X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate,
     98             int flags) {
     99         if (context == null) {
    100             throw new IllegalArgumentException("context == null");
    101         } else if (TextUtils.isEmpty(keyStoreAlias)) {
    102             throw new IllegalArgumentException("keyStoreAlias must not be empty");
    103         } else if (subjectDN == null) {
    104             throw new IllegalArgumentException("subjectDN == null");
    105         } else if (serialNumber == null) {
    106             throw new IllegalArgumentException("serialNumber == null");
    107         } else if (startDate == null) {
    108             throw new IllegalArgumentException("startDate == null");
    109         } else if (endDate == null) {
    110             throw new IllegalArgumentException("endDate == null");
    111         } else if (endDate.before(startDate)) {
    112             throw new IllegalArgumentException("endDate < startDate");
    113         }
    114 
    115         mContext = context;
    116         mKeystoreAlias = keyStoreAlias;
    117         mSubjectDN = subjectDN;
    118         mSerialNumber = serialNumber;
    119         mStartDate = startDate;
    120         mEndDate = endDate;
    121         mFlags = flags;
    122     }
    123 
    124     /**
    125      * Returns the alias that will be used in the {@code java.security.KeyStore}
    126      * in conjunction with the {@code AndroidKeyStore}.
    127      */
    128     public String getKeystoreAlias() {
    129         return mKeystoreAlias;
    130     }
    131 
    132     /**
    133      * Gets the Android context used for operations with this instance.
    134      */
    135     public Context getContext() {
    136         return mContext;
    137     }
    138 
    139     /**
    140      * Gets the subject distinguished name to be used on the X.509 certificate
    141      * that will be put in the {@link java.security.KeyStore}.
    142      */
    143     public X500Principal getSubjectDN() {
    144         return mSubjectDN;
    145     }
    146 
    147     /**
    148      * Gets the serial number to be used on the X.509 certificate that will be
    149      * put in the {@link java.security.KeyStore}.
    150      */
    151     public BigInteger getSerialNumber() {
    152         return mSerialNumber;
    153     }
    154 
    155     /**
    156      * Gets the start date to be used on the X.509 certificate that will be put
    157      * in the {@link java.security.KeyStore}.
    158      */
    159     public Date getStartDate() {
    160         return mStartDate;
    161     }
    162 
    163     /**
    164      * Gets the end date to be used on the X.509 certificate that will be put in
    165      * the {@link java.security.KeyStore}.
    166      */
    167     public Date getEndDate() {
    168         return mEndDate;
    169     }
    170 
    171     /**
    172      * @hide
    173      */
    174     int getFlags() {
    175         return mFlags;
    176     }
    177 
    178     /**
    179      * Returns {@code true} if this parameter will require generated keys to be
    180      * encrypted in the {@link java.security.KeyStore}.
    181      */
    182     public boolean isEncryptionRequired() {
    183         return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
    184     }
    185 
    186     /**
    187      * Builder class for {@link KeyPairGeneratorSpec} objects.
    188      * <p>
    189      * This will build a parameter spec for use with the <a href="{@docRoot}
    190      * guide/topics/security/keystore.html">Android KeyStore facility</a>.
    191      * <p>
    192      * The required fields must be filled in with the builder.
    193      * <p>
    194      * Example:
    195      *
    196      * <pre class="prettyprint">
    197      * Calendar start = new Calendar();
    198      * Calendar end = new Calendar();
    199      * end.add(1, Calendar.YEAR);
    200      *
    201      * KeyPairGeneratorSpec spec =
    202      *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
    203      *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
    204      *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
    205      * </pre>
    206      */
    207     public final static class Builder {
    208         private final Context mContext;
    209 
    210         private String mKeystoreAlias;
    211 
    212         private X500Principal mSubjectDN;
    213 
    214         private BigInteger mSerialNumber;
    215 
    216         private Date mStartDate;
    217 
    218         private Date mEndDate;
    219 
    220         private int mFlags;
    221 
    222         /**
    223          * Creates a new instance of the {@code Builder} with the given
    224          * {@code context}. The {@code context} passed in may be used to pop up
    225          * some UI to ask the user to unlock or initialize the Android KeyStore
    226          * facility.
    227          */
    228         public Builder(Context context) {
    229             if (context == null) {
    230                 throw new NullPointerException("context == null");
    231             }
    232             mContext = context;
    233         }
    234 
    235         /**
    236          * Sets the alias to be used to retrieve the key later from a
    237          * {@link java.security.KeyStore} instance using the
    238          * {@code AndroidKeyStore} provider.
    239          */
    240         public Builder setAlias(String alias) {
    241             if (alias == null) {
    242                 throw new NullPointerException("alias == null");
    243             }
    244             mKeystoreAlias = alias;
    245             return this;
    246         }
    247 
    248         /**
    249          * Sets the subject used for the self-signed certificate of the
    250          * generated key pair.
    251          */
    252         public Builder setSubject(X500Principal subject) {
    253             if (subject == null) {
    254                 throw new NullPointerException("subject == null");
    255             }
    256             mSubjectDN = subject;
    257             return this;
    258         }
    259 
    260         /**
    261          * Sets the serial number used for the self-signed certificate of the
    262          * generated key pair.
    263          */
    264         public Builder setSerialNumber(BigInteger serialNumber) {
    265             if (serialNumber == null) {
    266                 throw new NullPointerException("serialNumber == null");
    267             }
    268             mSerialNumber = serialNumber;
    269             return this;
    270         }
    271 
    272         /**
    273          * Sets the start of the validity period for the self-signed certificate
    274          * of the generated key pair.
    275          */
    276         public Builder setStartDate(Date startDate) {
    277             if (startDate == null) {
    278                 throw new NullPointerException("startDate == null");
    279             }
    280             mStartDate = startDate;
    281             return this;
    282         }
    283 
    284         /**
    285          * Sets the end of the validity period for the self-signed certificate
    286          * of the generated key pair.
    287          */
    288         public Builder setEndDate(Date endDate) {
    289             if (endDate == null) {
    290                 throw new NullPointerException("endDate == null");
    291             }
    292             mEndDate = endDate;
    293             return this;
    294         }
    295 
    296         /**
    297          * Indicates that this key must be encrypted at rest on storage. Note
    298          * that enabling this will require that the user enable a strong lock
    299          * screen (e.g., PIN, password) before creating or using the generated
    300          * key is successful.
    301          */
    302         public Builder setEncryptionRequired() {
    303             mFlags |= KeyStore.FLAG_ENCRYPTED;
    304             return this;
    305         }
    306 
    307         /**
    308          * Builds the instance of the {@code KeyPairGeneratorSpec}.
    309          *
    310          * @throws IllegalArgumentException if a required field is missing
    311          * @return built instance of {@code KeyPairGeneratorSpec}
    312          */
    313         public KeyPairGeneratorSpec build() {
    314             return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
    315                     mSerialNumber, mStartDate, mEndDate, mFlags);
    316         }
    317     }
    318 }
    319