103c3442f4d0d10987e06f58941948625a573a356pkanwar/*
203c3442f4d0d10987e06f58941948625a573a356pkanwar * Copyright (C) 2017 The Android Open Source Project
303c3442f4d0d10987e06f58941948625a573a356pkanwar *
403c3442f4d0d10987e06f58941948625a573a356pkanwar * Licensed under the Apache License, Version 2.0 (the "License");
503c3442f4d0d10987e06f58941948625a573a356pkanwar * you may not use this file except in compliance with the License.
603c3442f4d0d10987e06f58941948625a573a356pkanwar * You may obtain a copy of the License at
703c3442f4d0d10987e06f58941948625a573a356pkanwar *
803c3442f4d0d10987e06f58941948625a573a356pkanwar *      http://www.apache.org/licenses/LICENSE-2.0
903c3442f4d0d10987e06f58941948625a573a356pkanwar *
1003c3442f4d0d10987e06f58941948625a573a356pkanwar * Unless required by applicable law or agreed to in writing, software
1103c3442f4d0d10987e06f58941948625a573a356pkanwar * distributed under the License is distributed on an "AS IS" BASIS,
1203c3442f4d0d10987e06f58941948625a573a356pkanwar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1303c3442f4d0d10987e06f58941948625a573a356pkanwar * See the License for the specific language governing permissions and
1403c3442f4d0d10987e06f58941948625a573a356pkanwar * limitations under the License.
1503c3442f4d0d10987e06f58941948625a573a356pkanwar */
1603c3442f4d0d10987e06f58941948625a573a356pkanwarpackage android.telephony;
1703c3442f4d0d10987e06f58941948625a573a356pkanwar
1803c3442f4d0d10987e06f58941948625a573a356pkanwarimport android.os.Parcel;
1903c3442f4d0d10987e06f58941948625a573a356pkanwarimport android.os.Parcelable;
206d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwarimport java.util.Date;
2103c3442f4d0d10987e06f58941948625a573a356pkanwarimport android.util.Log;
2203c3442f4d0d10987e06f58941948625a573a356pkanwar
2303c3442f4d0d10987e06f58941948625a573a356pkanwarimport java.security.KeyFactory;
2403c3442f4d0d10987e06f58941948625a573a356pkanwarimport java.security.NoSuchAlgorithmException;
2503c3442f4d0d10987e06f58941948625a573a356pkanwarimport java.security.PublicKey;
2603c3442f4d0d10987e06f58941948625a573a356pkanwarimport java.security.spec.InvalidKeySpecException;
2703c3442f4d0d10987e06f58941948625a573a356pkanwarimport java.security.spec.X509EncodedKeySpec;
2803c3442f4d0d10987e06f58941948625a573a356pkanwar
2903c3442f4d0d10987e06f58941948625a573a356pkanwar/**
3003c3442f4d0d10987e06f58941948625a573a356pkanwar * Class to represent information sent by the carrier, which will be used to encrypt
3103c3442f4d0d10987e06f58941948625a573a356pkanwar * the IMSI + IMPI. The ecryption is being done by WLAN, and the modem.
3203c3442f4d0d10987e06f58941948625a573a356pkanwar *
3303c3442f4d0d10987e06f58941948625a573a356pkanwar * @hide
3403c3442f4d0d10987e06f58941948625a573a356pkanwar */
3503c3442f4d0d10987e06f58941948625a573a356pkanwarpublic final class ImsiEncryptionInfo implements Parcelable {
3603c3442f4d0d10987e06f58941948625a573a356pkanwar
3703c3442f4d0d10987e06f58941948625a573a356pkanwar    private static final String LOG_TAG = "ImsiEncryptionInfo";
3803c3442f4d0d10987e06f58941948625a573a356pkanwar
3903c3442f4d0d10987e06f58941948625a573a356pkanwar
4003c3442f4d0d10987e06f58941948625a573a356pkanwar    private final String mcc;
4103c3442f4d0d10987e06f58941948625a573a356pkanwar    private final String mnc;
4203c3442f4d0d10987e06f58941948625a573a356pkanwar    private final PublicKey publicKey;
4303c3442f4d0d10987e06f58941948625a573a356pkanwar    private final String keyIdentifier;
4403c3442f4d0d10987e06f58941948625a573a356pkanwar    private final int keyType;
456d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar    //Date-Time in UTC when the key will expire.
466d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar    private final Date expirationTime;
4703c3442f4d0d10987e06f58941948625a573a356pkanwar
4803c3442f4d0d10987e06f58941948625a573a356pkanwar    public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
496d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar                              byte[] key, Date expirationTime) {
506d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime);
516d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar    }
526d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar
536d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar    public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
546d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar                              PublicKey publicKey, Date expirationTime) {
556d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        // todo need to validate that ImsiEncryptionInfo is being created with the correct params.
566d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        //      Including validating that the public key is in "X.509" format. This will be done in
576d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        //      a subsequent CL.
5803c3442f4d0d10987e06f58941948625a573a356pkanwar        this.mcc = mcc;
5903c3442f4d0d10987e06f58941948625a573a356pkanwar        this.mnc = mnc;
6003c3442f4d0d10987e06f58941948625a573a356pkanwar        this.keyType = keyType;
6103c3442f4d0d10987e06f58941948625a573a356pkanwar        this.publicKey = publicKey;
6203c3442f4d0d10987e06f58941948625a573a356pkanwar        this.keyIdentifier = keyIdentifier;
636d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        this.expirationTime = expirationTime;
6403c3442f4d0d10987e06f58941948625a573a356pkanwar    }
6503c3442f4d0d10987e06f58941948625a573a356pkanwar
6603c3442f4d0d10987e06f58941948625a573a356pkanwar    public ImsiEncryptionInfo(Parcel in) {
6703c3442f4d0d10987e06f58941948625a573a356pkanwar        int length = in.readInt();
6803c3442f4d0d10987e06f58941948625a573a356pkanwar        byte b[] = new byte[length];
6903c3442f4d0d10987e06f58941948625a573a356pkanwar        in.readByteArray(b);
7003c3442f4d0d10987e06f58941948625a573a356pkanwar        publicKey = makeKeyObject(b);
7103c3442f4d0d10987e06f58941948625a573a356pkanwar        mcc = in.readString();
7203c3442f4d0d10987e06f58941948625a573a356pkanwar        mnc = in.readString();
7303c3442f4d0d10987e06f58941948625a573a356pkanwar        keyIdentifier = in.readString();
7403c3442f4d0d10987e06f58941948625a573a356pkanwar        keyType = in.readInt();
756d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        expirationTime = new Date(in.readLong());
7603c3442f4d0d10987e06f58941948625a573a356pkanwar    }
7703c3442f4d0d10987e06f58941948625a573a356pkanwar
7803c3442f4d0d10987e06f58941948625a573a356pkanwar    public String getMnc() {
7903c3442f4d0d10987e06f58941948625a573a356pkanwar        return this.mnc;
8003c3442f4d0d10987e06f58941948625a573a356pkanwar    }
8103c3442f4d0d10987e06f58941948625a573a356pkanwar
8203c3442f4d0d10987e06f58941948625a573a356pkanwar    public String getMcc() {
8303c3442f4d0d10987e06f58941948625a573a356pkanwar        return this.mcc;
8403c3442f4d0d10987e06f58941948625a573a356pkanwar    }
8503c3442f4d0d10987e06f58941948625a573a356pkanwar
8603c3442f4d0d10987e06f58941948625a573a356pkanwar    public String getKeyIdentifier() {
8703c3442f4d0d10987e06f58941948625a573a356pkanwar        return this.keyIdentifier;
8803c3442f4d0d10987e06f58941948625a573a356pkanwar    }
8903c3442f4d0d10987e06f58941948625a573a356pkanwar
9003c3442f4d0d10987e06f58941948625a573a356pkanwar    public int getKeyType() {
9103c3442f4d0d10987e06f58941948625a573a356pkanwar        return this.keyType;
9203c3442f4d0d10987e06f58941948625a573a356pkanwar    }
9303c3442f4d0d10987e06f58941948625a573a356pkanwar
9403c3442f4d0d10987e06f58941948625a573a356pkanwar    public PublicKey getPublicKey() {
9503c3442f4d0d10987e06f58941948625a573a356pkanwar        return this.publicKey;
9603c3442f4d0d10987e06f58941948625a573a356pkanwar    }
9703c3442f4d0d10987e06f58941948625a573a356pkanwar
986d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar    public Date getExpirationTime() {
996d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        return this.expirationTime;
1006d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar    }
1016d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar
10203c3442f4d0d10987e06f58941948625a573a356pkanwar    private static PublicKey makeKeyObject(byte[] publicKeyBytes) {
10303c3442f4d0d10987e06f58941948625a573a356pkanwar        try {
10403c3442f4d0d10987e06f58941948625a573a356pkanwar            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
10503c3442f4d0d10987e06f58941948625a573a356pkanwar            return KeyFactory.getInstance("RSA").generatePublic(pubKeySpec);
10603c3442f4d0d10987e06f58941948625a573a356pkanwar        } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
10703c3442f4d0d10987e06f58941948625a573a356pkanwar            Log.e(LOG_TAG, "Error makeKeyObject: unable to convert into PublicKey", ex);
10803c3442f4d0d10987e06f58941948625a573a356pkanwar        }
1096d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        throw new IllegalArgumentException();
11003c3442f4d0d10987e06f58941948625a573a356pkanwar    }
11103c3442f4d0d10987e06f58941948625a573a356pkanwar
11203c3442f4d0d10987e06f58941948625a573a356pkanwar    /** Implement the Parcelable interface */
11303c3442f4d0d10987e06f58941948625a573a356pkanwar    @Override
11403c3442f4d0d10987e06f58941948625a573a356pkanwar    public int describeContents() {
11503c3442f4d0d10987e06f58941948625a573a356pkanwar        return 0;
11603c3442f4d0d10987e06f58941948625a573a356pkanwar    }
11703c3442f4d0d10987e06f58941948625a573a356pkanwar
11803c3442f4d0d10987e06f58941948625a573a356pkanwar    public static final Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
11903c3442f4d0d10987e06f58941948625a573a356pkanwar            new Parcelable.Creator<ImsiEncryptionInfo>() {
12003c3442f4d0d10987e06f58941948625a573a356pkanwar                @Override
12103c3442f4d0d10987e06f58941948625a573a356pkanwar                public ImsiEncryptionInfo createFromParcel(Parcel in) {
12203c3442f4d0d10987e06f58941948625a573a356pkanwar                    return new ImsiEncryptionInfo(in);
12303c3442f4d0d10987e06f58941948625a573a356pkanwar                }
12403c3442f4d0d10987e06f58941948625a573a356pkanwar
12503c3442f4d0d10987e06f58941948625a573a356pkanwar                @Override
12603c3442f4d0d10987e06f58941948625a573a356pkanwar                public ImsiEncryptionInfo[] newArray(int size) {
12703c3442f4d0d10987e06f58941948625a573a356pkanwar                    return new ImsiEncryptionInfo[size];
12803c3442f4d0d10987e06f58941948625a573a356pkanwar                }
12903c3442f4d0d10987e06f58941948625a573a356pkanwar            };
13003c3442f4d0d10987e06f58941948625a573a356pkanwar
13103c3442f4d0d10987e06f58941948625a573a356pkanwar    @Override
13203c3442f4d0d10987e06f58941948625a573a356pkanwar    public void writeToParcel(Parcel dest, int flags) {
13303c3442f4d0d10987e06f58941948625a573a356pkanwar        byte[] b = publicKey.getEncoded();
13403c3442f4d0d10987e06f58941948625a573a356pkanwar        dest.writeInt(b.length);
13503c3442f4d0d10987e06f58941948625a573a356pkanwar        dest.writeByteArray(b);
13603c3442f4d0d10987e06f58941948625a573a356pkanwar        dest.writeString(mcc);
13703c3442f4d0d10987e06f58941948625a573a356pkanwar        dest.writeString(mnc);
13803c3442f4d0d10987e06f58941948625a573a356pkanwar        dest.writeString(keyIdentifier);
13903c3442f4d0d10987e06f58941948625a573a356pkanwar        dest.writeInt(keyType);
1406d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar        dest.writeLong(expirationTime.getTime());
14103c3442f4d0d10987e06f58941948625a573a356pkanwar    }
14203c3442f4d0d10987e06f58941948625a573a356pkanwar
14303c3442f4d0d10987e06f58941948625a573a356pkanwar    @Override
14403c3442f4d0d10987e06f58941948625a573a356pkanwar    public String toString(){
14503c3442f4d0d10987e06f58941948625a573a356pkanwar        return "[ImsiEncryptionInfo "
14603c3442f4d0d10987e06f58941948625a573a356pkanwar                + "mcc=" + mcc
14703c3442f4d0d10987e06f58941948625a573a356pkanwar                + "mnc=" + mnc
14803c3442f4d0d10987e06f58941948625a573a356pkanwar                + "publicKey=" + publicKey
14903c3442f4d0d10987e06f58941948625a573a356pkanwar                + ", keyIdentifier=" + keyIdentifier
15003c3442f4d0d10987e06f58941948625a573a356pkanwar                + ", keyType=" + keyType
1516d50fec388cf382a1f0a4886fe5cea16280f5bdfpkanwar                + ", expirationTime=" + expirationTime
15203c3442f4d0d10987e06f58941948625a573a356pkanwar                + "]";
15303c3442f4d0d10987e06f58941948625a573a356pkanwar    }
15403c3442f4d0d10987e06f58941948625a573a356pkanwar}
155