chenqiyang
2021-08-20 7b95fb4d4549d3452ee17165236186afc1f2b393
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*
 * Copyright (c) 2012-2019 Belledonne Communications SARL.
 *
 * This file is part of belle-sip.
 *
 * 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 AUTHENTICATION_HELPER_H_
#define AUTHENTICATION_HELPER_H_
 
#include "belle-sip/defs.h"
#include "belle-sip/belle-sip.h"
#include "bctoolbox/crypto.h"
 
#define MAX_LENGTH_BYTE 32
#define MAX_RESPONSE_SIZE 65
 
BELLE_SIP_BEGIN_DECLS
 
/**
 * Create an authorization header from an www_authenticate header, all common parameters are copyed.
 * copy params: scheme, realm, nonce, algorithm, opaque
 * @param authentication source to be used as input
 * @return belle_sip_header_authorization_t*
 */
BELLESIP_EXPORT belle_sip_header_authorization_t* belle_sip_auth_helper_create_authorization(const belle_sip_header_www_authenticate_t* authentication);
 
/**
 * Create an www_authenticate header from an authorization header, all common parameters are copyed.
 * copy params: scheme, realm, nonce, algorithm, opaque
 * @param authorization source to be used as input
 * @return belle_sip_header_www_authenticate_t*
 */
BELLESIP_EXPORT belle_sip_header_www_authenticate_t* belle_sip_auth_helper_create_www_authenticate(const belle_sip_header_authorization_t* authorization);
/**
 * Create an http authorization header from an www_authenticate header, all common parameters are copyed.
 * copy params: scheme, realm, nonce, algorithm, opaque
 * @param authentication source to be used as input
 * @return belle_http_header_authorization_t*
 */
BELLESIP_EXPORT belle_http_header_authorization_t* belle_http_auth_helper_create_authorization(const belle_sip_header_www_authenticate_t* authentication);
 
 
/**
 * Create an proxy_authorization header from an www_authenticate header, all common parameters are copyed.
 * copy params: scheme, realm, nonce, algorithm, opaque
 * @param authentication source to be used as input
 * @return belle_sip_header_authorization_t*
 */
BELLESIP_EXPORT belle_sip_header_proxy_authorization_t* belle_sip_auth_helper_create_proxy_authorization(const belle_sip_header_proxy_authenticate_t* proxy_authentication);
 
/**
 * return size which depends on algorithm
 * @return 0 if failed
 */
BELLESIP_EXPORT int belle_sip_auth_define_size(const char* algo);
 
/**
 * compute and set response value according to parameters
 * HA1=MD5(username:realm:passwd)
 * fills cnonce if needed (qop=auth);
 * fills qop
 *
 * @return 0 if succeed
 */
BELLESIP_EXPORT int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* authorization
                                                ,const char* method
                                                ,const char* ha1);
 
/**
 * compute and set response value according to parameters
 * @return 0 if succeed
 */
BELLESIP_EXPORT int belle_sip_auth_helper_fill_proxy_authorization(belle_sip_header_proxy_authorization_t* proxy_authorization
                                                ,const char* method
                                                ,const char* ha1);
 
/*
 * compute HA1 (NULL terminated)
 * HA1=MD5(userid:realm:passwd)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha1(const char* userid,const char* realm,const char* password, char ha1[33]);
/*
 * compute HA1 (NULL terminated)
 * HA1=MD5(userid:realm:passwd) or SHA-256(userid:realm:passwd)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha1_for_algorithm(const char* userid,const char* realm,const char* password, char *ha1, size_t size, const char* algo);
/*
 * compute HA2 (NULL terminated)
 * HA2=MD5(method:uri)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha2(const char* method,const char* uri, char ha2[33]);
 
/*
 * compute HA2 (NULL terminated)
 * HA2=MD5(method:uri) or SHA-256(method:uri)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_ha2_for_algorithm(const char* method,const char* uri, char *ha2, size_t size, const char* algo);
/*
 * compute response(NULL terminated)
 * res=MD5(ha1:nonce:ha2)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_response(const char* ha1,const char* nonce, const char* ha2, char response[33]);
 
/*
 * compute response(NULL terminated)
 * res=MD5(ha1:nonce:ha2) or SHA-256(ha1:nonce:ha2)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_for_algorithm(const char* ha1,const char* nonce, const char* ha2, char *response, size_t size, const char* algo);
/*
 * compute response(NULL terminated)
 * res=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth(    const char* ha1
                                                    , const char* nonce
                                                    , unsigned int nonce_count
                                                    , const char* cnonce
                                                    , const char* qop
                                                    , const char* ha2
                                                    , char response[33]);
 
/*
 * compute response(NULL terminated)
 * res=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2) or SHA-256(HA1:nonce:nonce_count:cnonce:qop:HA2)
 * return 0 in case of success
 * */
BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth_for_algorithm(const char* ha1
                                                                  , const char* nonce
                                                                  , unsigned int nonce_count
                                                                  , const char* cnonce
                                                                  , const char* qop
                                                                  , const char* ha2
                                                                  , char *response
                                                                  , size_t size, const char* algo);
/*TLS client certificate auth*/
 
/**
 * Set TLS certificate verification callback
 *
 * @param callback function pointer for callback, or NULL to unset
 * @deprecated on 2018/03/31 in favor of belle_tls_crypto_config_set_verify_callback()
 * Callback signature is:
 * int (*verify_cb_error_cb_t)(unsigned char* der, int length, int depth, int* flags);
 * der - raw certificate data, in DER format
 * length - length of certificate DER data
 * depth - position of certificate in cert chain, ending at 0 = root or top
 * flags - verification state for CURRENT certificate only
 */
BELLESIP_DEPRECATED BELLESIP_EXPORT int belle_sip_tls_set_verify_error_cb(void *callback);
 
/**
 * Format of certificate buffer
 **/
typedef enum  belle_sip_certificate_raw_format {
    BELLE_SIP_CERTIFICATE_RAW_FORMAT_PEM, /** PEM format*/
    BELLE_SIP_CERTIFICATE_RAW_FORMAT_DER /** ASN.1 raw format*/
}belle_sip_certificate_raw_format_t;
 
/**
 * Parse a buffer containing either a certificate chain order in PEM format or a single DER cert
 * @param buff raw buffer
 * @param size buffer size
 * @param format either PEM or DER
 * @return  belle_sip_certificates_chain_t or NULL if cannot be decoded
 */
BELLESIP_EXPORT belle_sip_certificates_chain_t* belle_sip_certificates_chain_parse(const char* buff, size_t size,belle_sip_certificate_raw_format_t format);
 
/**
 * Parse a buffer containing either a private or public rsa key in PEM format
 * @param buff raw buffer
 * @param size buffer size
 * @param passwd password (optionnal)
 * @return list of belle_sip_signing_key_t or NULL if cannot be decoded
 */
BELLESIP_EXPORT belle_sip_signing_key_t* belle_sip_signing_key_parse(const char* buff, size_t size,const char* passwd);
 
/**
 * Parse a pather containing either a certificate chain order in PEM format or a single DER cert
 * @param path file
 * @param format either PEM or DER
 * @return  belle_sip_certificates_chain_t or NUL if cannot be decoded
 */
BELLESIP_EXPORT belle_sip_certificates_chain_t* belle_sip_certificates_chain_parse_file(const char* path, belle_sip_certificate_raw_format_t format);
 
/**
 * Parse a directory for *.pem file containing a certificate and private key in PEM format or a single DER cert with subject CNAME as given
 *
 * @param[in]    path            directory to parse
 * @param[in]    subject            subject CNAME to look for
 * @param[out]    certificate        result certificate, NULL if not found. Is allocated by this function, caller must do a belle_sip_object_unref on it after use
 * @param[out]    pkey            result private key, NULL if not found. Is allocated by this function, caller must do a belle_sip_object_unref on it after use
 * @param[in]    format            either PEM or DER
 * @return  0 if we found a certificate and key matching given subject common name
 */
BELLESIP_EXPORT int belle_sip_get_certificate_and_pkey_in_dir(const char *path, const char *subject, belle_sip_certificates_chain_t **certificate, belle_sip_signing_key_t **pkey, belle_sip_certificate_raw_format_t format);
 
