3 * @author David Llewellyn-Jones
11 * @section DESCRIPTION
24 #include <openssl/crypto.h>
25 #include <openssl/rand.h>
26 #include <openssl/err.h>
28 #include "contrac/log.h"
29 #include "contrac/utils.h"
30 #include "contrac/rpi.h"
32 #include "contrac/contrac.h"
36 #define STATUS_TK (1 << 0)
37 #define STATUS_DTK (1 << 1)
38 #define STATUS_RPI (1 << 2)
40 #define STATUS_INITIALISED (STATUS_TK | STATUS_DTK | STATUS_RPI)
45 unsigned char tk
[TK_SIZE
];
48 // Rolling proximity identifier
52 uint8_t time_interval_number
;
57 // Function prototypes
59 // Function definitions
61 Contrac
* contrac_new() {
64 data
= calloc(sizeof(Contrac
), 1);
65 data
->dtk
= dtk_new();
66 data
->rpi
= rpi_new();
71 void contrac_delete(Contrac
* data
) {
73 dtk_delete(data
->dtk
);
74 rpi_delete(data
->rpi
);
76 // Clear the data for security
77 memset(data
, 0, sizeof(Contrac
));
83 bool contrac_generate_tracing_key(Contrac
* data
) {
87 result
= RAND_bytes(data
->tk
, TK_SIZE
);
90 data
->status
|= STATUS_TK
;
93 LOG(LOG_ERR
, "Error generating tracing key: %lu\n", ERR_get_error());
99 bool contrac_set_day_number(Contrac
* data
, uint32_t day_number
) {
102 result
= ((data
->status
& STATUS_TK
) != 0);
105 result
= contrac_generate_daily_key(data
->dtk
, data
, day_number
);
109 data
->day_number
= day_number
;
110 data
->status
|= STATUS_DTK
;
116 bool contrac_set_time_interval_number(Contrac
* data
, uint8_t time_interval_number
) {
119 result
= ((data
->status
& STATUS_DTK
) != 0);
122 result
= rpi_generate_proximity_id(data
->rpi
, data
->dtk
, time_interval_number
);
126 data
->time_interval_number
= time_interval_number
;
127 data
->status
|= STATUS_RPI
;
133 bool contrac_get_initialised(Contrac
const * data
) {
134 return ((data
->status
& STATUS_INITIALISED
) == STATUS_INITIALISED
);
137 void contrac_set_tracing_key(Contrac
* data
, unsigned char const * tracing_key
) {
138 memcpy(data
->tk
, tracing_key
, TK_SIZE
);
139 data
->status
|= STATUS_TK
;
142 const unsigned char * contrac_get_tracing_key(Contrac
const * data
) {
146 // base64 buffer must be at least 45 bytes (TK_SIZE_BASE64 + 1)
147 void contrac_get_tracing_key_base64(Contrac
const * data
, char * base64
) {
148 size_t size
= TK_SIZE_BASE64
+ 1;
149 base64_encode_binary_to_base64(data
->tk
, TK_SIZE
, (unsigned char *)base64
, &size
);
151 if (size
!= (TK_SIZE_BASE64
+ 1)) {
152 LOG(LOG_ERR
, "Base64 tracing key has incorrect size of %d bytes.\n", size
);
156 // tracing_key input must be 44 bytes long
157 bool contrac_set_tracing_key_base64(Contrac
* data
, char const * tracing_key
) {
159 unsigned char tk
[TK_SIZE
];
162 if (strlen(tracing_key
) != TK_SIZE_BASE64
) {
163 LOG(LOG_ERR
, "Base64 tracing key has incorrect size. Should be %d bytes.\n", TK_SIZE_BASE64
);
169 base64_decode_base64_to_binary((unsigned char *)tracing_key
, TK_SIZE_BASE64
, tk
, &size
);
171 if (size
< TK_SIZE
) {
172 LOG(LOG_ERR
, "Base64 tracking key output is too short %d bytes.\n", size
);
178 contrac_set_tracing_key(data
, tk
);
184 const unsigned char * contrac_get_daily_key(Contrac
const * data
) {
185 return dtk_get_daily_key(data
->dtk
);
188 // base64 buffer must be at least 25 bytes (DTK_SIZE_BASE64 + 1)
189 void contrac_get_daily_key_base64(Contrac
const * data
, char * base64
) {
190 size_t size
= DTK_SIZE_BASE64
+ 1;
191 base64_encode_binary_to_base64(dtk_get_daily_key(data
->dtk
), DTK_SIZE
, (unsigned char *)base64
, &size
);
193 if (size
!= (DTK_SIZE_BASE64
+ 1)) {
194 LOG(LOG_ERR
, "Base64 daily key has incorrect size of %d bytes.\n", size
);
198 const unsigned char * contrac_get_proximity_id(Contrac
const * data
) {
199 return rpi_get_proximity_id(data
->rpi
);
202 // base64 buffer must be at least 25 bytes (RPI_SIZE_BASE64 + 1)
203 void contrac_get_proximity_id_base64(Contrac
const * data
, char * base64
) {
204 size_t size
= RPI_SIZE_BASE64
+ 1;
205 base64_encode_binary_to_base64(rpi_get_proximity_id(data
->rpi
), RPI_SIZE
, (unsigned char *)base64
, &size
);
207 if (size
!= (RPI_SIZE_BASE64
+ 1)) {
208 LOG(LOG_ERR
, "Base64 proximity id has incorrect size of %d bytes.\n", size
);