/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
*
* This file is part of mediastreamer2.
*
* 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 3 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, see .
*/
#ifndef ms_zrtp_h
#define ms_zrtp_h
#include
#include "mediastreamer2/mscommon.h"
#include
#ifdef __cplusplus
extern "C"{
#endif
/* defined in mediastream.h */
struct _MSMediaStreamSessions;
/* Error codes */
#define MSZRTP_ERROR_CHANNEL_ALREADY_STARTED -0x0001
#define MS_MAX_ZRTP_CRYPTO_TYPES 7
/* cache related function return codes */
#define MSZRTP_CACHE_ERROR -0x1000
#define MSZRTP_CACHE_SETUP 0x2000
#define MSZRTP_CACHE_UPDATE 0x2001
#define MSZRTP_ERROR_CACHEDISABLED -0x0200
#define MSZRTP_ERROR_CACHEMIGRATIONFAILED -0x0400
typedef uint8_t MsZrtpCryptoTypesCount;
typedef enum _MSZrtpHash{
MS_ZRTP_HASH_INVALID,
MS_ZRTP_HASH_S256,
MS_ZRTP_HASH_S384,
MS_ZRTP_HASH_N256,
MS_ZRTP_HASH_N384
} MSZrtpHash;
typedef enum _MSZrtpCipher{
MS_ZRTP_CIPHER_INVALID,
MS_ZRTP_CIPHER_AES1,
MS_ZRTP_CIPHER_AES2,
MS_ZRTP_CIPHER_AES3,
MS_ZRTP_CIPHER_2FS1,
MS_ZRTP_CIPHER_2FS2,
MS_ZRTP_CIPHER_2FS3
} MSZrtpCipher;
typedef enum _MSZrtpAuthTag{
MS_ZRTP_AUTHTAG_INVALID,
MS_ZRTP_AUTHTAG_HS32,
MS_ZRTP_AUTHTAG_HS80,
MS_ZRTP_AUTHTAG_SK32,
MS_ZRTP_AUTHTAG_SK64
} MSZrtpAuthTag;
typedef enum _MSZrtpKeyAgreement{
MS_ZRTP_KEY_AGREEMENT_INVALID,
MS_ZRTP_KEY_AGREEMENT_DH2K,
MS_ZRTP_KEY_AGREEMENT_DH3K,
MS_ZRTP_KEY_AGREEMENT_EC25,
MS_ZRTP_KEY_AGREEMENT_EC38,
MS_ZRTP_KEY_AGREEMENT_EC52,
MS_ZRTP_KEY_AGREEMENT_X255,
MS_ZRTP_KEY_AGREEMENT_X448
} MSZrtpKeyAgreement;
typedef enum _MSZrtpSasType{
MS_ZRTP_SAS_INVALID,
MS_ZRTP_SAS_B32,
MS_ZRTP_SAS_B256
} MSZrtpSasType;
typedef enum _MSZrtpPeerStatus{
MS_ZRTP_PEER_STATUS_UNKNOWN,
MS_ZRTP_PEER_STATUS_INVALID,
MS_ZRTP_PEER_STATUS_VALID
} MSZrtpPeerStatus;
typedef struct MSZrtpParams {
void *zidCacheDB; /**< a pointer to an sqlite database holding all zrtp related information */
bctbx_mutex_t *zidCacheDBMutex; /**< pointer to a mutex used to lock cache access */
const char *selfUri; /* our sip URI, needed for zrtp Cache */
const char *peerUri; /* the sip URI of correspondant, needed for zrtp Cache */
uint32_t limeKeyTimeSpan; /**< amount in seconds of the lime key life span, set to 0 for infinite life span **/
bool_t autoStart; /*allow zrtp to start on first hello packet received*/
/* activated crypto types */
MSZrtpHash hashes[MS_MAX_ZRTP_CRYPTO_TYPES];
MsZrtpCryptoTypesCount hashesCount ;
MSZrtpCipher ciphers[MS_MAX_ZRTP_CRYPTO_TYPES];
MsZrtpCryptoTypesCount ciphersCount;
MSZrtpAuthTag authTags[MS_MAX_ZRTP_CRYPTO_TYPES];
MsZrtpCryptoTypesCount authTagsCount;
MSZrtpKeyAgreement keyAgreements[MS_MAX_ZRTP_CRYPTO_TYPES];
MsZrtpCryptoTypesCount keyAgreementsCount;
MSZrtpSasType sasTypes[MS_MAX_ZRTP_CRYPTO_TYPES];
MsZrtpCryptoTypesCount sasTypesCount;
} MSZrtpParams;
typedef struct _MSZrtpContext MSZrtpContext ;
/**
* check if ZRTP is available
* @return TRUE if it is available, FALSE if not
*/
MS2_PUBLIC bool_t ms_zrtp_available(void);
/**
* Create an initialise a ZRTP context
* @param[in] stream_sessions A link to the stream sessions structures, used to get rtp session to add transport modifier and needed to set SRTP sessions when keys are ready
* @param[in] params ZID cache filename and peer sip uri
* @return a pointer to the opaque context structure needed by MSZRTP
*/
MS2_PUBLIC MSZrtpContext* ms_zrtp_context_new(struct _MSMediaStreamSessions *stream_sessions, MSZrtpParams *params);
/**
* Create an initialise a ZRTP context on a channel when a ZRTP exchange was already performed on an other one
* @param[in] stream_sessions A link to the stream sessions structures, used to get rtp session to add transport modifier and needed to set SRTP sessions when keys are ready
* @param[in] activeContext The MSZRTP context of the already active session, used to pass to lib bzrtp its own context which shall remain unique.
* @return a pointer to the opaque context structure needed by MSZRTP
*/
MS2_PUBLIC MSZrtpContext* ms_zrtp_multistream_new(struct _MSMediaStreamSessions *stream_sessions, MSZrtpContext* activeContext);
/**
* Start a previously created ZRTP channel, ZRTP engine will start sending Hello packets
* @param[in] ctx Context previously created using ms_zrtp_context_new or ms_zrtp_multistream_new
* @return 0 on success
*/
MS2_PUBLIC int ms_zrtp_channel_start(MSZrtpContext *ctx);
/**
* Free ressources used by ZRTP context
* it will also free the libbzrtp context if no more channel are active
* @param[in/out] context the opaque MSZRTP context
*/
MS2_PUBLIC void ms_zrtp_context_destroy(MSZrtpContext *ctx);
/**
* Can be used to give more time for establishing zrtp session
* @param[in] ctx The MSZRTP context
* */
MS2_PUBLIC void ms_zrtp_reset_transmition_timer(MSZrtpContext* ctx);
/**
* Tell the MSZRTP context that SAS was controlled by user, it will trigger a ZID cache update
* @param[in] ctx MSZRTP context, used to retrieve cache and update it
*/
MS2_PUBLIC void ms_zrtp_sas_verified(MSZrtpContext* ctx);
/**
* Tell the MSZRTP context that user have requested the SAS verified status to be reseted, it will trigger a ZID cache update
* @param[in] ctx MSZRTP context, used to retrieve cache and update it
*/
MS2_PUBLIC void ms_zrtp_sas_reset_verified(MSZrtpContext* ctx);
/**
* Get the zrtp sas validation status for a peer uri.
* Once the SAS has been validated or rejected, the status will never return to UNKNOWN (unless you delete your cache)
* @param[in/out] db Pointer to the sqlite3 db open connection
* Use a void * to keep this API when building cacheless
* @param[in] peerUri the sip uri of the peer device we're querying status
* @param[in] dbMutex a mutex to synchronise zrtp cache database operation. Ignored if NULL
*
* @return - MS_ZRTP_PEER_STATUS_UNKNOWN: this uri is not present in cache OR during calls with the active device, SAS never was validated or rejected
* - MS_ZRTP_PEER_STATUS_INVALID: the active device status is set to valid
* - MS_ZRTP_PEER_STATUS_VALID: the active peer device status is set to invalid
*/
MS2_PUBLIC MSZrtpPeerStatus ms_zrtp_get_peer_status(void *db, const char *peerUri, bctbx_mutex_t *dbMutex);
/**
* Get the ZRTP Hello Hash from the given context
* @param[in] ctx MSZRTP context
* @param[out] The Zrtp Hello Hash as defined in RFC6189 section 8
*/
MS2_PUBLIC int ms_zrtp_getHelloHash(MSZrtpContext* ctx, uint8_t *output, size_t outputLength);
/**
* Set the optional ZRTP auxiliary shared secret
* @param[in] ctx MSZRTP context
* @param[in] The ZRTP auxiliary shared secret
* @param[in] The size of the auxiliary shared secret
* @return 0 on success, error code otherwise
*/
MS2_PUBLIC int ms_zrtp_setAuxiliarySharedSecret(MSZrtpContext *ctx, const uint8_t *auxSharedSecret, size_t auxSharedSecretLength);
/**
* Get the ZRTP auxiliary shared secret mismatch status
* @param[in] ctx MSZRTP context
* @return 0 on match, 1 otherwise
*/
MS2_PUBLIC uint8_t ms_zrtp_getAuxiliarySharedSecretMismatch(MSZrtpContext *ctx);
/**
* Set the peer ZRTP Hello Hash to the given context
* @param[in] ctx MSZRTP context
* @param[in] The Zrtp Hello Hash as defined in RFC6189 section 8
* @param[in] The Zrtp Hello Hash length
* @return 0 on success, error code otherwise
*/
MS2_PUBLIC int ms_zrtp_setPeerHelloHash(MSZrtpContext *ctx, uint8_t *peerHelloHashHexString, size_t peerHelloHashHexStringLength);
/**
* from_string and to_string for enums: MSZrtpHash, MSZrtpCipher, MSZrtpAuthTag, MSZrtpKeyAgreement, MSZrtpSasType
*/
MS2_PUBLIC MSZrtpHash ms_zrtp_hash_from_string(const char* str);
MS2_PUBLIC const char* ms_zrtp_hash_to_string(const MSZrtpHash hash);
MS2_PUBLIC MSZrtpCipher ms_zrtp_cipher_from_string(const char* str);
MS2_PUBLIC const char* ms_zrtp_cipher_to_string(const MSZrtpCipher cipher);
MS2_PUBLIC MSZrtpAuthTag ms_zrtp_auth_tag_from_string(const char* str);
MS2_PUBLIC const char* ms_zrtp_auth_tag_to_string(const MSZrtpAuthTag authTag);
MS2_PUBLIC MSZrtpKeyAgreement ms_zrtp_key_agreement_from_string(const char* str);
MS2_PUBLIC const char* ms_zrtp_key_agreement_to_string(const MSZrtpKeyAgreement keyAgreement);
MS2_PUBLIC MSZrtpSasType ms_zrtp_sas_type_from_string(const char* str);
MS2_PUBLIC const char* ms_zrtp_sas_type_to_string(const MSZrtpSasType sasType);
/* Cache wrapper functions : functions needed by liblinphone wrapped to avoid direct dependence of linphone on bzrtp */
/**
* @brief Check the given sqlite3 DB and create requested tables if needed
* Also manage DB schema upgrade
* @param[in/out] db Pointer to the sqlite3 db open connection
* Use a void * to keep this API when building cacheless
* @param[in] dbMutex a mutex to synchronise zrtp cache database operation. Ignored if NULL
*
* @return 0 on success, MSZRTP_CACHE_SETUP if cache was empty, MSZRTP_CACHE_UPDATE if db structure was updated error code otherwise
*/
MS2_PUBLIC int ms_zrtp_initCache(void *db, bctbx_mutex_t *dbMutex);
/**
* @brief Perform migration from xml version to sqlite3 version of cache
* Warning: new version of cache associate a ZID to each local URI, the old one did not
* the migration function will associate any data in the cache to the sip URI given in parameter which shall be the default URI
* @param[in] cacheXml a pointer to an xmlDocPtr structure containing the old cache to be migrated
* @param[in/out] cacheSqlite a pointer to an sqlite3 structure containing a cache initialised using ms_zrtp_cache_init function
* @param[in] selfURI default sip URI for this end point, NULL terminated char
*
* @return 0 on success, MSZRTP_ERROR_CACHEDISABLED when bzrtp was not compiled with cache enabled, MSZRTP_ERROR_CACHEMIGRATIONFAILED on error during migration
*/
MS2_PUBLIC int ms_zrtp_cache_migration(void *cacheXmlPtr, void *cacheSqlite, const char *selfURI);
#ifdef __cplusplus
}
#endif
#endif /* ms_zrtp_h */