Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2017 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 package android.telephony;
     17 
     18 import android.os.Parcel;
     19 import android.os.Parcelable;
     20 import java.util.Date;
     21 import android.util.Log;
     22 
     23 import java.security.KeyFactory;
     24 import java.security.NoSuchAlgorithmException;
     25 import java.security.PublicKey;
     26 import java.security.spec.InvalidKeySpecException;
     27 import java.security.spec.X509EncodedKeySpec;
     28 
     29 /**
     30  * Class to represent information sent by the carrier, which will be used to encrypt
     31  * the IMSI + IMPI. The ecryption is being done by WLAN, and the modem.
     32  *
     33  * @hide
     34  */
     35 public final class ImsiEncryptionInfo implements Parcelable {
     36 
     37     private static final String LOG_TAG = "ImsiEncryptionInfo";
     38 
     39 
     40     private final String mcc;
     41     private final String mnc;
     42     private final PublicKey publicKey;
     43     private final String keyIdentifier;
     44     private final int keyType;
     45     //Date-Time in UTC when the key will expire.
     46     private final Date expirationTime;
     47 
     48     public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
     49                               byte[] key, Date expirationTime) {
     50         this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime);
     51     }
     52 
     53     public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
     54                               PublicKey publicKey, Date expirationTime) {
     55         // todo need to validate that ImsiEncryptionInfo is being created with the correct params.
     56         //      Including validating that the public key is in "X.509" format. This will be done in
     57         //      a subsequent CL.
     58         this.mcc = mcc;
     59         this.mnc = mnc;
     60         this.keyType = keyType;
     61         this.publicKey = publicKey;
     62         this.keyIdentifier = keyIdentifier;
     63         this.expirationTime = expirationTime;
     64     }
     65 
     66     public ImsiEncryptionInfo(Parcel in) {
     67         int length = in.readInt();
     68         byte b[] = new byte[length];
     69         in.readByteArray(b);
     70         publicKey = makeKeyObject(b);
     71         mcc = in.readString();
     72         mnc = in.readString();
     73         keyIdentifier = in.readString();
     74         keyType = in.readInt();
     75         expirationTime = new Date(in.readLong());
     76     }
     77 
     78     public String getMnc() {
     79         return this.mnc;
     80     }
     81 
     82     public String getMcc() {
     83         return this.mcc;
     84     }
     85 
     86     public String getKeyIdentifier() {
     87         return this.keyIdentifier;
     88     }
     89 
     90     public int getKeyType() {
     91         return this.keyType;
     92     }
     93 
     94     public PublicKey getPublicKey() {
     95         return this.publicKey;
     96     }
     97 
     98     public Date getExpirationTime() {
     99         return this.expirationTime;
    100     }
    101 
    102     private static PublicKey makeKeyObject(byte[] publicKeyBytes) {
    103         try {
    104             X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
    105             return KeyFactory.getInstance("RSA").generatePublic(pubKeySpec);
    106         } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
    107             Log.e(LOG_TAG, "Error makeKeyObject: unable to convert into PublicKey", ex);
    108         }
    109         throw new IllegalArgumentException();
    110     }
    111 
    112     /** Implement the Parcelable interface */
    113     @Override
    114     public int describeContents() {
    115         return 0;
    116     }
    117 
    118     public static final Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
    119             new Parcelable.Creator<ImsiEncryptionInfo>() {
    120                 @Override
    121                 public ImsiEncryptionInfo createFromParcel(Parcel in) {
    122                     return new ImsiEncryptionInfo(in);
    123                 }
    124 
    125                 @Override
    126                 public ImsiEncryptionInfo[] newArray(int size) {
    127                     return new ImsiEncryptionInfo[size];
    128                 }
    129             };
    130 
    131     @Override
    132     public void writeToParcel(Parcel dest, int flags) {
    133         byte[] b = publicKey.getEncoded();
    134         dest.writeInt(b.length);
    135         dest.writeByteArray(b);
    136         dest.writeString(mcc);
    137         dest.writeString(mnc);
    138         dest.writeString(keyIdentifier);
    139         dest.writeInt(keyType);
    140         dest.writeLong(expirationTime.getTime());
    141     }
    142 
    143     @Override
    144     public String toString(){
    145         return "[ImsiEncryptionInfo "
    146                 + "mcc=" + mcc
    147                 + "mnc=" + mnc
    148                 + "publicKey=" + publicKey
    149                 + ", keyIdentifier=" + keyIdentifier
    150                 + ", keyType=" + keyType
    151                 + ", expirationTime=" + expirationTime
    152                 + "]";
    153     }
    154 }
    155