FreeSWITCH API Documentation  1.7.0
Functions | Variables
switch_core_cert.c File Reference
#include <switch.h>
#include <switch_ssl.h>
+ Include dependency graph for switch_core_cert.c:

Go to the source code of this file.

Functions

static void switch_ssl_ssl_lock_callback (int mode, int type, char *file, int line)
 
static unsigned long switch_ssl_ssl_thread_id (void)
 
void switch_ssl_init_ssl_locks (void)
 
void switch_ssl_destroy_ssl_locks (void)
 
static const EVP_MD * get_evp_by_name (const char *name)
 
int switch_core_cert_verify (dtls_fingerprint_t *fp)
 
int switch_core_cert_expand_fingerprint (dtls_fingerprint_t *fp, const char *str)
 
int switch_core_cert_extract_fingerprint (X509 *x509, dtls_fingerprint_t *fp)
 
int switch_core_cert_gen_fingerprint (const char *prefix, dtls_fingerprint_t *fp)
 
static int mkcert (X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
 
int switch_core_gen_certs (const char *prefix)
 

Variables

static switch_mutex_t ** ssl_mutexes
 
static switch_memory_pool_tssl_pool = NULL
 
static int ssl_count = 0
 

Function Documentation

static const EVP_MD* get_evp_by_name ( const char *  name)
static

Definition at line 96 of file switch_core_cert.c.

Referenced by switch_core_cert_extract_fingerprint().

97 {
98  if (!strcasecmp(name, "md5")) return EVP_md5();
99  if (!strcasecmp(name, "sha1")) return EVP_sha1();
100  if (!strcasecmp(name, "sha-1")) return EVP_sha1();
101  if (!strcasecmp(name, "sha-256")) return EVP_sha256();
102  if (!strcasecmp(name, "sha-512")) return EVP_sha512();
103 
104  return NULL;
105 }
static int mkcert ( X509 **  x509p,
EVP_PKEY **  pkeyp,
int  bits,
int  serial,
int  days 
)
static

Definition at line 336 of file switch_core_cert.c.

References switch_cache_db_handle::name, and switch_assert.

Referenced by switch_core_gen_certs().

337 {
338  X509 *x;
339  EVP_PKEY *pk;
340  RSA *rsa;
341  X509_NAME *name=NULL;
342 
343  switch_assert(pkeyp);
344  switch_assert(x509p);
345 
346  if (*pkeyp == NULL) {
347  if ((pk = EVP_PKEY_new()) == NULL) {
348  abort();
349  }
350  } else {
351  pk = *pkeyp;
352  }
353 
354  if (*x509p == NULL) {
355  if ((x = X509_new()) == NULL) {
356  goto err;
357  }
358  } else {
359  x = *x509p;
360  }
361 
362  rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);
363 
364  if (!EVP_PKEY_assign_RSA(pk, rsa)) {
365  abort();
366  goto err;
367  }
368 
369  rsa = NULL;
370 
371  X509_set_version(x, 0);
372  ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
373  X509_gmtime_adj(X509_get_notBefore(x), -(long)60*60*24*7);
374  X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days);
375  X509_set_pubkey(x, pk);
376 
377  name = X509_get_subject_name(x);
378 
379  /* This function creates and adds the entry, working out the
380  * correct string type and performing checks on its length.
381  * Normally we'd check the return value for errors...
382  */
383  X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"US", -1, -1, 0);
384  X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"FreeSWITCH", -1, -1, 0);
385 
386 
387  /* Its self signed so set the issuer name to be the same as the
388  * subject.
389  */
390  X509_set_issuer_name(x, name);
391 
392  if (!X509_sign(x, pk, EVP_sha1()))
393  goto err;
394 
395  *x509p = x;
396  *pkeyp = pk;
397  return(1);
398  err:
399  return(0);
400 }
#define switch_assert(expr)
int switch_core_cert_expand_fingerprint ( dtls_fingerprint_t fp,
const char *  str 
)

Definition at line 152 of file switch_core_cert.c.

References MAX_FPLEN.

Referenced by switch_rtp_add_dtls().

153 {
154  char *tmp = strdup(str);
155  char *p = tmp;
156  int i = 0;
157  char *v;
158 
159  while ((v = strsep(&p, ":")) && (i != (MAX_FPLEN - 1))) {
160  sscanf(v, "%02x", (uint32_t *) &fp->data[i++]);
161  }
162 
163  free(tmp);
164 
165  return i;
166 }
uint8_t data[MAX_FPLEN+1]
Definition: switch_core.h:152
#define MAX_FPLEN
Definition: switch_core.h:147
int switch_core_cert_extract_fingerprint ( X509 *  x509,
dtls_fingerprint_t fp 
)

Definition at line 168 of file switch_core_cert.c.

References get_evp_by_name(), SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, and switch_log_printf().

Referenced by dtls_state_setup(), and switch_core_cert_gen_fingerprint().

