1 /***************************************************************************/ /**
2  * @file
3  * @brief
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 #include "sl_status.h"
31 #include "sl_net.h"
32 #include "sl_si91x_driver.h"
33 #include "sl_wifi_credentials.h"
34 
35 /// Enumerations of TLS certificate types
36 typedef enum {
37   SL_SI91X_EAP_CLIENT             = 1,  ///< SL_SI91X_EAP_CLIENT
38   SL_SI91X_FAST_PAC_FILE          = 2,  ///< SL_SI91X_FAST_PAC_FILE
39   SL_SI91X_TLS_CLIENT             = 3,  ///< SL_SI91X_TLS_CLIENT
40   SL_SI91X_TLS_CLIENT_PRIVATE_KEY = 4,  ///< SL_SI91X_TLS_CLIENT_PRIVATE_KEY
41   SL_SI91X_TLS_CA_CERTIFICATE     = 5,  ///< SL_SI91X_TLS_CA_CERTIFICATE
42   SL_SI91X_TLS_SERVER_CERTIFICATE = 6,  ///< SL_SI91X_TLS_SERVER_CERTIFICATE
43   SL_SI91X_TLS_SERVER_PRIVATE_KEY = 7,  ///< SL_SI91X_TLS_SERVER_PRIVATE_KEY
44   SL_SI91X_EAP_PRIVATE_KEY        = 17, ///< SL_SI91X_EAP_PRIVATE_KEY
45   SL_SI91X_EAP_PUBLIC_KEY         = 33, ///< SL_SI91X_EAP_PUBLIC_KEY
46   SL_SI91X_EAP_CA_CERTIFICATE     = 49, ///< SL_SI91X_EAP_CA_CERTIFICATE
47 } sl_si91x_cert_type_t;
48 
49 /******************************************************
50  *               Function Declarations
51  ******************************************************/
52 sl_status_t sl_si91x_set_credential(sl_net_credential_id_t id,
53                                     sl_net_credential_type_t type,
54                                     const void *credential,
55                                     uint32_t credential_length);
56 sl_status_t sl_si91x_get_credential(sl_net_credential_id_t id,
57                                     const sl_net_credential_type_t *type,
58                                     const void *credential,
59                                     const uint32_t *credential_length);
60 sl_status_t sl_si91x_delete_credential(sl_net_credential_id_t id, sl_net_credential_type_t type);
61 
convert_to_si91x_cert_type(sl_net_credential_id_t id,sl_net_credential_type_t type)62 static sl_si91x_cert_type_t convert_to_si91x_cert_type(sl_net_credential_id_t id, sl_net_credential_type_t type)
63 {
64   switch (type) {
65     case SL_NET_SIGNING_CERTIFICATE:
66       if ((id == SL_NET_WIFI_EAP_SERVER_CREDENTIAL_ID) || (id == SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID)) {
67         return SL_SI91X_EAP_CA_CERTIFICATE;
68       }
69       if ((id & SL_NET_CREDENTIAL_GROUP_MASK) == SL_NET_TLS_SERVER_CREDENTIAL_START) {
70         return SL_SI91X_TLS_CA_CERTIFICATE;
71       }
72       break;
73 
74     case SL_NET_CERTIFICATE:
75       if (id == SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID) {
76         return SL_SI91X_EAP_CLIENT;
77       }
78 
79       switch (id & SL_NET_CREDENTIAL_GROUP_MASK) {
80         case SL_NET_TLS_CLIENT_CREDENTIAL_START:
81           return SL_SI91X_TLS_CLIENT;
82         case SL_NET_TLS_SERVER_CREDENTIAL_START:
83           return SL_SI91X_TLS_SERVER_CERTIFICATE;
84         default:
85           break;
86       }
87       break;
88 
89     case SL_NET_PUBLIC_KEY:
90       if (id == SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID) {
91         return SL_SI91X_EAP_PUBLIC_KEY;
92       }
93       break;
94 
95     case SL_NET_PRIVATE_KEY:
96       if (id == SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID) {
97         return SL_SI91X_EAP_PRIVATE_KEY;
98       }
99       switch (id & SL_NET_CREDENTIAL_GROUP_MASK) {
100         case SL_NET_TLS_CLIENT_CREDENTIAL_START:
101           return SL_SI91X_TLS_CLIENT_PRIVATE_KEY;
102         case SL_NET_TLS_SERVER_CREDENTIAL_START:
103           return SL_SI91X_TLS_SERVER_PRIVATE_KEY;
104         default:
105           break;
106       }
107       break;
108     case SL_NET_PACK_FILE:
109       if (id == SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID) {
110         return SL_SI91X_FAST_PAC_FILE;
111       }
112       break;
113     default:
114       return 0;
115   }
116 
117   return 0;
118 }
119 
get_certificate_index(sl_net_credential_id_t id)120 static uint8_t get_certificate_index(sl_net_credential_id_t id)
121 {
122   if ((id & SL_NET_CREDENTIAL_GROUP_MASK) != 0) {
123     return ((uint8_t)id & 0xFF);
124   }
125   switch (id) {
126     case SL_NET_WIFI_EAP_CLIENT_CREDENTIAL_ID:
127     case SL_NET_WIFI_EAP_SERVER_CREDENTIAL_ID:
128       return 0;
129 
130     default:
131       break;
132   }
133   return -1;
134 }
135 
sl_si91x_set_credential(sl_net_credential_id_t id,sl_net_credential_type_t type,const void * credential,uint32_t credential_length)136 sl_status_t sl_si91x_set_credential(sl_net_credential_id_t id,
137                                     sl_net_credential_type_t type,
138                                     const void *credential,
139                                     uint32_t credential_length)
140 {
141   sl_status_t status;
142   sl_si91x_cert_type_t cert_type = convert_to_si91x_cert_type(id, type);
143   uint8_t index                  = get_certificate_index(id);
144 
145   // Clear the certificate
146   status = sl_si91x_wifi_set_certificate_index((uint8_t)cert_type, index, NULL, 0);
147 
148   VERIFY_STATUS_AND_RETURN(status);
149   // Set the certificate
150   status = sl_si91x_wifi_set_certificate_index((uint8_t)cert_type, index, credential, credential_length);
151 
152   return status;
153 }
154 
sl_si91x_get_credential(sl_net_credential_id_t id,const sl_net_credential_type_t * type,const void * credential,const uint32_t * credential_length)155 sl_status_t sl_si91x_get_credential(sl_net_credential_id_t id,
156                                     const sl_net_credential_type_t *type,
157                                     const void *credential,
158                                     const uint32_t *credential_length)
159 {
160   UNUSED_PARAMETER(id);
161   UNUSED_PARAMETER(type);
162   UNUSED_PARAMETER(credential);
163   UNUSED_PARAMETER(credential_length);
164   return SL_STATUS_NOT_SUPPORTED;
165 }
166 
sl_si91x_delete_credential(sl_net_credential_id_t id,sl_net_credential_type_t type)167 sl_status_t sl_si91x_delete_credential(sl_net_credential_id_t id, sl_net_credential_type_t type)
168 {
169   sl_si91x_cert_type_t cert_type = convert_to_si91x_cert_type(id, type);
170   uint8_t index                  = get_certificate_index(id);
171 
172   // Clear the certificate
173   return sl_si91x_wifi_set_certificate_index((uint8_t)cert_type, index, NULL, 0);
174 }
175