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_get_native_cert.h"
14#include "securec.h"
15#include "tee_client_type.h"
16#include "tee_log.h"
17
18#ifdef LOG_TAG
19#undef LOG_TAG
20#endif
21#define LOG_TAG       "teecd_auth"
22#define INVLIAD_PARAM (-1)
23
24static int SetPathToBuf(uint8_t *buffer, uint32_t *len, uint32_t *inputLen, const char *path)
25{
26    int ret = -1;
27    uint32_t num;
28    uint32_t pathLen;
29
30    num     = (uint32_t)strlen(path);
31    pathLen = num;
32
33    if (*inputLen < sizeof(pathLen)) {
34        tloge("buffer overflow for pathLen\n");
35        return ret;
36    }
37
38    ret = memcpy_s(buffer, *inputLen, &pathLen, sizeof(pathLen));
39    if (ret != EOK) {
40        tloge("copy pkgname length failed\n");
41        return ret;
42    }
43
44    buffer    += sizeof(pathLen);
45    *len      += (uint32_t)sizeof(pathLen);
46    *inputLen -= (uint32_t)sizeof(pathLen);
47    ret = -1;
48
49    if (num > *inputLen) {
50        tloge("buffer overflow for path\n");
51        return ret;
52    }
53
54    ret = memcpy_s(buffer, *inputLen, path, num);
55    if (ret != EOK) {
56        tloge("copy pkgname failed\n");
57        return ret;
58    }
59
60    *len      += num;
61    *inputLen -= num;
62
63    return ret;
64}
65
66static int SetUidToBuf(uint8_t *buffer, uint32_t *len, uint32_t *inputLen, unsigned int caUid)
67{
68    int ret = -1;
69    uint32_t pubkeyLen;
70
71    pubkeyLen = sizeof(caUid);
72
73    if (*inputLen < sizeof(pubkeyLen)) {
74        tloge("buffer overflow for pubkeyLen\n");
75        return ret;
76    }
77
78    ret = memcpy_s(buffer, *inputLen, &pubkeyLen, sizeof(pubkeyLen));
79    if (ret != EOK) {
80        tloge("copy uid length failed\n");
81        return ret;
82    }
83
84    buffer    += sizeof(pubkeyLen);
85    *len      += (uint32_t)sizeof(pubkeyLen);
86    *inputLen -= (uint32_t)sizeof(pubkeyLen);
87    ret = -1;
88
89    if (pubkeyLen > *inputLen) {
90        tloge("buffer overflow for pubkey\n");
91        return ret;
92    }
93
94    ret = memcpy_s(buffer, *inputLen, &caUid, pubkeyLen);
95    if (ret != EOK) {
96        tloge("copy uid failed\n");
97        return ret;
98    }
99
100    *len   += pubkeyLen;
101
102    return ret;
103}
104
105static int SetUserInfoToBuf(uint8_t *buffer, uint32_t *len, uint32_t *inputLen, unsigned int caUid)
106{
107    int ret;
108
109    ret = SetUidToBuf(buffer, len, inputLen, caUid);
110    if (ret != 0) {
111        tloge("set uid failed\n");
112    }
113
114    return ret;
115}
116
117int TeeGetNativeCert(int caPid, unsigned int caUid, uint32_t *len, uint8_t *buffer)
118{
119    int ret;
120    char path[MAX_PATH_LENGTH] = { 0 };
121    uint32_t inputLen;
122    bool invalid = (len == NULL) || (buffer == NULL);
123    if (invalid) {
124        tloge("Param error!\n");
125        return INVLIAD_PARAM;
126    }
127    inputLen = *len;
128
129    ret = TeeGetPkgName(caPid, path, sizeof(path));
130    if (ret != 0) {
131        tloge("get ca path failed\n");
132        return ret;
133    }
134
135    *len = 0;
136
137    ret = SetPathToBuf(buffer, len, &inputLen, path);
138    if (ret != 0) {
139        tloge("set path failed\n");
140        return ret;
141    }
142    buffer += (sizeof(uint32_t) + strlen(path));
143
144    return SetUserInfoToBuf(buffer, len, &inputLen, caUid);
145}
146