1 /**
2 @file testUtils.c
3
4 @author Johan Pascal
5
6 @copyright Copyright (C) 2014 Belledonne Communications, Grenoble, France
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "testUtils.h"
29 #include "cryptoUtils.h"
30
31 #ifndef _WIN32
32 #if !defined(__QNXNTO__) && !(defined(__ANDROID__) && defined(__LP64__))
33 #include <ctype.h>
34 #include <string.h>
35 #endif
36 #else
37 #include <Windows.h>
38 #endif
39
40
41 int verbose = 0;
42
43 /* trace functions: bzrtp algo code to string */
bzrtp_hash_toString(uint8_t hashAlgo)44 const char *bzrtp_hash_toString(uint8_t hashAlgo) {
45 switch(hashAlgo) {
46 case(ZRTP_UNSET_ALGO): return "unset";
47 case(ZRTP_HASH_S256): return "SHA-256";
48 case(ZRTP_HASH_S384): return "SHA-384";
49 case(ZRTP_HASH_N256): return "SHA3-256";
50 case(ZRTP_HASH_N384): return "SHA3-384";
51 default: return "Unknown Algo";
52 }
53 }
54
bzrtp_keyAgreement_toString(uint8_t keyAgreementAlgo)55 const char *bzrtp_keyAgreement_toString(uint8_t keyAgreementAlgo) {
56 switch(keyAgreementAlgo) {
57 case(ZRTP_UNSET_ALGO): return "unset";
58 case(ZRTP_KEYAGREEMENT_DH2k): return "DHM-2048";
59 case(ZRTP_KEYAGREEMENT_EC25): return "ECDH-256";
60 case(ZRTP_KEYAGREEMENT_DH3k): return "DHM-3072";
61 case(ZRTP_KEYAGREEMENT_EC38): return "ECDH-384";
62 case(ZRTP_KEYAGREEMENT_EC52): return "ECDH-521";
63 case(ZRTP_KEYAGREEMENT_Prsh): return "PreShared";
64 case(ZRTP_KEYAGREEMENT_Mult): return "MultiStream";
65 default: return "Unknown Algo";
66 }
67 }
68
bzrtp_cipher_toString(uint8_t cipherAlgo)69 const char *bzrtp_cipher_toString(uint8_t cipherAlgo) {
70 switch(cipherAlgo) {
71 case(ZRTP_UNSET_ALGO): return "unset";
72 case(ZRTP_CIPHER_AES1): return "AES-128";
73 case(ZRTP_CIPHER_AES2): return "AES-192";
74 case(ZRTP_CIPHER_AES3): return "AES-256";
75 case(ZRTP_CIPHER_2FS1): return "TwoFish-128";
76 case(ZRTP_CIPHER_2FS2): return "TwoFish-192";
77 case(ZRTP_CIPHER_2FS3): return "TwoFish-256";
78 default: return "Unknown Algo";
79 }
80 }
81
bzrtp_authtag_toString(uint8_t authtagAlgo)82 const char *bzrtp_authtag_toString(uint8_t authtagAlgo) {
83 switch(authtagAlgo) {
84 case(ZRTP_UNSET_ALGO): return "unset";
85 case(ZRTP_AUTHTAG_HS32): return "HMAC-SHA1-32";
86 case(ZRTP_AUTHTAG_HS80): return "HMAC-SHA1-80";
87 case(ZRTP_AUTHTAG_SK32): return "Skein-32";
88 case(ZRTP_AUTHTAG_SK64): return "Skein-64";
89 default: return "Unknown Algo";
90 }
91 }
92
bzrtp_sas_toString(uint8_t sasAlgo)93 const char *bzrtp_sas_toString(uint8_t sasAlgo) {
94 switch(sasAlgo) {
95 case(ZRTP_UNSET_ALGO): return "unset";
96 case(ZRTP_SAS_B32): return "Base32";
97 case(ZRTP_SAS_B256): return "PGP-WordList";
98 default: return "Unknown Algo";
99 }
100 }
101
102
bzrtp_message(const char * fmt,...)103 void bzrtp_message(const char *fmt, ...) {
104 if (verbose) {
105 va_list args;
106 va_start(args, fmt);
107 vprintf(fmt, args);
108 va_end(args);
109 fflush(NULL);
110 }
111 }
112
printHex(char * title,uint8_t * data,uint32_t length)113 void printHex(char *title, uint8_t *data, uint32_t length) {
114 if (verbose) {
115 uint32_t i;
116 printf ("%s : ", title);
117 for (i=0; i<length; i++) {
118 printf ("0x%02x, ", data[i]);
119 }
120 printf ("\n");
121 fflush(NULL);
122 }
123 }
124
packetDump(bzrtpPacket_t * zrtpPacket,uint8_t addRawMessage)125 void packetDump(bzrtpPacket_t *zrtpPacket, uint8_t addRawMessage) {
126 if (verbose) {
127 int j;
128 printf ("SSRC %x - Message Length: %d - ", zrtpPacket->sourceIdentifier, zrtpPacket->messageLength);
129 if (zrtpPacket->packetString!=NULL) { /* paquet has been built and we need to get his sequence number in the packetString */
130 printf ("Sequence number: %02x%02x", *(zrtpPacket->packetString+2), *(zrtpPacket->packetString+3));
131 } else { /* packet has been parsed, so get his sequence number in the structure */
132 printf ("Sequence number: %04x", zrtpPacket->sequenceNumber);
133 }
134 switch (zrtpPacket->messageType) {
135 case MSGTYPE_HELLO :
136 {
137 bzrtpHelloMessage_t *messageData;
138 uint8_t algoTypeString[4];
139
140 printf(" - Message Type : Hello\n");
141 messageData = (bzrtpHelloMessage_t *)zrtpPacket->messageData;
142 printf ("Version %.4s\nIdentifier %.16s\n", messageData->version, messageData->clientIdentifier);
143 printHex ("H3", messageData->H3, 32);
144 printHex ("ZID", messageData->ZID, 12);
145 printf ("S : %d - M : %d - P : %d\nhc : %x - cc : %x - ac : %x - kc : %x - sc : %x\n", messageData->S, messageData->M, messageData->P, messageData->hc, messageData->cc, messageData->ac, messageData->kc, messageData->sc);
146 printf ("hc ");
147 for (j=0; j<messageData->hc; j++) {
148 bzrtp_cryptoAlgoTypeIntToString(messageData->supportedHash[j], algoTypeString);
149 printf("%.4s, ", algoTypeString);
150 }
151 printf ("\ncc ");
152 for (j=0; j<messageData->cc; j++) {
153 bzrtp_cryptoAlgoTypeIntToString(messageData->supportedCipher[j], algoTypeString);
154 printf("%.4s, ", algoTypeString);
155 }
156 printf ("\nac ");
157 for (j=0; j<messageData->ac; j++) {
158 bzrtp_cryptoAlgoTypeIntToString(messageData->supportedAuthTag[j], algoTypeString);
159 printf("%.4s, ", algoTypeString);
160 }
161 printf ("\nkc ");
162 for (j=0; j<messageData->kc; j++) {
163 bzrtp_cryptoAlgoTypeIntToString(messageData->supportedKeyAgreement[j], algoTypeString);
164 printf("%.4s, ", algoTypeString);
165 }
166 printf ("\nsc ");
167 for (j=0; j<messageData->sc; j++) {
168 bzrtp_cryptoAlgoTypeIntToString(messageData->supportedSas[j], algoTypeString);
169 printf("%.4s, ", algoTypeString);
170 }
171 printHex("\nMAC", messageData->MAC, 8);
172 }
173
174 break; /* MSGTYPE_HELLO */
175
176 case MSGTYPE_HELLOACK :
177 {
178 printf(" - Message Type : Hello ACK\n");
179 }
180 break;
181
182 case MSGTYPE_COMMIT:
183 {
184 uint8_t algoTypeString[4];
185 bzrtpCommitMessage_t *messageData;
186
187 printf(" - Message Type : Commit\n");
188 messageData = (bzrtpCommitMessage_t *)zrtpPacket->messageData;
189 printHex("H2", messageData->H2, 32);
190 printHex("ZID", messageData->ZID, 12);
191 bzrtp_cryptoAlgoTypeIntToString(messageData->hashAlgo, algoTypeString);
192 printf("Hash Algo: %.4s\n", algoTypeString);
193 bzrtp_cryptoAlgoTypeIntToString(messageData->cipherAlgo, algoTypeString);
194 printf("Cipher Algo: %.4s\n", algoTypeString);
195 bzrtp_cryptoAlgoTypeIntToString(messageData->authTagAlgo, algoTypeString);
196 printf("Auth tag Algo: %.4s\n", algoTypeString);
197 bzrtp_cryptoAlgoTypeIntToString(messageData->keyAgreementAlgo, algoTypeString);
198 printf("Key agreement Algo: %.4s\n", algoTypeString);
199 bzrtp_cryptoAlgoTypeIntToString(messageData->sasAlgo, algoTypeString);
200 printf("Sas Algo: %.4s\n", algoTypeString);
201 /* if it is a multistream or preshared commit, get the 16 bytes nonce */
202 if ((messageData->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Prsh) || (messageData->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Mult)) {
203 printHex("Nonce", messageData->nonce, 16);
204
205 /* and the keyID for preshared commit only */
206 if (messageData->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Prsh) {
207 printHex("KeyId", messageData->keyID, 8);
208 }
209 } else { /* it's a DH commit message, get the hvi */
210 printHex("hvi", messageData->hvi, 32);
211 }
212
213 printHex("\nMAC", messageData->MAC, 8);
214 }
215 break;
216 case MSGTYPE_DHPART1:
217 case MSGTYPE_DHPART2:
218 {
219 bzrtpDHPartMessage_t *messageData;
220
221 if (zrtpPacket->messageType == MSGTYPE_DHPART1) {
222 printf(" - Message Type : DHPart1\n");
223 } else {
224 printf(" - Message Type : DHPart2\n");
225 }
226 messageData = (bzrtpDHPartMessage_t *)zrtpPacket->messageData;
227 printHex ("H1", messageData->H1, 32);
228 printHex ("rs1ID", messageData->rs1ID, 8);
229 printHex ("rs2ID", messageData->rs2ID, 8);
230 printHex ("auxsecretID", messageData->auxsecretID, 8);
231 printHex ("pbxsecretID", messageData->pbxsecretID, 8);
232 printHex ("rs1ID", messageData->rs1ID, 8);
233 printf("PV length is %d\n", (zrtpPacket->messageLength-84));
234 printHex ("PV", messageData->pv, (zrtpPacket->messageLength-84)); /* length of fixed part of the message is 84, rest is the variable length PV */
235 printHex("MAC", messageData->MAC, 8);
236
237 }
238 break;
239 case MSGTYPE_CONFIRM1:
240 case MSGTYPE_CONFIRM2:
241 {
242 bzrtpConfirmMessage_t *messageData;
243
244 if (zrtpPacket->messageType == MSGTYPE_CONFIRM1) {
245 printf(" - Message Type : Confirm1\n");
246 } else {
247 printf(" - Message Type : Confirm2\n");
248 }
249 messageData = (bzrtpConfirmMessage_t *)zrtpPacket->messageData;
250 printHex("H0", messageData->H0, 32);
251 printf("sig_len %d\n", messageData->sig_len);
252 printf("E %d V %d A %d D %d\n", messageData->E, messageData->V, messageData->A, messageData->D);
253 printf("Cache expiration Interval %08x\n", messageData->cacheExpirationInterval);
254 }
255 break;
256 case MSGTYPE_CONF2ACK:
257 {
258 printf(" - Message Type: Conf2ACK\n");
259 }
260 }
261
262 if (addRawMessage) {
263 printHex("Data", zrtpPacket->packetString, zrtpPacket->messageLength+16);
264 }
265 fflush(NULL);
266 }
267 }
268
dumpContext(char * title,bzrtpContext_t * zrtpContext)269 void dumpContext(char *title, bzrtpContext_t *zrtpContext) {
270 if (verbose) {
271 uint8_t buffer[4];
272 int i,j;
273 printf("%s context is :\n", title);
274 printHex("selfZID", zrtpContext->selfZID, 12);
275 printHex("peerZID", zrtpContext->peerZID, 12);
276
277 for (i=0; i<ZRTP_MAX_CHANNEL_NUMBER; i++) {
278 if (zrtpContext->channelContext[i] != NULL) {
279 bzrtpChannelContext_t *channelContext = zrtpContext->channelContext[i];
280 printf("Channel %i\n self: %08x\n", i, channelContext->selfSSRC);
281 printf (" selfH: ");
282 for (j=0; j<4; j++) {
283 printHex(" ", channelContext->selfH[j], 32);
284 }
285 printf (" peerH: ");
286 for (j=0; j<4; j++) {
287 printHex(" ", channelContext->peerH[j], 32);
288 }
289
290 bzrtp_cryptoAlgoTypeIntToString(channelContext->hashAlgo, buffer);
291 printf(" Selected algos\n - Hash: %.4s\n", buffer);
292 bzrtp_cryptoAlgoTypeIntToString(channelContext->cipherAlgo, buffer);
293 printf(" - cipher: %.4s\n", buffer);
294 bzrtp_cryptoAlgoTypeIntToString(channelContext->authTagAlgo, buffer);
295 printf(" - auth tag: %.4s\n", buffer);
296 bzrtp_cryptoAlgoTypeIntToString(channelContext->keyAgreementAlgo, buffer);
297 printf(" - key agreement: %.4s\n", buffer);
298 bzrtp_cryptoAlgoTypeIntToString(channelContext->sasAlgo, buffer);
299 printf(" - sas: %.4s\n", buffer);
300 printHex(" initiator auxID", channelContext->initiatorAuxsecretID, 8);
301 printHex(" responder auxID", channelContext->responderAuxsecretID, 8);
302 if (channelContext->s0 != NULL) {
303 printHex(" s0", channelContext->s0, channelContext->hashLength);
304 }
305 if(channelContext->srtpSecrets.sas != NULL) {
306 printf(" sas : %.4s\n", channelContext->srtpSecrets.sas);
307 }
308 if (channelContext->srtpSecrets.selfSrtpKey != NULL) {
309 printHex(" selfsrtp key", channelContext->srtpSecrets.selfSrtpKey, channelContext->srtpSecrets.selfSrtpKeyLength);
310 printHex(" selfsrtp salt", channelContext->srtpSecrets.selfSrtpSalt, channelContext->srtpSecrets.selfSrtpSaltLength);
311 printHex(" peersrtp key", channelContext->srtpSecrets.peerSrtpKey, channelContext->srtpSecrets.peerSrtpKeyLength);
312 printHex(" peersrtp salt", channelContext->srtpSecrets.peerSrtpSalt, channelContext->srtpSecrets.peerSrtpSaltLength);
313 }
314 if (channelContext->mackeyi!=NULL) {
315 printHex(" mackeyi", channelContext->mackeyi, channelContext->hashLength);
316 }
317 if (channelContext->mackeyr!=NULL) {
318 printHex(" mackeyr", channelContext->mackeyr, channelContext->hashLength);
319 }
320 if (channelContext->zrtpkeyi!=NULL) {
321 printHex(" zrtpkeyi", channelContext->zrtpkeyi, channelContext->cipherKeyLength);
322 }
323 if (channelContext->zrtpkeyr!=NULL) {
324 printHex(" zrtpkeyr", channelContext->zrtpkeyr, channelContext->cipherKeyLength);
325 }
326 }
327 }
328
329 printf("Initiator Shared Secrets :\n");
330 printHex("rs1ID", zrtpContext->initiatorCachedSecretHash.rs1ID, 8);
331 printHex("rs2ID", zrtpContext->initiatorCachedSecretHash.rs2ID, 8);
332 printHex("pbxID", zrtpContext->initiatorCachedSecretHash.pbxsecretID, 8);
333
334 printf("Responder Shared Secrets :\n");
335 printHex("rs1ID", zrtpContext->responderCachedSecretHash.rs1ID, 8);
336 printHex("rs2ID", zrtpContext->responderCachedSecretHash.rs2ID, 8);
337 printHex("pbxID", zrtpContext->responderCachedSecretHash.pbxsecretID, 8);
338 fflush(NULL);
339 }
340 }
341
342
343 #ifdef ZIDCACHE_ENABLED
344
345 #define MAX_PATH_SIZE 1024
346
bzrtptester_sqlite3_open(const char * db_file,sqlite3 ** db)347 int bzrtptester_sqlite3_open(const char *db_file, sqlite3 **db) {
348 char* errmsg = NULL;
349 int ret;
350 int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
351
352 #if TARGET_OS_IPHONE
353 /* the secured filesystem of the iPHone doesn't allow writing while the app is in background mode, which is problematic.
354 * We workaround by asking that the open is made with no protection*/
355 flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
356 #endif
357
358 ret = sqlite3_open_v2(db_file, db, flags, NULL);
359
360 if (ret != SQLITE_OK) return ret;
361 // Some platforms do not provide a way to create temporary files which are needed
362 // for transactions... so we work in memory only
363 // see http ://www.sqlite.org/compile.html#temp_store
364 ret = sqlite3_exec(*db, "PRAGMA temp_store=MEMORY", NULL, NULL, &errmsg);
365 if (ret != SQLITE_OK) {
366 sqlite3_free(errmsg);
367 }
368
369 return ret;
370 }
371 #endif /* ZIDCACHE_ENABLED */
372