testUtils.c 10.1 KB
Newer Older
johan's avatar
johan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/**
 @file testUtils.c

 @author Johan Pascal

 @copyright Copyright (C) 2014 Belledonne Communications, Grenoble, France
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "testUtils.h"
#include "cryptoUtils.h"
johan's avatar
johan committed
30 31 32 33 34 35 36 37 38 39
int verbose = 0;

void bzrtp_message(const char *fmt, ...) {
	if (verbose) {
		va_list args;
		va_start(args, fmt);
		vprintf(fmt, args);
		va_end(args);
	}
}
johan's avatar
johan committed
40 41

void printHex(char *title, uint8_t *data, uint32_t length) {
johan's avatar
johan committed
42 43 44 45 46 47 48
	if (verbose) {
		int i;
		printf ("%s : ", title);
		for (i=0; i<length; i++) {
			printf ("0x%02x, ", data[i]);
		}
		printf ("\n");
johan's avatar
johan committed
49 50 51 52
	}
}

void packetDump(bzrtpPacket_t *zrtpPacket, uint8_t addRawMessage) {
johan's avatar
johan committed
53
	if (verbose) {
johan's avatar
johan committed
54 55 56 57 58 59 60 61 62 63
		int j;
		printf ("SSRC %x - Message Length: %d - ", zrtpPacket->sourceIdentifier, zrtpPacket->messageLength);
		if (zrtpPacket->packetString!=NULL) { /* paquet has been built and we need to get his sequence number in the packetString */
			printf ("Sequence number: %02x%02x", *(zrtpPacket->packetString+2), *(zrtpPacket->packetString+3));
		} else { /* packet has been parsed, so get his sequence number in the structure */
			printf ("Sequence number: %04x", zrtpPacket->sequenceNumber);
		}
		switch (zrtpPacket->messageType) {
			case MSGTYPE_HELLO :
				{
64 65 66
					bzrtpHelloMessage_t *messageData;
					uint8_t algoTypeString[4];

johan's avatar
johan committed
67
					printf(" - Message Type : Hello\n");
68
					messageData = (bzrtpHelloMessage_t *)zrtpPacket->messageData;
johan's avatar
johan committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
					printf ("Version %.4s\nIdentifier %.16s\n", messageData->version, messageData->clientIdentifier);
					printHex ("H3", messageData->H3, 32);
					printHex ("ZID", messageData->ZID, 12);
					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);
					printf ("hc ");
					for (j=0; j<messageData->hc; j++) {
						cryptoAlgoTypeIntToString(messageData->supportedHash[j], algoTypeString);
						printf("%.4s, ", algoTypeString);
					}
					printf ("\ncc ");
					for (j=0; j<messageData->cc; j++) {
						cryptoAlgoTypeIntToString(messageData->supportedCipher[j], algoTypeString);
						printf("%.4s, ", algoTypeString);
					}
					printf ("\nac ");
					for (j=0; j<messageData->ac; j++) {
						cryptoAlgoTypeIntToString(messageData->supportedAuthTag[j], algoTypeString);
						printf("%.4s, ", algoTypeString);
					}
					printf ("\nkc ");
					for (j=0; j<messageData->kc; j++) {
						cryptoAlgoTypeIntToString(messageData->supportedKeyAgreement[j], algoTypeString);
						printf("%.4s, ", algoTypeString);
					}
					printf ("\nsc ");
					for (j=0; j<messageData->sc; j++) {
						cryptoAlgoTypeIntToString(messageData->supportedSas[j], algoTypeString);
						printf("%.4s, ", algoTypeString);
					}
					printHex("\nMAC", messageData->MAC, 8);
				}

				break; /* MSGTYPE_HELLO */

			case MSGTYPE_HELLOACK :
				{
					printf(" - Message Type : Hello ACK\n");
				}
				break;

			case MSGTYPE_COMMIT:
				{
					uint8_t algoTypeString[4];
112 113
					bzrtpCommitMessage_t *messageData;

johan's avatar
johan committed
114
					printf(" - Message Type : Commit\n");
115
					messageData = (bzrtpCommitMessage_t *)zrtpPacket->messageData;
johan's avatar
johan committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
					printHex("H2", messageData->H2, 32);
					printHex("ZID", messageData->ZID, 12);
					cryptoAlgoTypeIntToString(messageData->hashAlgo, algoTypeString);
					printf("Hash Algo: %.4s\n", algoTypeString);
					cryptoAlgoTypeIntToString(messageData->cipherAlgo, algoTypeString);
					printf("Cipher Algo: %.4s\n", algoTypeString);
					cryptoAlgoTypeIntToString(messageData->authTagAlgo, algoTypeString);
					printf("Auth tag Algo: %.4s\n", algoTypeString);
					cryptoAlgoTypeIntToString(messageData->keyAgreementAlgo, algoTypeString);
					printf("Key agreement Algo: %.4s\n", algoTypeString);
					cryptoAlgoTypeIntToString(messageData->sasAlgo, algoTypeString);
					printf("Sas Algo: %.4s\n", algoTypeString);
					/* if it is a multistream or preshared commit, get the 16 bytes nonce */
					if ((messageData->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Prsh) || (messageData->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Mult)) {
						printHex("Nonce", messageData->nonce, 16);

						/* and the keyID for preshared commit only */
						if (messageData->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Prsh) {
							printHex("KeyId", messageData->keyID, 8);
						}
					} else { /* it's a DH commit message, get the hvi */
						printHex("hvi", messageData->hvi, 32);
					}

					printHex("\nMAC", messageData->MAC, 8);
				}
				break;
			case MSGTYPE_DHPART1:
			case MSGTYPE_DHPART2:
				{
146 147
					bzrtpDHPartMessage_t *messageData;

148 149 150 151 152
					if (zrtpPacket->messageType == MSGTYPE_DHPART1) {
						printf(" - Message Type : DHPart1\n");
					} else {
						printf(" - Message Type : DHPart2\n");
					}
153
					messageData = (bzrtpDHPartMessage_t *)zrtpPacket->messageData;
johan's avatar
johan committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
					printHex ("H1", messageData->H1, 32);
					printHex ("rs1ID", messageData->rs1ID, 8);
					printHex ("rs2ID", messageData->rs2ID, 8);
					printHex ("auxsecretID", messageData->auxsecretID, 8);
					printHex ("pbxsecretID", messageData->pbxsecretID, 8);
					printHex ("rs1ID", messageData->rs1ID, 8);
					printf("PV length is %d\n", (zrtpPacket->messageLength-84));
					printHex ("PV", messageData->pv, (zrtpPacket->messageLength-84)); /* length of fixed part of the message is 84, rest is the variable length PV */
					printHex("MAC", messageData->MAC, 8);
					
				}
				break;
			case MSGTYPE_CONFIRM1:
			case MSGTYPE_CONFIRM2:
				{
169 170
					bzrtpConfirmMessage_t *messageData;

171 172 173 174 175
					if (zrtpPacket->messageType == MSGTYPE_CONFIRM1) {
						printf(" - Message Type : Confirm1\n");
					} else {
						printf(" - Message Type : Confirm2\n");
					}
176
					messageData = (bzrtpConfirmMessage_t *)zrtpPacket->messageData;
johan's avatar
johan committed
177 178 179 180 181
					printHex("H0", messageData->H0, 32);
					printf("sig_len %d\n", messageData->sig_len);
					printf("E %d V %d A %d D %d\n", messageData->E,  messageData->V, messageData->A, messageData->D);
					printf("Cache expiration Interval %08x\n", messageData->cacheExpirationInterval);
				}
