1 /*
2  * Copyright (C) 2015 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 com.android.internal.widget;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 import android.service.gatekeeper.GateKeeperResponse;
22 import android.util.Slog;
23 
24 /**
25  * Response object for a ILockSettings credential verification request.
26  * @hide
27  */
28 public final class VerifyCredentialResponse implements Parcelable {
29 
30     public static final int RESPONSE_ERROR = -1;
31     public static final int RESPONSE_OK = 0;
32     public static final int RESPONSE_RETRY = 1;
33 
34     public static final VerifyCredentialResponse OK = new VerifyCredentialResponse();
35     public static final VerifyCredentialResponse ERROR
36             = new VerifyCredentialResponse(RESPONSE_ERROR, 0, null);
37     private static final String TAG = "VerifyCredentialResponse";
38 
39     private int mResponseCode;
40     private byte[] mPayload;
41     private int mTimeout;
42 
43     public static final Parcelable.Creator<VerifyCredentialResponse> CREATOR
44             = new Parcelable.Creator<VerifyCredentialResponse>() {
45         @Override
46         public VerifyCredentialResponse createFromParcel(Parcel source) {
47             int responseCode = source.readInt();
48             VerifyCredentialResponse response = new VerifyCredentialResponse(responseCode, 0, null);
49             if (responseCode == RESPONSE_RETRY) {
50                 response.setTimeout(source.readInt());
51             } else if (responseCode == RESPONSE_OK) {
52                 int size = source.readInt();
53                 if (size > 0) {
54                     byte[] payload = new byte[size];
55                     source.readByteArray(payload);
56                     response.setPayload(payload);
57                 }
58             }
59             return response;
60         }
61 
62         @Override
63         public VerifyCredentialResponse[] newArray(int size) {
64             return new VerifyCredentialResponse[size];
65         }
66 
67     };
68 
VerifyCredentialResponse()69     public VerifyCredentialResponse() {
70         mResponseCode = RESPONSE_OK;
71         mPayload = null;
72     }
73 
74 
VerifyCredentialResponse(byte[] payload)75     public VerifyCredentialResponse(byte[] payload) {
76         mPayload = payload;
77         mResponseCode = RESPONSE_OK;
78     }
79 
VerifyCredentialResponse(int timeout)80     public VerifyCredentialResponse(int timeout) {
81         mTimeout = timeout;
82         mResponseCode = RESPONSE_RETRY;
83         mPayload = null;
84     }
85 
VerifyCredentialResponse(int responseCode, int timeout, byte[] payload)86     private VerifyCredentialResponse(int responseCode, int timeout, byte[] payload) {
87         mResponseCode = responseCode;
88         mTimeout = timeout;
89         mPayload = payload;
90     }
91 
92     @Override
writeToParcel(Parcel dest, int flags)93     public void writeToParcel(Parcel dest, int flags) {
94         dest.writeInt(mResponseCode);
95         if (mResponseCode == RESPONSE_RETRY) {
96             dest.writeInt(mTimeout);
97         } else if (mResponseCode == RESPONSE_OK) {
98             if (mPayload != null) {
99                 dest.writeInt(mPayload.length);
100                 dest.writeByteArray(mPayload);
101             } else {
102                 dest.writeInt(0);
103             }
104         }
105     }
106 
107     @Override
describeContents()108     public int describeContents() {
109         return 0;
110     }
111 
getPayload()112     public byte[] getPayload() {
113         return mPayload;
114     }
115 
getTimeout()116     public int getTimeout() {
117         return mTimeout;
118     }
119 
getResponseCode()120     public int getResponseCode() {
121         return mResponseCode;
122     }
123 
setTimeout(int timeout)124     private void setTimeout(int timeout) {
125         mTimeout = timeout;
126     }
127 
setPayload(byte[] payload)128     private void setPayload(byte[] payload) {
129         mPayload = payload;
130     }
131 
stripPayload()132     public VerifyCredentialResponse stripPayload() {
133         return new VerifyCredentialResponse(mResponseCode, mTimeout, new byte[0]);
134     }
135 
fromGateKeeperResponse( GateKeeperResponse gateKeeperResponse)136     public static VerifyCredentialResponse fromGateKeeperResponse(
137             GateKeeperResponse gateKeeperResponse) {
138         VerifyCredentialResponse response;
139         int responseCode = gateKeeperResponse.getResponseCode();
140         if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
141             response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
142         } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
143             byte[] token = gateKeeperResponse.getPayload();
144             if (token == null) {
145                 // something's wrong if there's no payload with a challenge
146                 Slog.e(TAG, "verifyChallenge response had no associated payload");
147                 response = VerifyCredentialResponse.ERROR;
148             } else {
149                 response = new VerifyCredentialResponse(token);
150             }
151         } else {
152             response = VerifyCredentialResponse.ERROR;
153         }
154         return response;
155     }
156 }
157