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#include "SoftGateKeeper.h"
17#include "SoftGateKeeperDevice.h"
18
19namespace android {
20
21int SoftGateKeeperDevice::enroll(uint32_t uid,
22            const uint8_t *current_password_handle, uint32_t current_password_handle_length,
23            const uint8_t *current_password, uint32_t current_password_length,
24            const uint8_t *desired_password, uint32_t desired_password_length,
25            uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
26
27    if (enrolled_password_handle == NULL || enrolled_password_handle_length == NULL ||
28            desired_password == NULL || desired_password_length == 0)
29        return -EINVAL;
30
31    // Current password and current password handle go together
32    if (current_password_handle == NULL || current_password_handle_length == 0 ||
33            current_password == NULL || current_password_length == 0) {
34        current_password_handle = NULL;
35        current_password_handle_length = 0;
36        current_password = NULL;
37        current_password_length = 0;
38    }
39
40    SizedBuffer desired_password_buffer(desired_password_length);
41    memcpy(desired_password_buffer.buffer.get(), desired_password, desired_password_length);
42
43    SizedBuffer current_password_handle_buffer(current_password_handle_length);
44    if (current_password_handle) {
45        memcpy(current_password_handle_buffer.buffer.get(), current_password_handle,
46                current_password_handle_length);
47    }
48
49    SizedBuffer current_password_buffer(current_password_length);
50    if (current_password) {
51        memcpy(current_password_buffer.buffer.get(), current_password, current_password_length);
52    }
53
54    EnrollRequest request(uid, &current_password_handle_buffer, &desired_password_buffer,
55            &current_password_buffer);
56    EnrollResponse response;
57
58    impl_->Enroll(request, &response);
59
60    if (response.error == ERROR_RETRY) {
61        return response.retry_timeout;
62    } else if (response.error != ERROR_NONE) {
63        return -EINVAL;
64    }
65
66    *enrolled_password_handle = response.enrolled_password_handle.buffer.release();
67    *enrolled_password_handle_length = response.enrolled_password_handle.length;
68    return 0;
69}
70
71int SoftGateKeeperDevice::verify(uint32_t uid,
72        uint64_t challenge, const uint8_t *enrolled_password_handle,
73        uint32_t enrolled_password_handle_length, const uint8_t *provided_password,
74        uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length,
75        bool *request_reenroll) {
76
77    if (enrolled_password_handle == NULL ||
78            provided_password == NULL) {
79        return -EINVAL;
80    }
81
82    SizedBuffer password_handle_buffer(enrolled_password_handle_length);
83    memcpy(password_handle_buffer.buffer.get(), enrolled_password_handle,
84            enrolled_password_handle_length);
85    SizedBuffer provided_password_buffer(provided_password_length);
86    memcpy(provided_password_buffer.buffer.get(), provided_password, provided_password_length);
87
88    VerifyRequest request(uid, challenge, &password_handle_buffer, &provided_password_buffer);
89    VerifyResponse response;
90
91    impl_->Verify(request, &response);
92
93    if (response.error == ERROR_RETRY) {
94        return response.retry_timeout;
95    } else if (response.error != ERROR_NONE) {
96        return -EINVAL;
97    }
98
99    if (auth_token != NULL && auth_token_length != NULL) {
100       *auth_token = response.auth_token.buffer.release();
101       *auth_token_length = response.auth_token.length;
102    }
103
104    if (request_reenroll != NULL) {
105        *request_reenroll = response.request_reenroll;
106    }
107
108    return 0;
109}
110} // namespace android
111