1 /*
2 * Copyright (c) 2018, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file implements the OpenThread CoAP Secure API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
37
38 #include <openthread/coap_secure.h>
39 #include <openthread/ip6.h>
40
41 #include "coap/coap_message.hpp"
42 #include "coap/coap_secure.hpp"
43 #include "common/instance.hpp"
44 #include "common/locator_getters.hpp"
45
46 using namespace ot;
47
otCoapSecureStart(otInstance * aInstance,uint16_t aPort)48 otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort)
49 {
50 Instance &instance = *static_cast<Instance *>(aInstance);
51
52 return instance.GetApplicationCoapSecure().Start(aPort);
53 }
54
55 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
otCoapSecureSetCertificate(otInstance * aInstance,const uint8_t * aX509Cert,uint32_t aX509Length,const uint8_t * aPrivateKey,uint32_t aPrivateKeyLength)56 void otCoapSecureSetCertificate(otInstance * aInstance,
57 const uint8_t *aX509Cert,
58 uint32_t aX509Length,
59 const uint8_t *aPrivateKey,
60 uint32_t aPrivateKeyLength)
61 {
62 Instance &instance = *static_cast<Instance *>(aInstance);
63
64 OT_ASSERT(aX509Cert != nullptr && aX509Length != 0 && aPrivateKey != nullptr && aPrivateKeyLength != 0);
65
66 instance.GetApplicationCoapSecure().SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
67 }
68
otCoapSecureSetCaCertificateChain(otInstance * aInstance,const uint8_t * aX509CaCertificateChain,uint32_t aX509CaCertChainLength)69 void otCoapSecureSetCaCertificateChain(otInstance * aInstance,
70 const uint8_t *aX509CaCertificateChain,
71 uint32_t aX509CaCertChainLength)
72 {
73 Instance &instance = *static_cast<Instance *>(aInstance);
74
75 OT_ASSERT(aX509CaCertificateChain != nullptr && aX509CaCertChainLength != 0);
76
77 instance.GetApplicationCoapSecure().SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
78 }
79 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
80
81 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
otCoapSecureSetPsk(otInstance * aInstance,const uint8_t * aPsk,uint16_t aPskLength,const uint8_t * aPskIdentity,uint16_t aPskIdLength)82 void otCoapSecureSetPsk(otInstance * aInstance,
83 const uint8_t *aPsk,
84 uint16_t aPskLength,
85 const uint8_t *aPskIdentity,
86 uint16_t aPskIdLength)
87 {
88 Instance &instance = *static_cast<Instance *>(aInstance);
89
90 OT_ASSERT(aPsk != nullptr && aPskLength != 0 && aPskIdentity != nullptr && aPskIdLength != 0);
91
92 instance.GetApplicationCoapSecure().SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
93 }
94 #endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
95
96 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
otCoapSecureGetPeerCertificateBase64(otInstance * aInstance,unsigned char * aPeerCert,size_t * aCertLength,size_t aCertBufferSize)97 otError otCoapSecureGetPeerCertificateBase64(otInstance * aInstance,
98 unsigned char *aPeerCert,
99 size_t * aCertLength,
100 size_t aCertBufferSize)
101 {
102 Instance &instance = *static_cast<Instance *>(aInstance);
103
104 return instance.GetApplicationCoapSecure().GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
105 }
106 #endif // defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
107
otCoapSecureSetSslAuthMode(otInstance * aInstance,bool aVerifyPeerCertificate)108 void otCoapSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate)
109 {
110 Instance &instance = *static_cast<Instance *>(aInstance);
111
112 instance.GetApplicationCoapSecure().SetSslAuthMode(aVerifyPeerCertificate);
113 }
114
otCoapSecureConnect(otInstance * aInstance,const otSockAddr * aSockAddr,otHandleCoapSecureClientConnect aHandler,void * aContext)115 otError otCoapSecureConnect(otInstance * aInstance,
116 const otSockAddr * aSockAddr,
117 otHandleCoapSecureClientConnect aHandler,
118 void * aContext)
119 {
120 Instance &instance = *static_cast<Instance *>(aInstance);
121
122 return instance.GetApplicationCoapSecure().Connect(*static_cast<const Ip6::SockAddr *>(aSockAddr), aHandler,
123 aContext);
124 }
125
otCoapSecureDisconnect(otInstance * aInstance)126 void otCoapSecureDisconnect(otInstance *aInstance)
127 {
128 Instance &instance = *static_cast<Instance *>(aInstance);
129
130 instance.GetApplicationCoapSecure().Disconnect();
131 }
132
otCoapSecureIsConnected(otInstance * aInstance)133 bool otCoapSecureIsConnected(otInstance *aInstance)
134 {
135 Instance &instance = *static_cast<Instance *>(aInstance);
136
137 return instance.GetApplicationCoapSecure().IsConnected();
138 }
139
otCoapSecureIsConnectionActive(otInstance * aInstance)140 bool otCoapSecureIsConnectionActive(otInstance *aInstance)
141 {
142 Instance &instance = *static_cast<Instance *>(aInstance);
143
144 return instance.GetApplicationCoapSecure().IsConnectionActive();
145 }
146
otCoapSecureStop(otInstance * aInstance)147 void otCoapSecureStop(otInstance *aInstance)
148 {
149 Instance &instance = *static_cast<Instance *>(aInstance);
150
151 instance.GetApplicationCoapSecure().Stop();
152 }
153
154 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSecureSendRequestBlockWise(otInstance * aInstance,otMessage * aMessage,otCoapResponseHandler aHandler,void * aContext,otCoapBlockwiseTransmitHook aTransmitHook,otCoapBlockwiseReceiveHook aReceiveHook)155 otError otCoapSecureSendRequestBlockWise(otInstance * aInstance,
156 otMessage * aMessage,
157 otCoapResponseHandler aHandler,
158 void * aContext,
159 otCoapBlockwiseTransmitHook aTransmitHook,
160 otCoapBlockwiseReceiveHook aReceiveHook)
161 {
162 Instance &instance = *static_cast<Instance *>(aInstance);
163
164 return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Coap::Message *>(aMessage), aHandler, aContext,
165 aTransmitHook, aReceiveHook);
166 }
167 #endif
168
otCoapSecureSendRequest(otInstance * aInstance,otMessage * aMessage,otCoapResponseHandler aHandler,void * aContext)169 otError otCoapSecureSendRequest(otInstance * aInstance,
170 otMessage * aMessage,
171 otCoapResponseHandler aHandler,
172 void * aContext)
173 {
174 Instance &instance = *static_cast<Instance *>(aInstance);
175
176 return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Coap::Message *>(aMessage), aHandler, aContext);
177 }
178
179 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSecureAddBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)180 void otCoapSecureAddBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
181 {
182 Instance &instance = *static_cast<Instance *>(aInstance);
183
184 instance.GetApplicationCoapSecure().AddBlockWiseResource(*static_cast<Coap::ResourceBlockWise *>(aResource));
185 }
186
otCoapSecureRemoveBlockWiseResource(otInstance * aInstance,otCoapBlockwiseResource * aResource)187 void otCoapSecureRemoveBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource)
188 {
189 Instance &instance = *static_cast<Instance *>(aInstance);
190
191 instance.GetApplicationCoapSecure().RemoveBlockWiseResource(*static_cast<Coap::ResourceBlockWise *>(aResource));
192 }
193 #endif
194
otCoapSecureAddResource(otInstance * aInstance,otCoapResource * aResource)195 void otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource)
196 {
197 Instance &instance = *static_cast<Instance *>(aInstance);
198
199 instance.GetApplicationCoapSecure().AddResource(*static_cast<Coap::Resource *>(aResource));
200 }
201
otCoapSecureRemoveResource(otInstance * aInstance,otCoapResource * aResource)202 void otCoapSecureRemoveResource(otInstance *aInstance, otCoapResource *aResource)
203 {
204 Instance &instance = *static_cast<Instance *>(aInstance);
205
206 instance.GetApplicationCoapSecure().RemoveResource(*static_cast<Coap::Resource *>(aResource));
207 }
208
otCoapSecureSetClientConnectedCallback(otInstance * aInstance,otHandleCoapSecureClientConnect aHandler,void * aContext)209 void otCoapSecureSetClientConnectedCallback(otInstance * aInstance,
210 otHandleCoapSecureClientConnect aHandler,
211 void * aContext)
212 {
213 Instance &instance = *static_cast<Instance *>(aInstance);
214
215 instance.GetApplicationCoapSecure().SetClientConnectedCallback(aHandler, aContext);
216 }
217
otCoapSecureSetDefaultHandler(otInstance * aInstance,otCoapRequestHandler aHandler,void * aContext)218 void otCoapSecureSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
219 {
220 Instance &instance = *static_cast<Instance *>(aInstance);
221
222 instance.GetApplicationCoapSecure().SetDefaultHandler(aHandler, aContext);
223 }
224
225 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otCoapSecureSendResponseBlockWise(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo,void * aContext,otCoapBlockwiseTransmitHook aTransmitHook)226 otError otCoapSecureSendResponseBlockWise(otInstance * aInstance,
227 otMessage * aMessage,
228 const otMessageInfo * aMessageInfo,
229 void * aContext,
230 otCoapBlockwiseTransmitHook aTransmitHook)
231 {
232 Instance &instance = *static_cast<Instance *>(aInstance);
233
234 return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Coap::Message *>(aMessage),
235 *static_cast<const Ip6::MessageInfo *>(aMessageInfo),
236 nullptr, aContext, aTransmitHook);
237 }
238 #endif
239
otCoapSecureSendResponse(otInstance * aInstance,otMessage * aMessage,const otMessageInfo * aMessageInfo)240 otError otCoapSecureSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo)
241 {
242 Instance &instance = *static_cast<Instance *>(aInstance);
243
244 return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Coap::Message *>(aMessage),
245 *static_cast<const Ip6::MessageInfo *>(aMessageInfo));
246 }
247
248 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
249