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