182 183 184 185 186
				break;
			case MSGTYPE_CONF2ACK:
				{
					printf(" - Message Type: Conf2ACK\n");
				}
johan's avatar
johan committed
187 188 189 190 191
		}

		if (addRawMessage) {
			printHex("Data", zrtpPacket->packetString, zrtpPacket->messageLength+16);
		}
johan's avatar
johan committed
192
	}
johan's avatar
johan committed
193 194 195
}

void dumpContext(char *title, bzrtpContext_t *zrtpContext) {
johan's avatar
johan committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
	if (verbose) {
		uint8_t buffer[4];
		int i,j;
		printf("%s context is :\n", title);
		printHex("selfZID", zrtpContext->selfZID, 12);
		printHex("peerZID", zrtpContext->peerZID, 12);

		for (i=0; i<ZRTP_MAX_CHANNEL_NUMBER; i++) {
			if (zrtpContext->channelContext[i] != NULL) {
				bzrtpChannelContext_t *channelContext = zrtpContext->channelContext[i];
				printf("Channel %i\n  self: %08x\n", i, channelContext->selfSSRC);
				printf ("    selfH: ");
				for (j=0; j<4; j++) {
					printHex("      ", channelContext->selfH[j], 32);
				}
				printf ("    peerH: ");
				for (j=0; j<4; j++) {
					printHex("      ", channelContext->peerH[j], 32);
				}		

				cryptoAlgoTypeIntToString(channelContext->hashAlgo, buffer);
				printf("    Selected algos\n     - Hash: %.4s\n", buffer);
				cryptoAlgoTypeIntToString(channelContext->cipherAlgo, buffer);
				printf("     - cipher: %.4s\n", buffer);
				cryptoAlgoTypeIntToString(channelContext->authTagAlgo, buffer);
				printf("     - auth tag: %.4s\n", buffer);
				cryptoAlgoTypeIntToString(channelContext->keyAgreementAlgo, buffer);
				printf("     - key agreement: %.4s\n", buffer);
				cryptoAlgoTypeIntToString(channelContext->sasAlgo, buffer);
				printf("     - sas: %.4s\n", buffer);
				printHex("    initiator auxID", channelContext->initiatorAuxsecretID, 8);
				printHex("    responder auxID", channelContext->responderAuxsecretID, 8);
				if (channelContext->s0 != NULL) {
					printHex("    s0", channelContext->s0, channelContext->hashLength);
				}
				if(channelContext->srtpSecrets.sas != NULL) {
					printf("    sas : %.4s\n", channelContext->srtpSecrets.sas);
				}
				if (channelContext->srtpSecrets.selfSrtpKey != NULL) {
					printHex("    selfsrtp key", channelContext->srtpSecrets.selfSrtpKey, channelContext->srtpSecrets.selfSrtpKeyLength);
					printHex("    selfsrtp salt", channelContext->srtpSecrets.selfSrtpSalt, channelContext->srtpSecrets.selfSrtpSaltLength);
					printHex("    peersrtp key", channelContext->srtpSecrets.peerSrtpKey, channelContext->srtpSecrets.peerSrtpKeyLength);
					printHex("    peersrtp salt", channelContext->srtpSecrets.peerSrtpSalt, channelContext->srtpSecrets.peerSrtpSaltLength);
				}
				if (channelContext->mackeyi!=NULL) {
					printHex("    mackeyi", channelContext->mackeyi, channelContext->hashLength);
				}
				if (channelContext->mackeyr!=NULL) {
					printHex("    mackeyr", channelContext->mackeyr, channelContext->hashLength);
				}
				if (channelContext->zrtpkeyi!=NULL) {
					printHex("    zrtpkeyi", channelContext->zrtpkeyi, channelContext->cipherKeyLength);
				}
				if (channelContext->zrtpkeyr!=NULL) {
					printHex("    zrtpkeyr", channelContext->zrtpkeyr, channelContext->cipherKeyLength);
				}
252
			}
johan's avatar
johan committed
253
		}
johan's avatar
johan committed
254

johan's avatar
johan committed
255 256 257 258
		printf("Initiator Shared Secrets :\n");
		printHex("rs1ID", zrtpContext->initiatorCachedSecretHash.rs1ID, 8);
		printHex("rs2ID", zrtpContext->initiatorCachedSecretHash.rs2ID, 8);
		printHex("pbxID", zrtpContext->initiatorCachedSecretHash.pbxsecretID, 8);
johan's avatar
johan committed
259

johan's avatar
johan committed
260 261 262 263 264
		printf("Responder Shared Secrets :\n");
		printHex("rs1ID", zrtpContext->responderCachedSecretHash.rs1ID, 8);
		printHex("rs2ID", zrtpContext->responderCachedSecretHash.rs2ID, 8);
		printHex("pbxID", zrtpContext->responderCachedSecretHash.pbxsecretID, 8);
	}
johan's avatar
johan committed
265
}