MHEG5  18.9.0
MHEG5 Documentation
mh5tls.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2010 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
29 
30 #include "mh5profile.h"
31 #include "mh5tls.h"
32 #include "mh5memory.h"
33 #include "http_interface.h"
34 #include "mh5fileorm.h"
35 #include "stb_os.h"
36 
37 /*---constant definitions for this file--------------------------------------*/
38 #define TLS_CERT_TIMEOUT (24 * 60 * 60 * 1000)
39 #define MAX_TLS_CERT_NAME (22)
40 #define MAX_CALLBACKS (5)
41 
42 /*#define TLS_DEBUG_PRINT*/
43 
44 #ifdef TLS_DEBUG_PRINT
45 #define PRINT(x) DBG_PRINTF x
46 #else
47 #define PRINT(x)
48 #endif
49 
50 
51 /*---local typedef structs for this file-------------------------------------*/
52 /* Enumerated type to tell the state of the TLS certificate refresh process */
53 typedef enum
54 {
60 
61 /*---local (static) variable declarations for this file----------------------*/
62 static void(*tlsCallback[MAX_CALLBACKS]) (void);
63 static U16BIT callbackCount = 0;
64 static U32BIT lastCertStoreUpdate = 0;
65 static MHEG5Int lastRequestNumber = 0;
66 static MHEG5Bool lastRequestFailed = MHEG5FALSE;
67 static TlsCertRefreshState certRequestState = TLS_CERT_STATE_VALID;
68 
69 
70 /*---local function prototypes for this file---------------------------------*/
71 static MHEG5Bool IsTimeToUpdate(void);
72 static void ClearTlsCertStore(void);
73 static void TlsCertRetrieved( void *userData, S_CONTENT *content );
74 static void AddCertificates( U8BIT *certData, U32BIT certLen );
75 static void TlsCertRetrievalFailed( void *userData );
76 static void NotifyTlsReady(void);
77 
78 /*---global function definitions---------------------------------------------*/
79 
87 {
88  ClearTlsCertStore();
89 }
90 
96 {
97  ClearTlsCertStore();
98 
99  if (certRequestState == TLS_CERT_STATE_ASYNC)
100  {
101  /* A certificate has been requested - need to make sure it doesn't
102  * actually get used
103  */
104  certRequestState = TLS_CERT_STATE_INVALID;
105  }
106 }
107 
113 {
114  U32BIT count;
115 
116  count = httpGetTlsCertStoreCount();
117 
118  return count;
119 }
120 
127 {
129  MHEG5Int currentRequestNumber;
130  char name[MAX_TLS_CERT_NAME];
131  MHEG5String requestName;
132 
134 
135  if (lastRequestFailed)
136  {
137  /* Certificate store is still valid, no point in trying again */
139  }
140 
141  if (certRequestState == TLS_CERT_STATE_VALID)
142  {
143  if (IsTimeToUpdate())
144  {
145  ClearTlsCertStore();
146  }
147 
148  if (!lastRequestFailed)
149  {
150  certRequestState = TLS_CERT_STATE_SYNC;
151 
152  currentRequestNumber = lastRequestNumber;
153  sprintf(name, "DSM://auth.tls.%ld", lastRequestNumber + 1);
154  requestName.data = (U8BIT *)name;
155  requestName.len = strlen(name);
156  (void)MHEG5FileOrmGet( requestName, FRP_CERT | FRP_CACHE_DEFAULT, NULL,
157  TlsCertRetrieved, TlsCertRetrievalFailed);
158 
159  if (certRequestState == TLS_CERT_STATE_VALID)
160  {
161  if (currentRequestNumber == lastRequestNumber)
162  {
163  /* No new certificates, request failed */
165  }
166  else
167  {
168  /* Something new to test, request succeeded */
170  }
171  }
172  else
173  {
174  /* The request is not valid, so it was asynchronous */
175  certRequestState = TLS_CERT_STATE_ASYNC;
176  }
177  }
178  }
179 
180  return status;
181 }
182 
189 void MHEG5AddTlsCertificateCallback(void (*loadCallback)(void))
190 {
191  if (callbackCount < MAX_CALLBACKS)
192  {
193  tlsCallback[callbackCount] = loadCallback;
194  callbackCount++;
195  }
196 }
197 
198 /*---local function definitions----------------------------------------------*/
199 
200 
205 static MHEG5Bool IsTimeToUpdate(void)
206 {
207  MHEG5Bool timeToUpdate;
208  U32BIT currentTime;
209 
210  timeToUpdate = FALSE;
211 
212  /* Check if TLS certificates should be updated */
213  currentTime = STB_OSGetClockMilliseconds();
214  if (lastCertStoreUpdate == 0)
215  {
216  timeToUpdate = TRUE;
217  }
218  else if ((currentTime > lastCertStoreUpdate) &&
219  (currentTime - lastCertStoreUpdate) > TLS_CERT_TIMEOUT)
220  {
221  timeToUpdate = TRUE;
222  }
223  else if (currentTime < lastCertStoreUpdate)
224  {
225  /* overflow */
226  timeToUpdate = TRUE;
227  }
228 
229  return timeToUpdate;
230 }
231 
236 static void ClearTlsCertStore(void)
237 {
239  lastCertStoreUpdate = 0;
240  lastRequestNumber = 0;
241  lastRequestFailed = MHEG5FALSE;
242 }
243 
254 static void TlsCertRetrieved( void *userData, S_CONTENT *content )
255 {
256  USE_UNWANTED_PARAM(userData);
257 
258  if (certRequestState == TLS_CERT_STATE_INVALID)
259  {
260  /* Certificate store has been invalidated - ignore the file and
261  * call the TLS callback
262  */
263  certRequestState = TLS_CERT_STATE_VALID;
264  NotifyTlsReady();
265  }
266  else if (certRequestState != TLS_CERT_STATE_VALID)
267  {
268  /* Request is still active, update HTTP module */
269  AddCertificates( content->data, content->size );
270 
271  /* Update state */
272  ++lastRequestNumber;
273 
274  /* Call TLS callback, but only if response was asynchronous */
275  if (certRequestState == TLS_CERT_STATE_ASYNC)
276  {
277  NotifyTlsReady();
278  }
279 
280  certRequestState = TLS_CERT_STATE_VALID;
281  }
282 }
283 
290 static void AddCertificates(U8BIT *certData, U32BIT certLen)
291 {
292  U32BIT size;
293  U16BIT count;
294 
295  count = 0;
296  if (certLen > 2)
297  {
298  count = certData[0] << 8 | certData[1];
299  }
300 
301  /* TLS certificate files should only contain a single certificate */
302  if (count == 1)
303  {
304  if (certLen >= 5)
305  {
306  size = (certData[2] << 16 | certData[3] << 8 | certData[4]);
307  if (size + 5 == certLen)
308  {
309  httpAddTlsCertToStore(certData + 5, size);
310  }
311  else
312  {
313  /* invalid size */
314 #ifdef TLS_DEBUG
315  DBG_PRINTF("Invalid certificate size\n");
316 #endif
317  }
318  }
319  else
320  {
321  /* invalid certificate file length */
322 #ifdef TLS_DEBUG
323  DBG_PRINTF("Invalid certificate file length\n");
324 #endif
325  }
326  }
327 
328  if (lastRequestNumber == 0)
329  {
330  /* First request, remember update time (even if invalid certificate) */
331  lastCertStoreUpdate = STB_OSGetClockMilliseconds();
332  }
333 }
334 
342 void TlsCertRetrievalFailed(void *userData)
343 {
344  USE_UNWANTED_PARAM(userData);
345 
346  if (certRequestState == TLS_CERT_STATE_INVALID)
347  {
348  /* Certificate store has been invalidated - ignore the file and
349  * call the TLS callback
350  */
351  certRequestState = TLS_CERT_STATE_VALID;
352  NotifyTlsReady();
353  }
354  else
355  {
356  lastRequestFailed = MHEG5TRUE;
357  if (lastCertStoreUpdate == 0)
358  {
359  /* First attempt failed - no certificates */
360  lastCertStoreUpdate = STB_OSGetClockMilliseconds();
361  }
362 
363  /* Call TLS callback, but only if response was asynchronous */
364  if (certRequestState == TLS_CERT_STATE_ASYNC)
365  {
366  NotifyTlsReady();
367  }
368  }
369 
370  certRequestState = TLS_CERT_STATE_VALID;
371 }
372 
377 static void NotifyTlsReady(void)
378 {
379  U16BIT i;
380 
381  for (i = 0; i < callbackCount; i++)
382  {
383  if (tlsCallback[i] != NULL)
384  {
385  tlsCallback[i]();
386  }
387  }
388 }
389 
U32BIT STB_OSGetClockMilliseconds(void)
Get Current Computer Clock Time.
#define MAX_TLS_CERT_NAME
Definition: mh5tls.c:39
U32BIT size
Definition: fs_types.h:54
MHEG5TlsCertRequestStatus
Definition: mh5tls.h:37
Manages the interface between MHEG5 Engine and the HTTP component.
MHEG5TlsCertRequestStatus MHEG5GetNextTlsCertificate(void)
Issues a request to load the next TLS certificate from the DSM-CC object carousel.
Definition: mh5tls.c:126
#define DBG_PRINTF(...)
Definition: glue_debug.h:127
void MHEG5InvalidateTlsCertStore(void)
Invalidate the TLS certificate store.
Definition: mh5tls.c:95
#define MAX_CALLBACKS
Definition: mh5tls.c:40
void MHEG5AddTlsCertificateCallback(void(*loadCallback)(void))
Add a callback function to be called when pending requests are resolved.
Definition: mh5tls.c:189
void * MHEG5FileOrmGet(MHEG5String name, U16BIT priority, void *userData, F_CB_Good cbGood, F_CB_Fail cbFail)
Get a file. The file will be loaded and one of the callback functions called when request is resolved...
Definition: mh5fileorm.c:1179
#define FRP_CACHE_DEFAULT
Definition: mh5fileorm.h:38
void MHEG5ClearTlsCertStore(void)
Clear the TLS certificate store.
Definition: mh5tls.c:86
uint8_t U8BIT
Definition: techtype.h:82
long MHEG5Int
Definition: mh5base.h:73
This file defines the profile for the MHEG engine.
#define TLS_CERT_TIMEOUT
Definition: mh5tls.c:38
short MHEG5Bool
Definition: mh5base.h:71
MHEG5Byte * data
Definition: mh5base.h:85
#define MHEG5TRUE
Definition: mh5base.h:49
uint16_t U16BIT
Definition: techtype.h:84
void httpClearTlsCertStore(void)
Clear TLS certificate store.
File interface functions to DSMCC component.
redirection include
#define FALSE
Definition: techtype.h:68
Functions relating to TLS certificate store.
MHEG5Int len
Definition: mh5base.h:84
U8BIT * data
Definition: fs_types.h:55
#define USE_UNWANTED_PARAM(param)
Definition: techtype.h:48
#define TRUE
Definition: techtype.h:69
void httpAddTlsCertToStore(U8BIT *certData, U32BIT certLen)
Add TLS certificate to store.
U32BIT MHEG5GetTlsCertStoreCount(void)
Return number of TLS certificates in the TLS certificate store.
Definition: mh5tls.c:112
U32BIT httpGetTlsCertStoreCount(void)
Return number of TLS certificate in the certificate store.
TlsCertRefreshState
Definition: mh5tls.c:53
#define MHEG5FALSE
Definition: mh5base.h:48
uint32_t U32BIT
Definition: techtype.h:86
#define FRP_CERT
Definition: mh5fileorm.h:46
Header file - Function prototypes for operating system.