/**
 * Generate a self signed certificate and key and save them in a file if a path is given, file will be <subject>.pem
 *
 * @param[in]    path        If not NULL a file will be written in the given directory. filename is <subject>.pem
 * @param[in]    subject        used in the CN= field of issuer and subject name
 * @param[out]    certificate    the generated certificate. Must be destroyed using belle_sip_certificates_chain_destroy
 * @param[out]    key            the generated key. Must be destroyed using belle_sip_signing_key_destroy
 * @return 0 on success
 */
BELLESIP_EXPORT int belle_sip_generate_self_signed_certificate(const char* path, const char *subject, belle_sip_certificates_chain_t **certificate, belle_sip_signing_key_t **pkey);
 
/**
 * Convert a certificate into a its PEM format string
 *
 * @param[in]    cert    The certificate to be converted into PEM format string
 * @return    the PEM representation of certificate. Buffer is allocated by this function and must be freed by caller
 */
BELLESIP_EXPORT char *belle_sip_certificates_chain_get_pem(belle_sip_certificates_chain_t *cert);
 
/**
 * Convert a key into a its PEM format string
 *
 * @param[in]    key        The key to be converted into PEM format string
 * @return    the PEM representation of key. Buffer is allocated by this function and must be freed by caller
 */
BELLESIP_EXPORT char *belle_sip_signing_key_get_pem(belle_sip_signing_key_t *key);
 
/**
 * Generate a certificate fingerprint as described in RFC4572
 * Note: only SHA1 signing algo is supported for now
 *
 * @param[in]    certificate        The certificate used to generate the fingerprint
 * @return        The generated fingerprint formatted according to RFC4572 section 5. Is a null terminated string, must be freed by caller
 */
BELLESIP_EXPORT char *belle_sip_certificates_chain_get_fingerprint(belle_sip_certificates_chain_t *certificate);
 
/**
 * Parse a pather containing either a private or public rsa key
 * @param path file
 * @param passwd password (optionnal)
 * @return list of belle_sip_signing_key_t or NUL iff cannot be decoded
 */
BELLESIP_EXPORT belle_sip_signing_key_t* belle_sip_signing_key_parse_file(const char* path, const char* passwd);
 
#define BELLE_TLS_VERIFY_NONE        (0)
#define BELLE_TLS_VERIFY_CN_MISMATCH (1)
#define BELLE_TLS_VERIFY_ANY_REASON (0xff)
/* Set of functions deprecated on 2016/02/02 use the belle_tls_crypto_config_XXX ones */
BELLESIP_DEPRECATED BELLESIP_EXPORT belle_tls_verify_policy_t *belle_tls_verify_policy_new(void);
BELLESIP_DEPRECATED BELLESIP_EXPORT int belle_tls_verify_policy_set_root_ca(belle_tls_verify_policy_t *obj, const char *path);
BELLESIP_DEPRECATED BELLESIP_EXPORT void belle_tls_verify_policy_set_exceptions(belle_tls_verify_policy_t *obj, int flags);
BELLESIP_DEPRECATED BELLESIP_EXPORT unsigned int belle_tls_verify_policy_get_exceptions(const belle_tls_verify_policy_t *obj);
 
 
/**
 * Create a new crypto configuration object
 * The crypto configuration may be passed to a http provider or a listening point using the appropriate methods
 * It can be used to provide :
 * - a path to the trusted root certificates
 * - a way to override certificate verification exceptions
 * - a ssl configuration structure provided directly to the underlying crypto library (mbedtls 2 or above),
 * @return an empty belle_tls_crypto_config object, trusted certificate path is initialised to the default system path without any warranty
 */
BELLESIP_EXPORT belle_tls_crypto_config_t *belle_tls_crypto_config_new(void);
 
/**
 * Set the path to the trusted certificate chain
 * @param[in/out]    obj        The crypto configuration object to set
 * @param[in]        path    The path to the trusted certificate chain file(NULL terminated string)
 *
 * @return 0 on success
 */
BELLESIP_EXPORT int belle_tls_crypto_config_set_root_ca(belle_tls_crypto_config_t *obj, const char *path);
 
/**
 * Set the content of the trusted certificate chain
 * @param[in/out]    obj        The crypto configuration object to set
 * @param[in]        data    The content to the trusted certificate chain data(NULL terminated string)
 *
 * @return 0 on success
 */
