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