blob: 95cfc732f4d32661436af540e2a8319558394c4b [file] [log] [blame]
Andres Moralesac808182015-02-26 14:11:04 -08001/*
2 * Copyright 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 <sys/time.h>
17
18#include <keyguard/google_keyguard.h>
19
20namespace keyguard {
21
22GoogleKeyguard::~GoogleKeyguard() {
23 if (password_key_) {
24 memset_s(password_key_.get(), 0, sizeof(password_key_.get()) / sizeof(password_key_[0]));
25 }
26}
27
28void GoogleKeyguard::Enroll(const EnrollRequest &request, EnrollResponse *response) {
29 if (response == NULL) return;
30
31 SizedBuffer enrolled_password;
32 const SizedBuffer *provided_password = request.GetProvidedPassword();
33 if (provided_password == NULL || !provided_password->buffer) {
34 response->SetError(KG_ERROR_INVALID);
35 return;
36 }
37 enrolled_password.buffer = ComputeSignature(password_key_.get(),
38 provided_password->buffer.get(), provided_password->length, &enrolled_password.length);
39 response->SetEnrolledPasswordHandle(&enrolled_password);
40}
41
42void GoogleKeyguard::Verify(const VerifyRequest &request, VerifyResponse *response) {
43 if (response == NULL) return;
44
45 const SizedBuffer *enrolled_password = request.GetPasswordHandle();
46 const SizedBuffer *provided_password = request.GetProvidedPassword();
47
48
49 if (provided_password == NULL || !provided_password->buffer
50 || enrolled_password == NULL || !enrolled_password->buffer) {
51 response->SetError(KG_ERROR_INVALID);
52 return;
53 }
54
55 SizedBuffer signed_provided_password;
56 signed_provided_password.buffer = ComputeSignature(password_key_.get(),
57 provided_password->buffer.get(), provided_password->length,
58 &signed_provided_password.length);
59 if (memcmp_s(enrolled_password->buffer.get(), signed_provided_password.buffer.get(),
60 enrolled_password->length) == 0) {
61 // Signature matches
62 SizedBuffer auth_token;
63 auth_token.buffer = MintAuthToken(request.GetUserId(), &auth_token.length);
64 response->SetVerificationToken(&auth_token);
65 } else {
66 response->SetError(KG_ERROR_INVALID);
67 }
68}
69
70std::unique_ptr<uint8_t> GoogleKeyguard::MintAuthToken(uint32_t user_id, size_t *length) {
71 AuthToken *auth_token = new AuthToken;
72 SizedBuffer serialized_auth_token;
73
74 struct timeval time;
75 gettimeofday(&time, NULL);
76
77 auth_token->auth_token_size = sizeof(AuthToken) -
78 sizeof(auth_token->auth_token_tag) - sizeof(auth_token->auth_token_size);
79 auth_token->user_id = user_id;
80 auth_token->timestamp = static_cast<uint64_t>(time.tv_sec);
81
82 size_t hash_len = (size_t)((uint8_t *)&auth_token->hmac_tag - (uint8_t *)auth_token);
83 size_t signature_len;
84 std::unique_ptr<uint8_t> signature = ComputeSignature(GetAuthTokenKey().get(),
85 reinterpret_cast<uint8_t *>(auth_token), hash_len, &signature_len);
86
87 memcpy(&auth_token->hmac, signature.get(), sizeof(auth_token->hmac));
88 if (length != NULL) *length = sizeof(AuthToken);
89 std::unique_ptr<uint8_t> result(reinterpret_cast<uint8_t *>(auth_token));
90 return result;
91}
92}