BELLESIP_EXPORT int belle_tls_crypto_config_set_root_ca_data(belle_tls_crypto_config_t *obj, const char *data);
 
/**
 * Set the exception flags to manage exception overriding during peer certificate verification
 * @param[in/out]    obj        The crypto configuration object to set
 * @param[in]        flags    Flags value to set:
 *                             BELLE_TLS_VERIFY_NONE to raise and error on any exception
 *                             BELLE_TLS_VERIFY_CN_MISMATCH to ignore Common Name mismatch
 *                             BELLE_TLS_VERIFY_ANY_REASON to ignore any exception
 *
 * @return 0 on success
 */
BELLESIP_EXPORT void belle_tls_crypto_config_set_verify_exceptions(belle_tls_crypto_config_t *obj, int flags);
 
/**
 * Get the exception flags used to manage exception overriding during peer certificate verification
 * @param[in]i        obj        The crypto configuration object to set
 * @return            Possible flags value :
 *                             BELLE_TLS_VERIFY_NONE to raise and error on any exception
 *                             BELLE_TLS_VERIFY_CN_MISMATCH to ignore Common Name mismatch
 *                             BELLE_TLS_VERIFY_ANY_REASON to ignore any exception
 *
 */
BELLESIP_EXPORT unsigned int belle_tls_crypto_config_get_verify_exceptions(const belle_tls_crypto_config_t *obj);
 
 
/**
 * Callback prototype to override certificate check at upper level.
 * @param user_data the user pointer passed to belle_tls_crypto_config_set_verify_callback()
 * @param cert the x509 certificate
 * @param depth depth of certificate in the certificate chain (the callback is called for each certificate of the chain
 * @param flags i/o parameter containing the error flags reported by the crypto library (BCTBX_CERTIFICATE_VERIFY_* flags).
 *         The application may freely alterate the flags on output, in order to bypass verifications or add new error flags.
 *         The flags MUST be set or unset with bctbx_x509_certificate_set_flag() bctbx_x509_certificate_unset_flag()
**/
typedef void (*belle_tls_crypto_config_verify_callback_t)(void *user_data, bctbx_x509_certificate_t *cert , int depth, uint32_t *flags);
 
/**
 * Set a callback function to call during each TLS handshake in order to override certificate verification.
 * @param obj the crypto config object
 * @param cb the application callback
 * @param cb_data an application data pointer that will be passed to callback when invoked.
**/
BELLESIP_EXPORT void belle_tls_crypto_config_set_verify_callback(belle_tls_crypto_config_t *obj, belle_tls_crypto_config_verify_callback_t cb, void *cb_data);
 
 
/**
 * Callback prototype to check remote certificate once hanshake is completed (post-check).
 * @param user_data the user pointer passed to belle_tls_crypto_config_set_postcheck_callback()
 * @param cert the peer x509 certificate
 * @return 0 if all is good, -1 otherwise
**/
typedef int (*belle_tls_crypto_config_postcheck_callback_t)(void *user_data, const bctbx_x509_certificate_t *cert);
 
/**
 * Set the post-check callback function executed upon successfull TLS handshake..
 * @param obj the crypto config object
 * @param cb the application callback
 * @param cb_data an application data pointer that will be passed to callback when invoked.
**/
BELLESIP_EXPORT void belle_tls_crypto_config_set_postcheck_callback(belle_tls_crypto_config_t *obj, belle_tls_crypto_config_postcheck_callback_t cb, void *cb_data);
 
/**
 * Set the pointer to an externally provided ssl configuration for the crypto library
 * @param[in/out]    obj            The crypto configuration object to set
 * @param[in]        ssl_config    A pointer to an opaque structure which will be provided directly to the crypto library used in bctoolbox. Use with extra care.
 *                                 This ssl_config structure is responsability of the caller and will not be freed at the connection's end.
 */
BELLESIP_EXPORT void belle_tls_crypto_config_set_ssl_config(belle_tls_crypto_config_t *obj, void *ssl_config);
 
BELLE_SIP_END_DECLS
 
#endif /* AUTHENTICATION_HELPER_H_ */