build: require minimum version of OpenSSL to be 1.0.1

Change-Id: I5d3fe907a7ab3159955e80a60cf0f011fd2b3154
Refs: #3007, #2949, #3089
diff --git a/.waf-tools/openssl.py b/.waf-tools/openssl.py
new file mode 100644
index 0000000..ec0dad1
--- /dev/null
+++ b/.waf-tools/openssl.py
@@ -0,0 +1,105 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# Yingdi Yu (UCLA) 2016
+
+'''
+
+When using this tool, the wscript will look like:
+
+    def options(opt):
+        opt.load('openssl')
+
+    def configure(conf):
+        conf.load('compiler_cxx openssl')
+        conf.check_openssl()
+
+    def build(bld):
+        bld(source='main.cpp', target='app', use='OPENSSL')
+
+'''
+
+import re
+from waflib import Utils, Logs
+from waflib.Configure import conf
+
+OPENSSL_VERSION_FILE = 'opensslv.h'
+OPENSSL_DIR_OSX = ['/usr/local', '/opt/local']
+OPENSSL_DIR = ['/usr', '/usr/local', '/opt/local', '/sw']
+
+def options(opt):
+    opt.add_option('--with-openssl', type='string', default=None, dest='openssl_dir',
+                   help='''Path to where OpenSSL is installed, e.g., /usr/local''')
+
+
+@conf
+def __openssl_get_version_file(self, dir):
+    try:
+        return self.root.find_dir(dir).find_node('%s/%s' % ('include/openssl',
+                                                            OPENSSL_VERSION_FILE))
+    except:
+        return None
+
+@conf
+def __openssl_find_root_and_version_file(self, *k, **kw):
+    root = k and k[0] or kw.get('path', self.options.openssl_dir)
+
+    file = self.__openssl_get_version_file(root)
+    if root and file:
+        return (root, file)
+
+    openssl_dir = [];
+    if Utils.unversioned_sys_platform() == "darwin":
+        openssl_dir = OPENSSL_DIR_OSX
+    else:
+        openssl_dir = OPENSSL_DIR
+
+    if not root:
+        for dir in openssl_dir:
+            file = self.__openssl_get_version_file(dir)
+            if file:
+                return (dir, file)
+
+    if root:
+        self.fatal('OpenSSL not found in %s' % root)
+    else:
+        self.fatal('OpenSSL not found, please provide a --with-openssl=PATH argument (see help)')
+
+@conf
+def check_openssl(self, *k, **kw):
+    atleast_version = kw.get('atleast_version', 0)
+    var = kw.get('uselib_store', 'OPENSSL')
+
+    self.start_msg('Checking for OpenSSL lib')
+    (root, file) = self.__openssl_find_root_and_version_file(*k, **kw)
+
+    try:
+        txt = file.read()
+        re_version = re.compile('^#\\s*define\\s+OPENSSL_VERSION_NUMBER\\s+(.*)L', re.M)
+        version_number = re_version.search(txt)
+
+        re_version_text = re.compile('^#\\s*define\\s+OPENSSL_VERSION_TEXT\\s+(.*)', re.M)
+        version_text = re_version_text.search(txt)
+
+        if version_number and version_text:
+            version = version_number.group(1)
+            self.end_msg(version_text.group(1))
+        else:
+            self.fatal('OpenSSL version file is present, but is not recognizable')
+    except:
+        self.fatal('OpenSSL version file is not found or is not usable')
+
+    if int(version, 16) < atleast_version:
+        self.fatal("The version of OpenSSL is too old\n" +
+                   "Please upgrade your distribution or install newer version of OpenSSL library")
+
+    kwargs = {}
+    if root:
+        kwargs['includes'] = "%s/include" % root
+        kwargs['libpath'] = "%s/lib" % root
+
+    libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
+                               msg='Checking if OpenSSL library works',
+                               define_name='HAVE_%s' % var,
+                               uselib_store=var,
+                               mandatory=True,
+                               **kwargs)