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 
GetLoginInfo(const struct ucred * cr,int fd,uint8_t * buf,unsigned int bufLen)28 static 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 
SendLoginInfo(const struct ucred * cr,const CaRevMsg * caRevInfo,int fd)46 int 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 
78 END:
79     free(buf);
80     return ret;
81 }
82 
RecvCaMsg(int socket,CaRevMsg * caInfo)83 int 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 }