169 {
170  const EVP_MD *evp;
171  unsigned int i, j;
172 
173  evp = get_evp_by_name(fp->type);
174 
175  if (X509_digest(x509, evp, fp->data, &fp->len) != 1 || fp->len <= 0) {
177  return -1;
178  }
179 
180  for (i = 0, j = 0; i < fp->len; ++i, j += 3){
181  sprintf((char*)&fp->str[j], (i == (fp->len - 1)) ? "%.2X" : "%.2X:", fp->data[i]);
182  }
183  *(&fp->str[fp->len * 3]) = '\0';
184 
185  return 0;
186 
187 }
#define SWITCH_CHANNEL_LOG
char str[MAX_FPSTRLEN]
Definition: switch_core.h:154
char * type
Definition: switch_core.h:153
uint8_t data[MAX_FPLEN+1]
Definition: switch_core.h:152
uint32_t len
Definition: switch_core.h:151
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static const EVP_MD * get_evp_by_name(const char *name)
int switch_core_cert_gen_fingerprint ( const char *  prefix,
dtls_fingerprint_t fp 
)

Definition at line 189 of file switch_core_cert.c.

References switch_directories::certs_dir, SWITCH_CHANNEL_LOG, switch_core_cert_extract_fingerprint(), switch_file_exists(), SWITCH_GLOBAL_dirs, SWITCH_LOG_ERROR, switch_log_printf(), switch_mprintf(), SWITCH_PATH_SEPARATOR, and SWITCH_STATUS_SUCCESS.

Referenced by generate_local_fingerprint().

190 {
191  X509* x509 = NULL;
192  BIO* bio = NULL;
193  int ret = 0;
194  char *rsa;
195 
197 
198  if (switch_file_exists(rsa, NULL) != SWITCH_STATUS_SUCCESS) {
199  free(rsa);
201  }
202 
203  if (!(bio = BIO_new(BIO_s_file()))) {
205  goto end;
206  }
207 
208  if (BIO_read_filename(bio, rsa) != 1) {
210  goto end;
211  }
212 
213  if (!(x509 = PEM_read_bio_X509(bio, NULL, 0, NULL))) {
215  goto end;
216  }
217 
219 
220  ret = 1;
221 
222  end:
223 
224  if (bio) {
225  BIO_free_all(bio);
226  }
227 
228  if (x509) {
229  X509_free(x509);
230  }
231 
232  free(rsa);
233 
234  return ret;
235 }
#define SWITCH_CHANNEL_LOG
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
int switch_core_cert_extract_fingerprint(X509 *x509, dtls_fingerprint_t *fp)
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_status_t switch_file_exists(const char *filename, switch_memory_pool_t *pool)
Definition: switch_apr.c:496
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
int switch_core_cert_verify ( dtls_fingerprint_t fp)

Definition at line 133 of file switch_core_cert.c.

References MAX_FPLEN.

Referenced by dtls_state_setup().

134 {
135  unsigned char fdata[MAX_FPLEN] = { 0 };
136  char *tmp = strdup(fp->str);
137  char *p = tmp;
138  int i = 0;
139  char *v;
140 
141  while ((v = strsep(&p, ":")) && (i != (MAX_FPLEN - 1))) {
142  sscanf(v, "%02x", (uint32_t *) &fdata[i++]);
143  }
144 
145  free(tmp);
146 
147  i = !memcmp(fdata, fp->data, i);
148 
149  return i;
150 }
char str[MAX_FPSTRLEN]
Definition: switch_core.h:154
uint8_t data[MAX_FPLEN+1]
Definition: switch_core.h:152
#define MAX_FPLEN
Definition: switch_core.h:147
int switch_core_gen_certs ( const char *  prefix)

Definition at line 240 of file switch_core_cert.c.

References switch_directories::certs_dir, mkcert(), switch_file_exists(), SWITCH_GLOBAL_dirs, switch_is_file_path(), switch_mprintf(), SWITCH_PATH_SEPARATOR, switch_safe_free, SWITCH_STATUS_SUCCESS, and switch_stristr().

Referenced by switch_core_media_init().

