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