Commit b709b862 authored by johan's avatar johan

Better management of mismatching peer/local ZRTP implementation

- Stick to old export key only when peer is BZRTP v1.0.x
- message to calling lib when peer is unlikely to implement LIME
parent c6c2e6db
......@@ -127,6 +127,7 @@ typedef struct bzrtpSrtpSecrets_struct {
/* define message codes */
#define BZRTP_MESSAGE_CACHEMISMATCH 0x01
#define BZRTP_MESSAGE_PEERVERSIONOBSOLETE 0x02
#define BZRTP_MESSAGE_PEERNOTBZRTP 0x03
/**
* Function pointer used by bzrtp to free memory allocated by callbacks.
......@@ -154,13 +155,6 @@ typedef struct bzrtpCallbacks_struct {
#define ZRTP_MAGIC_COOKIE 0x5a525450
#define ZRTP_VERSION "1.10"
/* Client identifier can contain up to 16 characters */
/* Use it to pass bzrtp version number to peer, is it part of Hello message */
/* custom Linphone Instant Messaging Encryption depends on bzrtp version */
/* Note: ZRTP_VERSION and BZrtp version are for now both at 1.1 but they are unrelated */
#define ZRTP_CLIENT_IDENTIFIERv1_1 "BZRTPv1.1"
#define ZRTP_CLIENT_IDENTIFIER ZRTP_CLIENT_IDENTIFIERv1_1
/* error code definition */
#define BZRTP_ERROR_INVALIDCALLBACKID 0x0001
#define BZRTP_ERROR_CONTEXTNOTREADY 0x0002
......
......@@ -72,6 +72,18 @@ typedef struct bzrtpChannelContext_struct bzrtpChannelContext_t;
#define NON_HELLO_CAP_RETRANSMISSION_STEP 1200
#define NON_HELLO_MAX_RETRANSMISSION_NUMBER 10
/* Client identifier can contain up to 16 characters, it identify the BZRTP library version */
/* Use it to pass bzrtp version number to peer, is it part of Hello message */
/* custom Linphone Instant Messaging Encryption depends on bzrtp version */
/* Note: ZRTP_VERSION and BZrtp version are for now both at 1.1 but they are unrelated */
/* historically since the creation of bzrtp, it used client idenfiers : */
#define ZRTP_CLIENT_IDENTIFIERv1_0a "LINPHONE-ZRTPCPP"
#define ZRTP_CLIENT_IDENTIFIERv1_0b "BZRTP"
/* Since version 1.1 which implement correctly the key export mechanism described in ZRTP RFC 4.5.2, bzrtp lib identifies itself as */
#define ZRTP_CLIENT_IDENTIFIERv1_1 "BZRTPv1.1"
#define ZRTP_CLIENT_IDENTIFIER ZRTP_CLIENT_IDENTIFIERv1_1
/* pgp word list for use with SAS */
extern const char * pgpWordsEven[];
extern const char * pgpWordsOdd[];
......
......@@ -559,7 +559,7 @@ int bzrtp_exportKey(bzrtpContext_t *zrtpContext, char *label, size_t labelLength
/* check we have s0 or exportedKey and KDFContext in channel[0] - export keys is available only on channel 0 completion - see RFC 4.5.2 */
bzrtpChannelContext_t *zrtpChannelContext = zrtpContext->channelContext[0];
if (zrtpContext->peerBzrtpVersion < 10100) { /* keep compatibility with older implementation of bzrtp */
if (zrtpContext->peerBzrtpVersion == 10000) { /* keep compatibility with older implementation of bzrtp */
/* before version 1.1.0 (turned into an int MMmmpp -> 010100) exported keys wrongly derives from given label and s0 direclty instead of
deriving one Exported Key from S0 and then as many as needed from the exported key as specified in the RFC section 4.5.2 */
if (zrtpChannelContext->s0 == NULL || zrtpChannelContext->KDFContext == NULL) {
......@@ -573,7 +573,7 @@ int bzrtp_exportKey(bzrtpContext_t *zrtpContext, char *label, size_t labelLength
bzrtp_keyDerivationFunction(zrtpChannelContext->s0, zrtpChannelContext->hashLength, (uint8_t *)label, labelLength, zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, *derivedKeyLength, (void (*)(uint8_t *, uint8_t, uint8_t *, uint32_t, uint8_t, uint8_t *))zrtpChannelContext->hmacFunction, derivedKey);
} else {
} else { /* peer either use version 1.1 of BZRTP or another library, just stick to the RFC to create the export key */
if ((zrtpChannelContext->s0 == NULL && zrtpContext->exportedKey) || zrtpChannelContext->KDFContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
......
......@@ -1659,16 +1659,26 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex
memcpy(zrtpChannelContext->peerH[3], helloMessage->H3, 32); /* H3 */
zrtpChannelContext->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket; /* peer hello packet */
/* Extract from peerHello packet the version of bzrtp used by peer and store it in global context(needed later when exporting keys) */
/* Bzrtp version started to be publicised in version 1.1, before that the client identifier was simply BZRTP and earlier version also have LINPHONE-ZRTPCPP */
/* So basically just check if the client identifier is BZRTPv1.1 or not. */
/* If not, it may be earlier version or an other library, so compute the exported keys old style just in case we need them */
if (strncmp(ZRTP_CLIENT_IDENTIFIERv1_1, (char *)helloMessage->clientIdentifier, 16)==0) {
zrtpContext->peerBzrtpVersion=10100;
} else { /* this is not version 1.1 of bzrtp(can be another zrtp lib or and older version of bzrtp), set it to 1.0 */
/* Extract from peerHello packet the version of bzrtp used by peer and store it in global context(needed later when exporting keys)
* Bzrtp version started to be publicised in version 1.1, before that the client identifier was simply BZRTP and earlier version also have LINPHONE-ZRTPCPP
* We must know this version in order to keep export key computation compatible between version as before v1.1 it was badly implemented
* So basically check :
* if the client identifier is BZRTP or LINPHONE-ZRTPCPP -> version 1.0 (use the old and incorrect way of creating an export key)
* if BZRTPv1.1 -> version 1.1 (use RFC compliant way of creating the export key )
* if anything else peer use another library, set version to 0.0 and use RFC compliant way of creating the export key as peer library is expected to be RFC compliant
*/
/* This is BZRTP in its old version */
if ((strncmp(ZRTP_CLIENT_IDENTIFIERv1_0a, (char *)helloMessage->clientIdentifier, 16)==0) || (strncmp(ZRTP_CLIENT_IDENTIFIERv1_0b, (char *)helloMessage->clientIdentifier, 16)==0)){
zrtpContext->peerBzrtpVersion=10000;
if (zrtpContext->zrtpCallbacks.bzrtp_statusMessage!=NULL && zrtpContext->zrtpCallbacks.bzrtp_messageLevel>=BZRTP_MESSAGE_LOG) { /* use error level as this one MUST (RFC section 4.3.2) be warned */
zrtpContext->zrtpCallbacks.bzrtp_statusMessage(zrtpChannelContext->clientData, BZRTP_MESSAGE_LOG, BZRTP_MESSAGE_PEERVERSIONOBSOLETE, (const char *)helloMessage->clientIdentifier);
if (zrtpContext->zrtpCallbacks.bzrtp_statusMessage!=NULL && zrtpContext->zrtpCallbacks.bzrtp_messageLevel>=BZRTP_MESSAGE_WARNING) { /* use warning level as the client may really wants to know this */
zrtpContext->zrtpCallbacks.bzrtp_statusMessage(zrtpChannelContext->clientData, BZRTP_MESSAGE_WARNING, BZRTP_MESSAGE_PEERVERSIONOBSOLETE, (const char *)helloMessage->clientIdentifier);
}
} else if (strncmp(ZRTP_CLIENT_IDENTIFIERv1_1, (char *)helloMessage->clientIdentifier, 16)==0) { /* peer has the current version, everything is Ok */
zrtpContext->peerBzrtpVersion=10100;
} else { /* peer uses another lib, we're probably not LIME compliant, log it */
zrtpContext->peerBzrtpVersion=0;
if (zrtpContext->zrtpCallbacks.bzrtp_statusMessage!=NULL && zrtpContext->zrtpCallbacks.bzrtp_messageLevel>=BZRTP_MESSAGE_LOG) {
zrtpContext->zrtpCallbacks.bzrtp_statusMessage(zrtpChannelContext->clientData, BZRTP_MESSAGE_LOG, BZRTP_MESSAGE_PEERNOTBZRTP, (const char *)helloMessage->clientIdentifier);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment