chenqiyang
2021-08-27 6a63c4281fbe7e17103115320cd276397d733081
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
112
113
114
115
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
 * 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 <http://www.gnu.org/licenses/>.
 */
 
#ifndef ms_zrtp_h
#define ms_zrtp_h
 
#include <ortp/rtpsession.h>
#include "mediastreamer2/mscommon.h"
#include <bctoolbox/port.h>
 
#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 */