Просмотр исходного кода

security: add BSecurity for initializing OpenSSL locking

ambrop7 15 лет назад
Родитель
Сommit
fc2ce39626
3 измененных файлов с 176 добавлено и 0 удалено
  1. 126 0
      security/BSecurity.c
  2. 49 0
      security/BSecurity.h
  3. 1 0
      security/CMakeLists.txt

+ 126 - 0
security/BSecurity.c

@@ -0,0 +1,126 @@
+/**
+ * @file BSecurity.c
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef BADVPN_THREADWORK_USE_PTHREAD
+    #include <pthread.h>
+#endif
+
+#include <openssl/crypto.h>
+
+#include <misc/debug.h>
+#include <misc/balloc.h>
+
+#include <security/BSecurity.h>
+
+int bsecurity_initialized = 0;
+int bsecurity_use_threads;
+
+#ifdef BADVPN_THREADWORK_USE_PTHREAD
+pthread_mutex_t *bsecurity_locks;
+int bsecurity_num_locks;
+#endif
+
+#ifdef BADVPN_THREADWORK_USE_PTHREAD
+
+static unsigned long id_callback (void)
+{
+    ASSERT(bsecurity_initialized)
+    ASSERT(bsecurity_use_threads)
+    
+    return (unsigned long)pthread_self();
+}
+
+static void locking_callback (int mode, int type, const char *file, int line)
+{
+    ASSERT(bsecurity_initialized)
+    ASSERT(bsecurity_use_threads)
+    ASSERT(type >= 0)
+    ASSERT(type < bsecurity_num_locks)
+    
+    if ((mode & CRYPTO_LOCK)) {
+        ASSERT_FORCE(pthread_mutex_lock(&bsecurity_locks[type]) == 0)
+    } else {
+        ASSERT_FORCE(pthread_mutex_unlock(&bsecurity_locks[type]) == 0)
+    }
+}
+
+#endif
+
+int BSecurity_GlobalInit (int use_threads)
+{
+    ASSERT(use_threads == 0 || use_threads == 1)
+    ASSERT(!bsecurity_initialized)
+    
+    #ifdef BADVPN_THREADWORK_USE_PTHREAD
+    
+    if (use_threads) {
+        // get number of locks
+        int num_locks = CRYPTO_num_locks();
+        ASSERT_FORCE(num_locks >= 0)
+        
+        // alloc locks array
+        if (!(bsecurity_locks = BAllocArray(num_locks, sizeof(bsecurity_locks[0])))) {
+            goto fail0;
+        }
+        
+        // init locks
+        bsecurity_num_locks = 0;
+        for (int i = 0; i < num_locks; i++) {
+            if (pthread_mutex_init(&bsecurity_locks[i], NULL) != 0) {
+                goto fail1;
+            }
+            bsecurity_num_locks++;
+        }
+    }
+    
+    #endif
+    
+    bsecurity_initialized = 1;
+    bsecurity_use_threads = use_threads;
+    
+    #ifdef BADVPN_THREADWORK_USE_PTHREAD
+    if (use_threads) {
+        CRYPTO_set_id_callback(id_callback);
+        CRYPTO_set_locking_callback(locking_callback);
+    }
+    #endif
+    
+    return 1;
+    
+    #ifdef BADVPN_THREADWORK_USE_PTHREAD
+fail1:
+    while (bsecurity_num_locks > 0) {
+        ASSERT_FORCE(pthread_mutex_destroy(&bsecurity_locks[bsecurity_num_locks - 1]) == 0)
+        bsecurity_num_locks--;
+    }
+    BFree(bsecurity_locks);
+fail0:
+    return 0;
+    #endif
+}
+
+void BSecurity_GlobalAssert (int need_threads)
+{
+    ASSERT(need_threads == 0 || need_threads == 1)
+    ASSERT(bsecurity_initialized)
+    ASSERT(!(need_threads) || bsecurity_use_threads)
+}

+ 49 - 0
security/BSecurity.h

@@ -0,0 +1,49 @@
+/**
+ * @file BSecurity.h
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * @section DESCRIPTION
+ * 
+ * Initialization of OpenSSL for security functions.
+ */
+
+#ifndef BADVPN_SECURITY_BSECURITY_H
+#define BADVPN_SECURITY_BSECURITY_H
+
+/**
+ * Initializes security functions.
+ * May only be called once.
+ * 
+ * @param use_threads whether the application may call security functions
+ *                    from different threads. Must be 0 or 1.
+ * @return 1 on success, 0 on failure
+ */
+int BSecurity_GlobalInit (int use_threads);
+
+/**
+ * Asserts that {@link BSecurity_GlobalInit} was done, and that it was
+ * done with use_threads=1 if need_threads=1.
+ * 
+ * @param need_threads whether the application may call security functions
+ *                     from different threads. Must be 0 or 1.
+ */
+void BSecurity_GlobalAssert (int need_threads);
+
+#endif

+ 1 - 0
security/CMakeLists.txt

@@ -1,4 +1,5 @@
 add_library(security
+    BSecurity.c
     BEncryption.c
     BHash.c
     BRandom.c