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