241 {
242  //BIO *bio_err;
243  X509 *x509 = NULL;
244  EVP_PKEY *pkey = NULL;
245  char *rsa = NULL, *pvt = NULL;
246  FILE *fp;
247  char *pem = NULL;
248 
249  if (switch_stristr(".pem", prefix)) {
250 
251  if (switch_is_file_path(prefix)) {
252  pem = strdup(prefix);
253  } else {
255  }
256 
257  if (switch_file_exists(pem, NULL) == SWITCH_STATUS_SUCCESS) {
258  goto end;
259  }
260  } else {
261  if (switch_is_file_path(prefix)) {
262  pvt = switch_mprintf("%s.key", prefix);
263  rsa = switch_mprintf("%s.crt", prefix);
264  } else {
267  }
268 
270  goto end;
271  }
272  }
273 
274  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
275 
276  //bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
277 
278  mkcert(&x509, &pkey, 1024, 0, 36500);
279 
280  //RSA_print_fp(stdout, pkey->pkey.rsa, 0);
281  //X509_print_fp(stdout, x509);
282 
283  if (pem) {
284  if ((fp = fopen(pem, "w"))) {
285  PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
286  PEM_write_X509(fp, x509);
287  fclose(fp);
288  }
289 
290  } else {
291  if (pvt && (fp = fopen(pvt, "w"))) {
292  PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
293  fclose(fp);
294  }
295 
296  if (rsa && (fp = fopen(rsa, "w"))) {
297  PEM_write_X509(fp, x509);
298  fclose(fp);
299  }
300  }
301 
302  X509_free(x509);
303  EVP_PKEY_free(pkey);
304 
305 #ifndef OPENSSL_NO_ENGINE
306  ENGINE_cleanup();
307 #endif
308  CRYPTO_cleanup_all_ex_data();
309 
310  //CRYPTO_mem_leaks(bio_err);
311  //BIO_free(bio_err);
312 
313 
314  end:
315 
316  switch_safe_free(pvt);
317  switch_safe_free(rsa);
318  switch_safe_free(pem);
319 
320  return(0);
321 }
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_status_t switch_file_exists(const char *filename, switch_memory_pool_t *pool)
Definition: switch_apr.c:496
static switch_bool_t switch_is_file_path(const char *file)
const char * switch_stristr(const char *instr, const char *str)
static int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
void switch_ssl_destroy_ssl_locks ( void  )

Definition at line 79 of file switch_core_cert.c.

References ssl_count, ssl_mutexes, and switch_mutex_destroy().

Referenced by switch_core_destroy().

80 {
81  int i;
82 
83  if (ssl_count == 1) {
84  CRYPTO_set_locking_callback(NULL);
85  for (i = 0; i < CRYPTO_num_locks(); i++) {
86  if (ssl_mutexes[i]) {
88  }
89  }
90 
91  OPENSSL_free(ssl_mutexes);
92  ssl_count--;
93  }
94 }
switch_status_t switch_mutex_destroy(switch_mutex_t *lock)
Definition: switch_apr.c:280
static int ssl_count
static switch_mutex_t ** ssl_mutexes
void switch_ssl_init_ssl_locks ( void  )

Definition at line 54 of file switch_core_cert.c.

References ssl_count, ssl_mutexes, ssl_pool, switch_assert, switch_core_new_memory_pool, switch_mutex_init(), SWITCH_MUTEX_NESTED, switch_ssl_ssl_lock_callback(), and switch_ssl_ssl_thread_id().

Referenced by switch_core_init().

55 {
56 
57  int i, num;
58 
59  if (ssl_count == 0) {
60  num = CRYPTO_num_locks();
61 
62  ssl_mutexes = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(switch_mutex_t*));
63  switch_assert(ssl_mutexes != NULL);
64 
66 
67  for (i = 0; i < num; i++) {
69  switch_assert(ssl_mutexes[i] != NULL);
70  }
71 
72  CRYPTO_set_id_callback(switch_ssl_ssl_thread_id);
73  CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))switch_ssl_ssl_lock_callback);
74  }
75 
76  ssl_count++;
77 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
static int ssl_count
static unsigned long switch_ssl_ssl_thread_id(void)
static switch_mutex_t ** ssl_mutexes
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
struct apr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
static void switch_ssl_ssl_lock_callback(int mode, int type, char *file, int line)
static switch_memory_pool_t * ssl_pool
#define switch_assert(expr)
static void switch_ssl_ssl_lock_callback ( int  mode,
int  type,
char *  file,
int  line 
)
inlinestatic

Definition at line 39 of file switch_core_cert.c.

References ssl_mutexes, switch_mutex_lock(), and switch_mutex_unlock().

Referenced by switch_ssl_init_ssl_locks().

40 {
41  if (mode & CRYPTO_LOCK) {
43  }
44  else {
46  }
47 }
static switch_mutex_t ** ssl_mutexes
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_byte_t switch_byte_t uint32_t switch_bitpack_mode_t mode
static unsigned long switch_ssl_ssl_thread_id ( void  )
inlinestatic

Definition at line 49 of file switch_core_cert.c.

References switch_thread_self().

Referenced by switch_ssl_init_ssl_locks().

50 {
51  return (unsigned long) switch_thread_self();
52 }
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79

Variable Documentation

int ssl_count = 0
static

Definition at line 37 of file switch_core_cert.c.

Referenced by switch_ssl_destroy_ssl_locks(), and switch_ssl_init_ssl_locks().

switch_mutex_t** ssl_mutexes
static
switch_memory_pool_t* ssl_pool = NULL
static

Definition at line 36 of file switch_core_cert.c.

Referenced by switch_ssl_init_ssl_locks().