1e656c62eSopenharmony_ci/*
2e656c62eSopenharmony_ci * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3e656c62eSopenharmony_ci * Licensed under the Mulan PSL v2.
4e656c62eSopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2.
5e656c62eSopenharmony_ci * You may obtain a copy of Mulan PSL v2 at:
6e656c62eSopenharmony_ci *     http://license.coscl.org.cn/MulanPSL2
7e656c62eSopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8e656c62eSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9e656c62eSopenharmony_ci * PURPOSE.
10e656c62eSopenharmony_ci * See the Mulan PSL v2 for more details.
11e656c62eSopenharmony_ci */
12e656c62eSopenharmony_ci
13e656c62eSopenharmony_ci#include "tee_ca_auth.h"
14e656c62eSopenharmony_ci#include <sys/ioctl.h> /* for ioctl */
15e656c62eSopenharmony_ci#include "securec.h"
16e656c62eSopenharmony_ci#include "tc_ns_client.h"
17e656c62eSopenharmony_ci#include "tee_client_type.h"
18e656c62eSopenharmony_ci#include "tee_log.h"
19e656c62eSopenharmony_ci#include "tee_auth_common.h"
20e656c62eSopenharmony_ci#include "tee_get_native_cert.h"
21e656c62eSopenharmony_ci#include "tee_ca_daemon.h"
22e656c62eSopenharmony_ci
23e656c62eSopenharmony_ci#ifdef LOG_TAG
24e656c62eSopenharmony_ci#undef LOG_TAG
25e656c62eSopenharmony_ci#endif
26e656c62eSopenharmony_ci#define LOG_TAG "teecd_auth"
27e656c62eSopenharmony_ci
28e656c62eSopenharmony_cistatic int GetLoginInfo(const struct ucred *cr, int fd, uint8_t *buf, unsigned int bufLen)
29e656c62eSopenharmony_ci{
30e656c62eSopenharmony_ci    int ret;
31e656c62eSopenharmony_ci
32e656c62eSopenharmony_ci    ret = TeeGetNativeCert(cr->pid, cr->uid, &bufLen, buf);
33e656c62eSopenharmony_ci    if (ret != 0) {
34e656c62eSopenharmony_ci        tloge("CERT check failed<%d>\n", ret);
35e656c62eSopenharmony_ci        /* Inform the driver the cert could not be set */
36e656c62eSopenharmony_ci        ret = ioctl(fd, TC_NS_CLIENT_IOCTL_LOGIN, NULL);
37e656c62eSopenharmony_ci        if (ret != 0) {
38e656c62eSopenharmony_ci            tloge("Failed to set login information for client err=%d!\n", ret);
39e656c62eSopenharmony_ci        }
40e656c62eSopenharmony_ci        return -1;
41e656c62eSopenharmony_ci    }
42e656c62eSopenharmony_ci
43e656c62eSopenharmony_ci    return ret;
44e656c62eSopenharmony_ci}
45e656c62eSopenharmony_ci
46e656c62eSopenharmony_ciint SendLoginInfo(const struct ucred *cr, const CaRevMsg *caRevInfo, int fd)
47e656c62eSopenharmony_ci{
48e656c62eSopenharmony_ci    int ret;
49e656c62eSopenharmony_ci    unsigned int bufLen = BUF_MAX_SIZE;
50e656c62eSopenharmony_ci
51e656c62eSopenharmony_ci    if (cr == NULL || caRevInfo == NULL) {
52e656c62eSopenharmony_ci        tloge("bad parameters\n");
53e656c62eSopenharmony_ci        return -1;
54e656c62eSopenharmony_ci    }
55e656c62eSopenharmony_ci
56e656c62eSopenharmony_ci    uint8_t *buf = (uint8_t *)malloc(bufLen);
57e656c62eSopenharmony_ci    if (buf == NULL) {
58e656c62eSopenharmony_ci        tloge("malloc fail.\n");
59e656c62eSopenharmony_ci        return -1;
60e656c62eSopenharmony_ci    }
61e656c62eSopenharmony_ci    ret = memset_s(buf, bufLen, 0, bufLen);
62e656c62eSopenharmony_ci    if (ret != EOK) {
63e656c62eSopenharmony_ci        tloge("memset failed, ret=0x%x\n", ret);
64e656c62eSopenharmony_ci        goto END;
65e656c62eSopenharmony_ci    }
66e656c62eSopenharmony_ci
67e656c62eSopenharmony_ci    ret = GetLoginInfo(cr, fd, buf, bufLen);
68e656c62eSopenharmony_ci    if (ret != 0) {
69e656c62eSopenharmony_ci        tloge("get cert failed\n");
70e656c62eSopenharmony_ci        goto END;
71e656c62eSopenharmony_ci    }
72e656c62eSopenharmony_ci
73e656c62eSopenharmony_ci    ret = ioctl(fd, TC_NS_CLIENT_IOCTL_LOGIN, buf);
74e656c62eSopenharmony_ci    if (ret != 0) {
75e656c62eSopenharmony_ci        tloge("Failed set login info for client err=%d!\n", ret);
76e656c62eSopenharmony_ci    }
77e656c62eSopenharmony_ci
78e656c62eSopenharmony_ciEND:
79e656c62eSopenharmony_ci    free(buf);
80e656c62eSopenharmony_ci    return ret;
81e656c62eSopenharmony_ci}
82e656c62eSopenharmony_ci
83e656c62eSopenharmony_ciint RecvCaMsg(int socket, CaRevMsg *caInfo)
84e656c62eSopenharmony_ci{
85e656c62eSopenharmony_ci    struct iovec iov[1];
86e656c62eSopenharmony_ci    struct msghdr message;
87e656c62eSopenharmony_ci    fd_set fds;
88e656c62eSopenharmony_ci    struct timeval timeout = { 3, 0 }; /* 3s timeout */
89e656c62eSopenharmony_ci    int ret;
90e656c62eSopenharmony_ci
91e656c62eSopenharmony_ci    if (caInfo == NULL) {
92e656c62eSopenharmony_ci        tloge("bad parameter\n");
93e656c62eSopenharmony_ci        return -1;
94e656c62eSopenharmony_ci    }
95e656c62eSopenharmony_ci
96e656c62eSopenharmony_ci    errno_t rc = memset_s(&message, sizeof(message), 0, sizeof(struct msghdr));
97e656c62eSopenharmony_ci    if (rc != EOK) {
98e656c62eSopenharmony_ci        tloge("message memset_s failed\n");
99e656c62eSopenharmony_ci        return -1;
100e656c62eSopenharmony_ci    }
101e656c62eSopenharmony_ci
102e656c62eSopenharmony_ci    message.msg_name            = NULL;
103e656c62eSopenharmony_ci    message.msg_namelen         = 0;
104e656c62eSopenharmony_ci    message.msg_flags           = 0;
105e656c62eSopenharmony_ci    message.msg_iov             = iov;
106e656c62eSopenharmony_ci    message.msg_iovlen          = 1;
107e656c62eSopenharmony_ci    message.msg_control         = NULL;
108e656c62eSopenharmony_ci    message.msg_controllen      = 0;
109e656c62eSopenharmony_ci    message.msg_iov[0].iov_base = caInfo;
110e656c62eSopenharmony_ci    message.msg_iov[0].iov_len  = sizeof(CaRevMsg);
111e656c62eSopenharmony_ci
112e656c62eSopenharmony_ci    FD_ZERO(&fds);
113e656c62eSopenharmony_ci    FD_SET(socket, &fds);
114e656c62eSopenharmony_ci    ret = select(socket + 1, &fds, NULL, NULL, &timeout);
115e656c62eSopenharmony_ci    if (ret <= 0) {
116e656c62eSopenharmony_ci        tloge("teecd socket timeout or err, err=%d.\n", errno);
117e656c62eSopenharmony_ci        return -1;
118e656c62eSopenharmony_ci    }
119e656c62eSopenharmony_ci    ret = (int)recvmsg(socket, &message, 0);
120e656c62eSopenharmony_ci    if (ret <= 0) {
121e656c62eSopenharmony_ci        tloge("tee ca daemon recvmsg failed. \n");
122e656c62eSopenharmony_ci        return -1;
123e656c62eSopenharmony_ci    }
124e656c62eSopenharmony_ci    return 0;
125e656c62eSopenharmony_ci}