1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "x509_distinguished_name.h"
17 #include "x509_distinguished_name_spi.h"
18 
19 #include <securec.h>
20 
21 #include "config.h"
22 #include "cf_log.h"
23 #include "cf_memory.h"
24 #include "utils.h"
25 #include "x509_distinguished_name_openssl.h"
26 
27 #define HCF_X509_DISTINGUISHED_NAME_CLASS "HcfX509DistinguishedName"
28 typedef CfResult (*HcfX509DistinguishedNameSpiCreateFunc)(const CfBlob *, const bool, HcfX509DistinguishedNameSpi **);
29 
30 typedef struct {
31     HcfX509DistinguishedName base;
32     HcfX509DistinguishedNameSpi *spiObj;
33     const char *certType;
34 } HcfX509DistinguishedNameImpl;
35 
36 typedef struct {
37     HcfX509DistinguishedNameSpiCreateFunc createFunc;
38 } HcfX509DistinguishedNameFuncSet;
39 
40 typedef struct {
41     char *certType;
42     HcfX509DistinguishedNameFuncSet funcSet;
43 } HcfDistiNameFactoryAbility;
44 
GetX509DistinguishedNameClass(void)45 static const char *GetX509DistinguishedNameClass(void)
46 {
47     return HCF_X509_DISTINGUISHED_NAME_CLASS;
48 }
49 
50 static const HcfDistiNameFactoryAbility X509_DISTINGUISHED_NAME_ABILITY_SET[] = {
51     { "X509DistinguishedName", { OpensslX509DistinguishedNameSpiCreate, } }
52 };
53 
FindAbility(const char * certType)54 static const HcfX509DistinguishedNameFuncSet *FindAbility(const char *certType)
55 {
56     if (certType == NULL) {
57         LOGE("CertType is null!");
58         return NULL;
59     }
60     for (uint32_t i = 0; i < sizeof(X509_DISTINGUISHED_NAME_ABILITY_SET) / sizeof(HcfDistiNameFactoryAbility); i++) {
61         if (strcmp(X509_DISTINGUISHED_NAME_ABILITY_SET[i].certType, certType) == 0) {
62             return &(X509_DISTINGUISHED_NAME_ABILITY_SET[i].funcSet);
63         }
64     }
65     LOGE("Cert not support! [cert]: %s", certType);
66     return NULL;
67 }
68 
DestroyX509DistinguishedName(CfObjectBase * self)69 static void DestroyX509DistinguishedName(CfObjectBase *self)
70 {
71     if (self == NULL) {
72         LOGE("Invalid input parameter.");
73         return;
74     }
75     if (!CfIsClassMatch(self, GetX509DistinguishedNameClass())) {
76         LOGE("Class is not match.");
77         return;
78     }
79     HcfX509DistinguishedNameImpl *impl = (HcfX509DistinguishedNameImpl *)self;
80     CfObjDestroy(impl->spiObj);
81     CfFree(impl);
82 }
83 
GetEncoded(HcfX509DistinguishedName * self,CfEncodingBlob * out)84 static CfResult GetEncoded(HcfX509DistinguishedName *self, CfEncodingBlob *out)
85 {
86     if ((self == NULL) || (out == NULL)) {
87         LOGE("Invalid input parameter.");
88         return CF_INVALID_PARAMS;
89     }
90     if (!CfIsClassMatch((CfObjectBase *)self, GetX509DistinguishedNameClass())) {
91         LOGE("Class is not match.");
92         return CF_INVALID_PARAMS;
93     }
94     return ((HcfX509DistinguishedNameImpl *)self)->spiObj->engineGetEncode(
95         ((HcfX509DistinguishedNameImpl *)self)->spiObj, out);
96 }
97 
GetName(HcfX509DistinguishedName * self,CfBlob * type,CfBlob * out,CfArray * outArr)98 static CfResult GetName(HcfX509DistinguishedName *self, CfBlob *type, CfBlob *out, CfArray *outArr)
99 {
100     if (self == NULL) {
101         LOGE("Invalid input parameter.");
102         return CF_INVALID_PARAMS;
103     }
104     if (!CfIsClassMatch((CfObjectBase *)self, GetX509DistinguishedNameClass())) {
105         LOGE("Class is not match.");
106         return CF_INVALID_PARAMS;
107     }
108     return ((HcfX509DistinguishedNameImpl *)self)->spiObj->engineGetName(
109         ((HcfX509DistinguishedNameImpl *)self)->spiObj, type, out, outArr);
110 }
111 
HcfX509DistinguishedNameCreate(const CfBlob * inStream,bool bString,HcfX509DistinguishedName ** returnObj)112 CfResult HcfX509DistinguishedNameCreate(const CfBlob *inStream, bool bString, HcfX509DistinguishedName **returnObj)
113 {
114     if ((inStream == NULL) || (returnObj == NULL)) {
115         return CF_INVALID_PARAMS;
116     }
117     const HcfX509DistinguishedNameFuncSet *funcSet = FindAbility("X509DistinguishedName");
118     if (funcSet == NULL) {
119         return CF_NOT_SUPPORT;
120     }
121     HcfX509DistinguishedNameSpi *spiObj = NULL;
122     CfResult res = funcSet->createFunc(inStream, bString, &spiObj);
123     if (res != CF_SUCCESS) {
124         LOGE("Failed to create spi object!");
125         return res;
126     }
127     HcfX509DistinguishedNameImpl *x509NameImpl =
128         (HcfX509DistinguishedNameImpl *)CfMalloc(sizeof(HcfX509DistinguishedNameImpl), 0);
129     if (x509NameImpl == NULL) {
130         LOGE("Failed to allocate x509DistinguishedNameImpl memory!");
131         CfObjDestroy(spiObj);
132         return CF_ERR_MALLOC;
133     }
134     x509NameImpl->base.base.getClass = GetX509DistinguishedNameClass;
135     x509NameImpl->base.base.destroy = DestroyX509DistinguishedName;
136     x509NameImpl->base.getEncode = GetEncoded;
137     x509NameImpl->base.getName = GetName;
138     x509NameImpl->spiObj = spiObj;
139     *returnObj = (HcfX509DistinguishedName *)x509NameImpl;
140     return CF_SUCCESS;
141 }