forked from wolfSSL/wolfssl
Merge pull request #5129 from LinuxJedi/remove-python-wrappers
Remove the Python wrappers from wolfSSL source
This commit is contained in:
@ -2,6 +2,6 @@
|
|||||||
# included from Top Level Makefile.am
|
# included from Top Level Makefile.am
|
||||||
# All paths should be given relative to the root
|
# All paths should be given relative to the root
|
||||||
|
|
||||||
include wrapper/python/wolfcrypt/include.am
|
|
||||||
include wrapper/python/wolfssl/include.am
|
|
||||||
include wrapper/CSharp/include.am
|
include wrapper/CSharp/include.am
|
||||||
|
|
||||||
|
EXTRA_DIST+= wrapper/python/README.md
|
||||||
|
11
wrapper/python/README.md
Normal file
11
wrapper/python/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# wolfSSL Python Wrappers
|
||||||
|
|
||||||
|
The wolfSSL Python Wrappers have moved to their own separate trees. Details of which can be found below.
|
||||||
|
|
||||||
|
## wolfCrypt-py
|
||||||
|
|
||||||
|
wolfCrypt-py's source code can be found [on GitHub here](https://github.com/wolfSSL/wolfcrypt-py). The latest release is also available [on PyPi here](https://pypi.org/project/wolfcrypt/).
|
||||||
|
|
||||||
|
## wolfSSL-py
|
||||||
|
|
||||||
|
Alternatively if you need a wolfSSL Python wrapper, the source code can be found [on GitHub here](https://github.com/wolfSSL/wolfssl-py). Likewise the latest release can be found [on PyPi here](https://pypi.org/project/wolfssl/).
|
@ -1,33 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
[ "$(whoami)" != "root" ] && echo "Sorry, you are not root." && exit 1
|
|
||||||
|
|
||||||
rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-6.noarch.rpm
|
|
||||||
yum update
|
|
||||||
yum install -y git autoconf libtool
|
|
||||||
|
|
||||||
git clone https://github.com/wolfssl/wolfssl.git
|
|
||||||
[ $? -ne 0 ] && echo "\n\nCouldn't download wolfssl.\n\n" && exit 1
|
|
||||||
|
|
||||||
pushd wolfssl
|
|
||||||
|
|
||||||
./autogen.sh
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
echo /usr/local/lib > wolfssl.conf
|
|
||||||
mv wolfssl.conf /etc/ld.so.conf
|
|
||||||
ldconfig
|
|
||||||
|
|
||||||
popd
|
|
||||||
rm -rf wolfssl
|
|
||||||
|
|
||||||
yum install -y libffi-devel python-devel python-pip
|
|
||||||
|
|
||||||
pip install wolfcrypt
|
|
||||||
[ $? -ne 0 ] && echo "\n\nCouldn't install wolfcrypt.\n\n" && exit 1
|
|
||||||
|
|
||||||
echo "Test should print:"
|
|
||||||
echo "da39a3ee5e6b4b0d3255bfef95601890afd80709"
|
|
||||||
echo "Running test:"
|
|
||||||
python -c "from wolfcrypt.hashes import Sha; print(Sha().hexdigest())"
|
|
18
wrapper/python/wolfcrypt/.gitignore
vendored
18
wrapper/python/wolfcrypt/.gitignore
vendored
@ -1,18 +0,0 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
|
|
||||||
# Distribution
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
.eggs/
|
|
||||||
*.egg-info/
|
|
||||||
|
|
||||||
# Unit test
|
|
||||||
.tox/
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# Virtual env
|
|
||||||
.env
|
|
@ -1,30 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
[ "$(whoami)" != "root" ] && echo "Sorry, you are not root." && exit 1
|
|
||||||
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y git autoconf libtool
|
|
||||||
|
|
||||||
git clone https://github.com/wolfssl/wolfssl.git
|
|
||||||
[ $? -ne 0 ] && echo "\n\nCouldn't download wolfssl.\n\n" && exit 1
|
|
||||||
|
|
||||||
pushd wolfssl
|
|
||||||
|
|
||||||
./autogen.sh
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
ldconfig
|
|
||||||
|
|
||||||
popd
|
|
||||||
rm -rf wolfssl
|
|
||||||
|
|
||||||
apt-get install -y libffi-dev python-dev python-pip
|
|
||||||
|
|
||||||
pip install wolfcrypt
|
|
||||||
[ $? -ne 0 ] && echo "\n\nCouldn't install wolfcrypt.\n\n" && exit 1
|
|
||||||
|
|
||||||
echo "Test should print:"
|
|
||||||
echo "da39a3ee5e6b4b0d3255bfef95601890afd80709"
|
|
||||||
echo "Running test:"
|
|
||||||
python -c "from wolfcrypt.hashes import Sha; print(Sha().hexdigest())"
|
|
@ -1,23 +0,0 @@
|
|||||||
Licensing
|
|
||||||
---------
|
|
||||||
|
|
||||||
wolfSSL’s software is available under two distinct licensing models:
|
|
||||||
open source and standard commercial licensing. Please see the relevant
|
|
||||||
section below for information on each type of license.
|
|
||||||
|
|
||||||
Open Source
|
|
||||||
~~~~~~~~~~~
|
|
||||||
|
|
||||||
wolfCrypt and wolfSSL software are free software downloads and may be modified
|
|
||||||
to the needs of the user as long as the user adheres to version two of the GPL
|
|
||||||
License. The GPLv2 license can be found on the `gnu.org website
|
|
||||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>`_.
|
|
||||||
|
|
||||||
Commercial Licensing
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Businesses and enterprises who wish to incorporate wolfSSL products into
|
|
||||||
proprietary appliances or other commercial software products for
|
|
||||||
re-distribution must license commercial versions. Licenses are generally issued
|
|
||||||
for one product and include unlimited royalty-free distribution. Custom
|
|
||||||
licensing terms are also available at licensing@wolfssl.com.
|
|
@ -1 +0,0 @@
|
|||||||
include LICENSING.rst
|
|
@ -1,144 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
wolfcrypt: the wolfSSL Crypto Engine
|
|
||||||
====================================
|
|
||||||
|
|
||||||
**wolfCrypt Python**, a.k.a. ``wolfcrypt`` is a Python library that encapsulates
|
|
||||||
**wolfSSL's wolfCrypt API**.
|
|
||||||
|
|
||||||
`wolfCrypt <https://wolfssl.com/wolfSSL/Products-wolfcrypt.html>`_ is a
|
|
||||||
lightweight, portable, C-language-based crypto library
|
|
||||||
targeted at IoT, embedded, and RTOS environments primarily because of its size,
|
|
||||||
speed, and feature set. It works seamlessly in desktop, enterprise, and cloud
|
|
||||||
environments as well. It is the crypto engine behind `wolfSSl's embedded ssl
|
|
||||||
library <https://wolfssl.com/wolfSSL/Products-wolfssl.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
In order to use ``wolfcrypt``, first you'll need to install ``wolfssl`` C
|
|
||||||
embedded ssl library.
|
|
||||||
|
|
||||||
Installing ``wolfssl`` :
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
**Mac OSX**
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
brew install wolfssl
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
git clone https://github.com/wolfssl/wolfssl.git
|
|
||||||
cd wolfssl/
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-sha512
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
|
|
||||||
**Ubuntu**
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y git autoconf libtool
|
|
||||||
|
|
||||||
git clone https://github.com/wolfssl/wolfssl.git
|
|
||||||
cd wolfssl/
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-sha512
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
sudo ldconfig
|
|
||||||
|
|
||||||
**CentOS**
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-6.noarch.rpm
|
|
||||||
sudo yum update
|
|
||||||
sudo yum install -y git autoconf libtool
|
|
||||||
|
|
||||||
git clone git@github.com:wolfssl/wolfssl.git
|
|
||||||
cd wolfssl
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-sha512
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
echo /usr/local/lib > wolfssl.conf
|
|
||||||
sudo mv wolfssl.conf /etc/ld.so.conf
|
|
||||||
sudo ldconfig
|
|
||||||
|
|
||||||
|
|
||||||
Installing ``wolfcrypt`` :
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
**Mac OSX**
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
sudo -H pip install wolfcrypt
|
|
||||||
|
|
||||||
|
|
||||||
**Ubuntu**
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
sudo apt-get install -y python-dev python3-dev python-pip libffi-dev
|
|
||||||
sudo -H pip install wolfcrypt
|
|
||||||
|
|
||||||
|
|
||||||
**CentOS**
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
sudo yum install -y python-devel python3-devel python-pip libffi-devel
|
|
||||||
sudo -H pip install wolfcrypt
|
|
||||||
|
|
||||||
|
|
||||||
Testing ``wolfcrypt`` :
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
python -c "from wolfcrypt.hashes import Sha; print Sha().hexdigest()"
|
|
||||||
|
|
||||||
expected output: **da39a3ee5e6b4b0d3255bfef95601890afd80709**
|
|
||||||
|
|
||||||
|
|
||||||
Testing ``wolfcrypt``'s source code with ``tox`` :
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To run the unit tests in the source code, you'll need ``tox`` and a few other
|
|
||||||
requirements. The source code relies at 'WOLFSSL_DIR/wrapper/python/wolfcrypt'
|
|
||||||
where WOLFSSL_DIR is the path of ``wolfssl``'s source code.
|
|
||||||
|
|
||||||
1. Make sure that the testing requirements are installed:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ sudo -H pip install -r requirements-testing.txt
|
|
||||||
|
|
||||||
|
|
||||||
2. Run ``tox``:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ tox
|
|
||||||
...
|
|
||||||
_________________________________ summary _________________________________
|
|
||||||
py27: commands succeeded
|
|
||||||
SKIPPED: py34: InterpreterNotFound: python3.4
|
|
||||||
py35: commands succeeded
|
|
||||||
congratulations :)
|
|
||||||
|
|
||||||
Note: the test is performed using multiple versions of python. If you are
|
|
||||||
missing a version the test will be skipped with an **InterpreterNotFound
|
|
||||||
error**.
|
|
14
wrapper/python/wolfcrypt/Vagrantfile
vendored
14
wrapper/python/wolfcrypt/Vagrantfile
vendored
@ -1,14 +0,0 @@
|
|||||||
# -*- mode: ruby -*-
|
|
||||||
# vi: set ft=ruby :
|
|
||||||
BOX = "ubuntu"
|
|
||||||
VAGRANTFILE_API_VERSION = "2"
|
|
||||||
|
|
||||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
||||||
if BOX == "ubuntu"
|
|
||||||
config.vm.box = "ubuntu/trusty64"
|
|
||||||
config.vm.provision "shell", path: ".ubuntu-provisioner.sh"
|
|
||||||
else
|
|
||||||
config.vm.box = "moisesguimaraes/centos72-64"
|
|
||||||
config.vm.provision "shell", path: ".centos-provisioner.sh"
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,230 +0,0 @@
|
|||||||
# Makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
PAPER =
|
|
||||||
BUILDDIR = _build
|
|
||||||
|
|
||||||
# User-friendly check for sphinx-build
|
|
||||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
|
||||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
|
|
||||||
.PHONY: help
|
|
||||||
help:
|
|
||||||
@echo "Please use \`make <target>' where <target> is one of"
|
|
||||||
@echo " html to make standalone HTML files"
|
|
||||||
@echo " dirhtml to make HTML files named index.html in directories"
|
|
||||||
@echo " singlehtml to make a single large HTML file"
|
|
||||||
@echo " pickle to make pickle files"
|
|
||||||
@echo " json to make JSON files"
|
|
||||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
|
||||||
@echo " qthelp to make HTML files and a qthelp project"
|
|
||||||
@echo " applehelp to make an Apple Help Book"
|
|
||||||
@echo " devhelp to make HTML files and a Devhelp project"
|
|
||||||
@echo " epub to make an epub"
|
|
||||||
@echo " epub3 to make an epub3"
|
|
||||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
|
||||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
|
||||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
|
||||||
@echo " text to make text files"
|
|
||||||
@echo " man to make manual pages"
|
|
||||||
@echo " texinfo to make Texinfo files"
|
|
||||||
@echo " info to make Texinfo files and run them through makeinfo"
|
|
||||||
@echo " gettext to make PO message catalogs"
|
|
||||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
|
||||||
@echo " xml to make Docutils-native XML files"
|
|
||||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
|
||||||
@echo " linkcheck to check all external links for integrity"
|
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
|
||||||
@echo " dummy to check syntax errors of document sources"
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf $(BUILDDIR)/*
|
|
||||||
|
|
||||||
.PHONY: html
|
|
||||||
html:
|
|
||||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
|
||||||
|
|
||||||
.PHONY: dirhtml
|
|
||||||
dirhtml:
|
|
||||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
|
||||||
|
|
||||||
.PHONY: singlehtml
|
|
||||||
singlehtml:
|
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
|
||||||
|
|
||||||
.PHONY: pickle
|
|
||||||
pickle:
|
|
||||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the pickle files."
|
|
||||||
|
|
||||||
.PHONY: json
|
|
||||||
json:
|
|
||||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the JSON files."
|
|
||||||
|
|
||||||
.PHONY: htmlhelp
|
|
||||||
htmlhelp:
|
|
||||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
|
||||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
|
||||||
|
|
||||||
.PHONY: qthelp
|
|
||||||
qthelp:
|
|
||||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
|
||||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
|
||||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/wolfcrypt.qhcp"
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/wolfcrypt.qhc"
|
|
||||||
|
|
||||||
.PHONY: applehelp
|
|
||||||
applehelp:
|
|
||||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
|
||||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
|
||||||
"~/Library/Documentation/Help or install it in your application" \
|
|
||||||
"bundle."
|
|
||||||
|
|
||||||
.PHONY: devhelp
|
|
||||||
devhelp:
|
|
||||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished."
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/wolfcrypt"
|
|
||||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/wolfcrypt"
|
|
||||||
@echo "# devhelp"
|
|
||||||
|
|
||||||
.PHONY: epub
|
|
||||||
epub:
|
|
||||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
|
||||||
|
|
||||||
.PHONY: epub3
|
|
||||||
epub3:
|
|
||||||
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
|
|
||||||
|
|
||||||
.PHONY: latex
|
|
||||||
latex:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
|
||||||
|
|
||||||
.PHONY: latexpdf
|
|
||||||
latexpdf:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
.PHONY: latexpdfja
|
|
||||||
latexpdfja:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
.PHONY: text
|
|
||||||
text:
|
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
|
||||||
|
|
||||||
.PHONY: man
|
|
||||||
man:
|
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
|
||||||
|
|
||||||
.PHONY: texinfo
|
|
||||||
texinfo:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
|
||||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
|
||||||
"(use \`make info' here to do that automatically)."
|
|
||||||
|
|
||||||
.PHONY: info
|
|
||||||
info:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo "Running Texinfo files through makeinfo..."
|
|
||||||
make -C $(BUILDDIR)/texinfo info
|
|
||||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
|
||||||
|
|
||||||
.PHONY: gettext
|
|
||||||
gettext:
|
|
||||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
|
||||||
|
|
||||||
.PHONY: changes
|
|
||||||
changes:
|
|
||||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
|
||||||
@echo
|
|
||||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
|
||||||
|
|
||||||
.PHONY: linkcheck
|
|
||||||
linkcheck:
|
|
||||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
|
||||||
@echo
|
|
||||||
@echo "Link check complete; look for any errors in the above output " \
|
|
||||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
|
||||||
|
|
||||||
.PHONY: doctest
|
|
||||||
doctest:
|
|
||||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
|
||||||
@echo "Testing of doctests in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/doctest/output.txt."
|
|
||||||
|
|
||||||
.PHONY: coverage
|
|
||||||
coverage:
|
|
||||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
|
||||||
@echo "Testing of coverage in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/coverage/python.txt."
|
|
||||||
|
|
||||||
.PHONY: xml
|
|
||||||
xml:
|
|
||||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
|
||||||
|
|
||||||
.PHONY: pseudoxml
|
|
||||||
pseudoxml:
|
|
||||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
|
||||||
|
|
||||||
.PHONY: dummy
|
|
||||||
dummy:
|
|
||||||
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. Dummy builder generates no files."
|
|
@ -1,74 +0,0 @@
|
|||||||
Asymmetric Key Algorithms
|
|
||||||
=========================
|
|
||||||
|
|
||||||
.. module:: wolfcrypt.ciphers
|
|
||||||
|
|
||||||
**Asymmetric key algorithms** are encryption algorithms that use **a pair
|
|
||||||
of cryptographic keys**, one for data encryption and signing and the other
|
|
||||||
one for data decryption and signature verification.
|
|
||||||
|
|
||||||
``wolfcrypt`` provides access to the following **Asymmetric Key Ciphers**:
|
|
||||||
|
|
||||||
Asymmetric Key Encryption Classes
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
.. autoclass:: RsaPublic
|
|
||||||
:members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoclass:: RsaPrivate
|
|
||||||
:members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
>>> from wolfcrypt.ciphers import RsaPrivate, RsaPublic
|
|
||||||
>>> from wolfcrypt.utils import h2b
|
|
||||||
>>>
|
|
||||||
>>> private = "3082025C02010002818100BC730EA849F374A2A9EF18A5DA559921F9C8ECB36D" \
|
|
||||||
... + "48E53535757737ECD161905F3ED9E4D5DF94CAC1A9D719DA86C9E84DC4613682" \
|
|
||||||
... + "FEABAD7E7725BB8D11A5BC623AA838CC39A20466B4F7F7F3AADA4D020EBB5E8D" \
|
|
||||||
... + "6948DC77C9280E22E96BA426BA4CE8C1FD4A6F2B1FEF8AAEF69062E5641EEB2B" \
|
|
||||||
... + "3C67C8DC2700F6916865A902030100010281801397EAE8387825A25C04CE0D40" \
|
|
||||||
... + "7C31E5C470CD9B823B5809863B665FDC3190F14FD5DB15DDDED73B9593311831" \
|
|
||||||
... + "0E5EA3D6A21A716E81481C4BCFDB8E7A866132DCFB55C1166D279224458BF1B8" \
|
|
||||||
... + "48B14B1DACDEDADD8E2FC291FBA5A96EF83A6AF1FD5018EF9FE7C3CA78EA56D3" \
|
|
||||||
... + "D3725B96DD4E064E3AC3D9BE72B66507074C01024100FA47D47A7C923C55EF81" \
|
|
||||||
... + "F041302DA3CF8F1CE6872705700DDF9835D6F18B382F24B5D084B6794F712994" \
|
|
||||||
... + "5AF0646AACE772C6ED4D59983E673AF3742CF9611769024100C0C1820D0CEBC6" \
|
|
||||||
... + "2FDC92F99D821A31E9E9F74BF282871CEE166AD11D188270F3C0B62FF6F3F71D" \
|
|
||||||
... + "F18623C84EEB8F568E8FF5BFF1F72BB5CC3DC657390C1B54410241009D7E05DE" \
|
|
||||||
... + "EDF4B7B2FBFC304B551DE32F0147966905CD0E2E2CBD8363B6AB7CB76DCA5B64" \
|
|
||||||
... + "A7CEBE86DF3B53DE61D21EEBA5F637EDACAB78D94CE755FBD71199C102401898" \
|
|
||||||
... + "1829E61E2739702168AC0A2FA172C121869538C65890A0579CBAE3A7B115C8DE" \
|
|
||||||
... + "F61BC2612376EFB09D1C44BE1343396717C89DCAFBF545648B38822CF2810240" \
|
|
||||||
... + "3989E59C195530BAB7488C48140EF49F7E779743E1B419353123759C3B44AD69" \
|
|
||||||
... + "1256EE0061641666D37C742B15B4A2FEBF086B1A5D3F9012B105863129DBD9E2"
|
|
||||||
>>>
|
|
||||||
>>> prv = RsaPrivate(h2b(private))
|
|
||||||
>>>
|
|
||||||
>>> public = "30819F300D06092A864886F70D010101050003818D0030818902818100BC730E" \
|
|
||||||
... + "A849F374A2A9EF18A5DA559921F9C8ECB36D48E53535757737ECD161905F3ED9" \
|
|
||||||
... + "E4D5DF94CAC1A9D719DA86C9E84DC4613682FEABAD7E7725BB8D11A5BC623AA8" \
|
|
||||||
... + "38CC39A20466B4F7F7F3AADA4D020EBB5E8D6948DC77C9280E22E96BA426BA4C" \
|
|
||||||
... + "E8C1FD4A6F2B1FEF8AAEF69062E5641EEB2B3C67C8DC2700F6916865A90203010001"
|
|
||||||
>>>
|
|
||||||
>>> pub = RsaPublic(h2b(public))
|
|
||||||
>>>
|
|
||||||
>>> plaintext = b"Everyone gets Friday off."
|
|
||||||
>>>
|
|
||||||
>>> ciphertext = pub.encrypt(plaintext)
|
|
||||||
>>> ciphertext # doctest: +SKIP
|
|
||||||
b'e\xb7\xc2\xad\x0c\x04.\xefU8\x17QB\x852\x03\x01\xef\xbe=\xb4\xaf\xaf\x97\x9e4\x96\x9f\xc3\x8e\x87\x9a8o$.|_e\x1d\xa2yi?\x83\x18\xf9Yr|\x1fQ\x1a\x18\x1e\xab\xd17\xc5\x8c\xae\x08c)\xbc\nIr\x8d\xc3\x88\x7f\xde\x1f\x1a^lB\r\xf1\xc0\xfd0\xdeA\xf3\xd2\xe5q\x9a0\xee\xb4,\x97\x80\xa4|U;\xe6\x11\xf0\xc2Q\x987\xe1>F\xf5\x14\x186@G~(Q\xf2;\xcb\x05\xee\x88\x0b\xd8\xa7'
|
|
||||||
>>>
|
|
||||||
>>> prv.decrypt(ciphertext)
|
|
||||||
b'Everyone gets Friday off.'
|
|
||||||
>>>
|
|
||||||
>>> signature = prv.sign(plaintext)
|
|
||||||
>>> signature # doctest: +SKIP
|
|
||||||
b'~\xc4\xe65\x15\xb17\x7fX\xaf,\xc2lw\xbd\x8f\t\x9d\xbf\xac\xdez\x90\xb4\x9f\x1aM\x88#Z\xea\xcb\xa6\xdb\x99\xf55\xd0\xfe|Mu\xb6\xb79(t\x81+h\xf2\xcd\x88v\xa8\xbaM\x86\xcfk\xe8\xf3\x0b\xb8\x8ew\xda>\xf8\xd5[H\xeaAh\xc6\xdaQlo]\xdd\xf8w\xe7#M-\x12f\xae,\xdd\xa6d FP<;R\xa2\x96hJ\xee_\x1fh\xaa\xc8\xdfAJ\xa5\xdd\x05\xc4\x89\x0c\xd7\xa0C\xb7u"U\x03'
|
|
||||||
>>>
|
|
||||||
>>> pub.verify(signature)
|
|
||||||
b'Everyone gets Friday off.'
|
|
@ -1,299 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# wolfcrypt documentation build configuration file, created by
|
|
||||||
# sphinx-quickstart on Fri Apr 29 16:47:53 2016.
|
|
||||||
#
|
|
||||||
# This file is execfile()d with the current directory set to its
|
|
||||||
# containing dir.
|
|
||||||
#
|
|
||||||
# Note that not all possible configuration values are present in this
|
|
||||||
# autogenerated file.
|
|
||||||
#
|
|
||||||
# All configuration values have a default; values that are commented out
|
|
||||||
# serve to show the default.
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import sphinx_rtd_theme
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
|
||||||
#needs_sphinx = '1.0'
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = [
|
|
||||||
'sphinx.ext.autodoc',
|
|
||||||
'sphinx.ext.doctest',
|
|
||||||
'sphinx.ext.coverage',
|
|
||||||
'sphinx.ext.viewcode',
|
|
||||||
'sphinx.ext.githubpages',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
|
||||||
|
|
||||||
# The suffix(es) of source filenames.
|
|
||||||
# You can specify multiple suffix as a list of string:
|
|
||||||
# source_suffix = ['.rst', '.md']
|
|
||||||
source_suffix = '.rst'
|
|
||||||
|
|
||||||
# The encoding of source files.
|
|
||||||
#source_encoding = 'utf-8-sig'
|
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = u'wolfcrypt'
|
|
||||||
copyright = u'2016, wolfSSL Inc. All rights reserved'
|
|
||||||
author = u'wolfSSL'
|
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
|
||||||
# |version| and |release|, also used in various other places throughout the
|
|
||||||
# built documents.
|
|
||||||
#
|
|
||||||
|
|
||||||
base_dir = os.path.join(os.path.dirname(__file__), os.pardir)
|
|
||||||
about = {}
|
|
||||||
with open(os.path.join(base_dir, "wolfcrypt", "__about__.py")) as f:
|
|
||||||
exec(f.read(), about)
|
|
||||||
|
|
||||||
version = release = about["__version__"]
|
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
||||||
# for a list of supported languages.
|
|
||||||
#
|
|
||||||
# This is also used if you do content translation via gettext catalogs.
|
|
||||||
# Usually you set "language" from the command line for these cases.
|
|
||||||
language = None
|
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
|
||||||
# non-false value, then it is used:
|
|
||||||
#today = ''
|
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
|
||||||
#today_fmt = '%B %d, %Y'
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
# This patterns also effect to html_static_path and html_extra_path
|
|
||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all
|
|
||||||
# documents.
|
|
||||||
#default_role = None
|
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
|
||||||
#add_function_parentheses = True
|
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description
|
|
||||||
# unit titles (such as .. function::).
|
|
||||||
#add_module_names = True
|
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
|
||||||
# output. They are ignored by default.
|
|
||||||
#show_authors = False
|
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
|
||||||
#modindex_common_prefix = []
|
|
||||||
|
|
||||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
|
||||||
#keep_warnings = False
|
|
||||||
|
|
||||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
|
||||||
todo_include_todos = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ----------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
|
||||||
# further. For a list of options available for each theme, see the
|
|
||||||
# documentation.
|
|
||||||
#html_theme_options = {}
|
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
|
||||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
|
||||||
|
|
||||||
# The name for this set of Sphinx documents.
|
|
||||||
# "<project> v<release> documentation" by default.
|
|
||||||
#html_title = u'%s v%s' % (project, release)
|
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
||||||
#html_short_title = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
|
||||||
# of the sidebar.
|
|
||||||
#html_logo = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to use as a favicon of
|
|
||||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
|
||||||
# pixels large.
|
|
||||||
#html_favicon = None
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
|
||||||
# directly to the root of the documentation.
|
|
||||||
#html_extra_path = []
|
|
||||||
|
|
||||||
# If not None, a 'Last updated on:' timestamp is inserted at every page
|
|
||||||
# bottom, using the given strftime format.
|
|
||||||
# The empty string is equivalent to '%b %d, %Y'.
|
|
||||||
#html_last_updated_fmt = None
|
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
||||||
# typographically correct entities.
|
|
||||||
#html_use_smartypants = True
|
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
#html_sidebars = {}
|
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
|
||||||
# template names.
|
|
||||||
#html_additional_pages = {}
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#html_domain_indices = True
|
|
||||||
|
|
||||||
# If false, no index is generated.
|
|
||||||
#html_use_index = True
|
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter.
|
|
||||||
#html_split_index = False
|
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages.
|
|
||||||
#html_show_sourcelink = True
|
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_sphinx = True
|
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_copyright = True
|
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will
|
|
||||||
# contain a <link> tag referring to it. The value of this option must be the
|
|
||||||
# base URL from which the finished HTML is served.
|
|
||||||
#html_use_opensearch = ''
|
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
|
||||||
#html_file_suffix = None
|
|
||||||
|
|
||||||
# Language to be used for generating the HTML full-text search index.
|
|
||||||
# Sphinx supports the following languages:
|
|
||||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
|
||||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
|
|
||||||
#html_search_language = 'en'
|
|
||||||
|
|
||||||
# A dictionary with options for the search language support, empty by default.
|
|
||||||
# 'ja' uses this config value.
|
|
||||||
# 'zh' user can custom change `jieba` dictionary path.
|
|
||||||
#html_search_options = {'type': 'default'}
|
|
||||||
|
|
||||||
# The name of a javascript file (relative to the configuration directory) that
|
|
||||||
# implements a search results scorer. If empty, the default will be used.
|
|
||||||
#html_search_scorer = 'scorer.js'
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
htmlhelp_basename = 'wolfcrypt-pydoc'
|
|
||||||
|
|
||||||
# -- Options for LaTeX output ---------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
|
||||||
#'papersize': 'letterpaper',
|
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
|
||||||
#'pointsize': '10pt',
|
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
|
||||||
#'preamble': '',
|
|
||||||
|
|
||||||
# Latex figure (float) alignment
|
|
||||||
#'figure_align': 'htbp',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title,
|
|
||||||
# author, documentclass [howto, manual, or own class]).
|
|
||||||
latex_documents = [
|
|
||||||
(master_doc, 'wolfcrypt.tex', u'wolfcrypt Python Documentation',
|
|
||||||
u'wolfSSL', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
|
||||||
# the title page.
|
|
||||||
#latex_logo = None
|
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
||||||
# not chapters.
|
|
||||||
#latex_use_parts = False
|
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
|
||||||
#latex_show_pagerefs = False
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#latex_show_urls = False
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#latex_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#latex_domain_indices = True
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output ---------------------------------------
|
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
|
||||||
# (source start file, name, description, authors, manual section).
|
|
||||||
man_pages = [
|
|
||||||
(master_doc, 'wolfcrypt', u'wolfcrypt Python Documentation',
|
|
||||||
[author], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#man_show_urls = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output -------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree into Texinfo files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# dir menu entry, description, category)
|
|
||||||
texinfo_documents = [
|
|
||||||
(master_doc, 'wolfcrypt', u'wolfcrypt Python Documentation',
|
|
||||||
author, 'wolfcrypt', 'One line description of project.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#texinfo_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#texinfo_domain_indices = True
|
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
|
||||||
#texinfo_show_urls = 'footnote'
|
|
||||||
|
|
||||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
|
||||||
#texinfo_no_detailmenu = False
|
|
||||||
|
|
||||||
# Preserves the order of the members, doesn't sorts them alphabetically.
|
|
||||||
autodoc_member_order = 'bysource'
|
|
@ -1,71 +0,0 @@
|
|||||||
Message Digests
|
|
||||||
===============
|
|
||||||
|
|
||||||
.. module:: wolfcrypt.hashes
|
|
||||||
|
|
||||||
A **message digest** is the output of a **cryptographic hash function**
|
|
||||||
containing a string of bytes created by a **one-way formula** using the
|
|
||||||
original message as input.
|
|
||||||
|
|
||||||
Message digests are designed to protect the integrity of a piece of data or
|
|
||||||
media to detect changes and alterations to any part of a message.
|
|
||||||
|
|
||||||
|
|
||||||
Hashing Classes
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Interface
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
All Hashing Functions available in this module implements the following
|
|
||||||
interface:
|
|
||||||
|
|
||||||
.. autoclass:: _Hash
|
|
||||||
:members:
|
|
||||||
|
|
||||||
SHA-1
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
.. attention::
|
|
||||||
|
|
||||||
NIST has deprecated SHA-1 in favor of the SHA-2 variants. New applications
|
|
||||||
are strongly suggested to use SHA-2 over SHA-1.
|
|
||||||
|
|
||||||
.. autoclass:: Sha
|
|
||||||
|
|
||||||
SHA-2 family
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: Sha256
|
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: Sha384
|
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: Sha512
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> from wolfcrypt.hashes import Sha256
|
|
||||||
>>>
|
|
||||||
>>> s = Sha256()
|
|
||||||
>>> s.update(b'wolf')
|
|
||||||
>>> s.update(b'crypt')
|
|
||||||
>>> s.digest()
|
|
||||||
b'\x96\xe0.{\x1c\xbc\xd6\xf1\x04\xfe\x1f\xdbFR\x02zU\x05\xb6\x86R\xb7\x00\x95\xc61\x8f\x9d\xce\r\x18D'
|
|
||||||
>>> s.hexdigest()
|
|
||||||
b'96e02e7b1cbcd6f104fe1fdb4652027a5505b68652b70095c6318f9dce0d1844'
|
|
||||||
>>>
|
|
||||||
>>> s.update(b'rocks')
|
|
||||||
>>> s.hexdigest()
|
|
||||||
b'e1a50df419d65715c48316bdc6a6f7f0485f4b26c1b107228faf17988b61c83f'
|
|
||||||
>>>
|
|
||||||
>>> Sha256(b'wolfcryptrocks').hexdigest()
|
|
||||||
b'e1a50df419d65715c48316bdc6a6f7f0485f4b26c1b107228faf17988b61c83f'
|
|
||||||
>>>
|
|
||||||
>>> Sha256.new(b'wolfcryptrocks').hexdigest()
|
|
||||||
b'e1a50df419d65715c48316bdc6a6f7f0485f4b26c1b107228faf17988b61c83f'
|
|
@ -1,15 +0,0 @@
|
|||||||
.. include:: ../README.rst
|
|
||||||
|
|
||||||
Summary
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
symmetric
|
|
||||||
asymmetric
|
|
||||||
digest
|
|
||||||
mac
|
|
||||||
random
|
|
||||||
|
|
||||||
.. include:: ../LICENSING.rst
|
|
@ -1,74 +0,0 @@
|
|||||||
Message Authentication Codes
|
|
||||||
============================
|
|
||||||
|
|
||||||
.. module:: wolfcrypt.hashes
|
|
||||||
|
|
||||||
A **message authentication code** (MAC) is a short piece of information used
|
|
||||||
to authenticate a message — in other words, to confirm that the message came
|
|
||||||
from the stated sender (its authenticity) and has not been changed in transit
|
|
||||||
(its integrity).
|
|
||||||
|
|
||||||
``wolfcrypt`` implements the **Hash-based message authentication code** (HMAC),
|
|
||||||
which uses a cryptographic hash function coupled with a secret key to produce
|
|
||||||
**message authentication codes**.
|
|
||||||
|
|
||||||
|
|
||||||
Hmac Classes
|
|
||||||
------------
|
|
||||||
|
|
||||||
Interface
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
All Hmac classes available in this module implements the following
|
|
||||||
interface:
|
|
||||||
|
|
||||||
.. autoclass:: _Hmac
|
|
||||||
:members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
SHA-1
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
.. attention::
|
|
||||||
|
|
||||||
NIST has deprecated SHA-1 in favor of the SHA-2 variants. New applications
|
|
||||||
are strongly suggested to use SHA-2 over SHA-1.
|
|
||||||
|
|
||||||
.. autoclass:: HmacSha
|
|
||||||
|
|
||||||
SHA-2 family
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: HmacSha256
|
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: HmacSha384
|
|
||||||
|
|
||||||
|
|
||||||
.. autoclass:: HmacSha512
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> from wolfcrypt.hashes import HmacSha256
|
|
||||||
>>>
|
|
||||||
>>> h = HmacSha256('secret')
|
|
||||||
>>> h.update("wolf")
|
|
||||||
>>> h.update("crypt")
|
|
||||||
>>> h.digest()
|
|
||||||
b'\x18\xbf*\t9\xa2o\xdf\\\xc8\xe0\xc2U\x94,\x8dY\x02;\x1c<Q\xdf\x8d\xdb\x863\xfb\xc1f#o'
|
|
||||||
>>> h.hexdigest()
|
|
||||||
b'18bf2a0939a26fdf5cc8e0c255942c8d59023b1c3c51df8ddb8633fbc166236f'
|
|
||||||
>>>
|
|
||||||
>>> h.update("rocks")
|
|
||||||
>>> h.hexdigest()
|
|
||||||
b'85dc8c1995d20b17942d52773d8a597d028ad958e5736beafb59a4742f63889e'
|
|
||||||
>>>
|
|
||||||
>>> HmacSha256('secret', 'wolfcryptrocks').hexdigest()
|
|
||||||
b'85dc8c1995d20b17942d52773d8a597d028ad958e5736beafb59a4742f63889e'
|
|
||||||
>>>
|
|
||||||
>>> HmacSha256.new('secret', 'wolfcryptrocks').hexdigest()
|
|
||||||
b'85dc8c1995d20b17942d52773d8a597d028ad958e5736beafb59a4742f63889e'
|
|
@ -1,30 +0,0 @@
|
|||||||
Random Number Generation
|
|
||||||
========================
|
|
||||||
|
|
||||||
A **cryptographically secure pseudo-random number generator** (CSPRNG) is a
|
|
||||||
**pseudo-random number generator** (PRNG) with properties that make it suitable
|
|
||||||
for use in cryptography.
|
|
||||||
|
|
||||||
Using the standard random module APIs for cryptographic keys or initialization
|
|
||||||
vectors can result in major security issues depending on the algorithms in use.
|
|
||||||
|
|
||||||
``wolfcrypt`` provides the following CSPRNG implementation:
|
|
||||||
|
|
||||||
.. module:: wolfcrypt.random
|
|
||||||
|
|
||||||
.. autoclass:: Random
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
>>> from wolfcrypt.random import Random
|
|
||||||
>>>
|
|
||||||
>>> r = Random()
|
|
||||||
>>> b = r.byte()
|
|
||||||
>>> b # doctest: +SKIP
|
|
||||||
b'\x8c'
|
|
||||||
>>> b16 = r.bytes(16)
|
|
||||||
>>> b16 # doctest: +SKIP
|
|
||||||
b']\x93nk\x95\xbc@\xffX\xab\xdcB\xda\x11\xf7\x03'
|
|
@ -1,42 +0,0 @@
|
|||||||
Symmetric Key Algorithms
|
|
||||||
========================
|
|
||||||
|
|
||||||
.. module:: wolfcrypt.ciphers
|
|
||||||
|
|
||||||
**Symmetric key algorithms** are encryption algorithms that use the **same
|
|
||||||
cryptographic keys** for both encryption and decryption of data.
|
|
||||||
This operation is also known as **Symmetric Key Encryption**.
|
|
||||||
|
|
||||||
``wolfcrypt`` provides access to the following **Symmetric Key Ciphers**:
|
|
||||||
|
|
||||||
Symmetric Key Encryption Classes
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Interface
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
All **Symmetric Key Ciphers** available in this module implements the following
|
|
||||||
interface:
|
|
||||||
|
|
||||||
.. autoclass:: _Cipher
|
|
||||||
:members:
|
|
||||||
|
|
||||||
Classes
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: Aes
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> from wolfcrypt.ciphers import Aes, MODE_CBC
|
|
||||||
>>>
|
|
||||||
>>> cipher = Aes(b'0123456789abcdef', MODE_CBC, b'1234567890abcdef')
|
|
||||||
>>> ciphertext = cipher.encrypt('now is the time ')
|
|
||||||
>>> ciphertext
|
|
||||||
b'\x95\x94\x92W_B\x81S,\xcc\x9dFw\xa23\xcb'
|
|
||||||
>>> cipher.decrypt(ciphertext)
|
|
||||||
b'now is the time '
|
|
@ -1,30 +0,0 @@
|
|||||||
# vim:ft=automake
|
|
||||||
# included from Top Level Makefile.am
|
|
||||||
# All paths should be given relative to the root
|
|
||||||
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/.gitignore
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/asymmetric.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/conf.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/digest.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/index.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/mac.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/Makefile
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/random.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/docs/symmetric.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/LICENSING.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/MANIFEST.in
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/README.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/requirements-testing.txt
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/setup.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/test/test_ciphers.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/test/test_hashes.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/test/test_random.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/tox.ini
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/__about__.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/__init__.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/build_ffi.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/ciphers.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/exceptions.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/hashes.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/random.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfcrypt/wolfcrypt/utils.py
|
|
@ -1,3 +0,0 @@
|
|||||||
pytest>=2.9.1
|
|
||||||
cffi>=1.6.0
|
|
||||||
tox>=2.3.1
|
|
@ -1,57 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# Python 2.7 Standard Library
|
|
||||||
from __future__ import absolute_import
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from wolfcrypt.__about__ import metadata
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
os.chdir(os.path.dirname(sys.argv[0]) or ".")
|
|
||||||
|
|
||||||
long_description = open("README.rst", "rt").read().replace(
|
|
||||||
".. include:: LICENSING.rst\n",
|
|
||||||
open("LICENSING.rst", "rt").read()
|
|
||||||
)
|
|
||||||
|
|
||||||
info = dict(
|
|
||||||
metadata = {k[2:-2]: metadata[k] for k in metadata},
|
|
||||||
contents = {
|
|
||||||
"long_description": long_description,
|
|
||||||
"package_data": {"": ["*.txt"]},
|
|
||||||
"packages": find_packages(),
|
|
||||||
"cffi_modules": ["./wolfcrypt/build_ffi.py:ffi"],
|
|
||||||
},
|
|
||||||
requirements = {
|
|
||||||
"setup_requires": ["cffi>=1.6.0"],
|
|
||||||
"install_requires": ["cffi>=1.6.0"],
|
|
||||||
},
|
|
||||||
scripts = {},
|
|
||||||
plugins = {},
|
|
||||||
tests = {},
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
kwargs = {k:v for dct in info.values() for (k,v) in dct.items()}
|
|
||||||
setup(**kwargs)
|
|
@ -1,193 +0,0 @@
|
|||||||
# test_ciphers.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
import unittest
|
|
||||||
from wolfcrypt.ciphers import *
|
|
||||||
from wolfcrypt.utils import t2b, h2b
|
|
||||||
|
|
||||||
|
|
||||||
class TestAes(unittest.TestCase):
|
|
||||||
key = "0123456789abcdef"
|
|
||||||
IV = "1234567890abcdef"
|
|
||||||
plain = t2b("now is the time ")
|
|
||||||
cipher = h2b("959492575f4281532ccc9d4677a233cb")
|
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.aes = Aes.new(self.key, MODE_CBC, self.IV)
|
|
||||||
|
|
||||||
|
|
||||||
def test_raises(self):
|
|
||||||
# invalid key length
|
|
||||||
self.assertRaises(ValueError, Aes.new, "key", MODE_CBC, self.IV)
|
|
||||||
|
|
||||||
# invalid mode
|
|
||||||
self.assertRaises(ValueError, Aes.new, self.key, MODE_ECB, self.IV)
|
|
||||||
|
|
||||||
# invalid iv length
|
|
||||||
self.assertRaises(ValueError, Aes.new, self.key, MODE_CBC, "IV")
|
|
||||||
|
|
||||||
# invalid data length
|
|
||||||
self.assertRaises(ValueError, self.aes.encrypt, "foo")
|
|
||||||
self.assertRaises(ValueError, self.aes.decrypt, "bar")
|
|
||||||
|
|
||||||
|
|
||||||
def test_single_encryption(self):
|
|
||||||
assert self.aes.encrypt(self.plain) == self.cipher
|
|
||||||
|
|
||||||
|
|
||||||
def test_multi_encryption(self):
|
|
||||||
result = t2b("")
|
|
||||||
segments = tuple(self.plain[i:i + self.aes.block_size] \
|
|
||||||
for i in range(0, len(self.plain), self.aes.block_size))
|
|
||||||
|
|
||||||
for segment in segments:
|
|
||||||
result += self.aes.encrypt(segment)
|
|
||||||
|
|
||||||
assert result == self.cipher
|
|
||||||
|
|
||||||
|
|
||||||
def test_single_decryption(self):
|
|
||||||
assert self.aes.decrypt(self.cipher) == self.plain
|
|
||||||
|
|
||||||
|
|
||||||
def test_multi_decryption(self):
|
|
||||||
result = t2b("")
|
|
||||||
segments = tuple(self.cipher[i:i + self.aes.block_size] \
|
|
||||||
for i in range(0, len(self.cipher), self.aes.block_size))
|
|
||||||
|
|
||||||
for segment in segments:
|
|
||||||
result += self.aes.decrypt(segment)
|
|
||||||
|
|
||||||
assert result == self.plain
|
|
||||||
|
|
||||||
|
|
||||||
class TestRsaPrivate(unittest.TestCase):
|
|
||||||
key = "3082025C02010002818100BC730EA849F374A2A9EF18A5DA559921F9C8ECB36D" \
|
|
||||||
+ "48E53535757737ECD161905F3ED9E4D5DF94CAC1A9D719DA86C9E84DC4613682" \
|
|
||||||
+ "FEABAD7E7725BB8D11A5BC623AA838CC39A20466B4F7F7F3AADA4D020EBB5E8D" \
|
|
||||||
+ "6948DC77C9280E22E96BA426BA4CE8C1FD4A6F2B1FEF8AAEF69062E5641EEB2B" \
|
|
||||||
+ "3C67C8DC2700F6916865A902030100010281801397EAE8387825A25C04CE0D40" \
|
|
||||||
+ "7C31E5C470CD9B823B5809863B665FDC3190F14FD5DB15DDDED73B9593311831" \
|
|
||||||
+ "0E5EA3D6A21A716E81481C4BCFDB8E7A866132DCFB55C1166D279224458BF1B8" \
|
|
||||||
+ "48B14B1DACDEDADD8E2FC291FBA5A96EF83A6AF1FD5018EF9FE7C3CA78EA56D3" \
|
|
||||||
+ "D3725B96DD4E064E3AC3D9BE72B66507074C01024100FA47D47A7C923C55EF81" \
|
|
||||||
+ "F041302DA3CF8F1CE6872705700DDF9835D6F18B382F24B5D084B6794F712994" \
|
|
||||||
+ "5AF0646AACE772C6ED4D59983E673AF3742CF9611769024100C0C1820D0CEBC6" \
|
|
||||||
+ "2FDC92F99D821A31E9E9F74BF282871CEE166AD11D188270F3C0B62FF6F3F71D" \
|
|
||||||
+ "F18623C84EEB8F568E8FF5BFF1F72BB5CC3DC657390C1B54410241009D7E05DE" \
|
|
||||||
+ "EDF4B7B2FBFC304B551DE32F0147966905CD0E2E2CBD8363B6AB7CB76DCA5B64" \
|
|
||||||
+ "A7CEBE86DF3B53DE61D21EEBA5F637EDACAB78D94CE755FBD71199C102401898" \
|
|
||||||
+ "1829E61E2739702168AC0A2FA172C121869538C65890A0579CBAE3A7B115C8DE" \
|
|
||||||
+ "F61BC2612376EFB09D1C44BE1343396717C89DCAFBF545648B38822CF2810240" \
|
|
||||||
+ "3989E59C195530BAB7488C48140EF49F7E779743E1B419353123759C3B44AD69" \
|
|
||||||
+ "1256EE0061641666D37C742B15B4A2FEBF086B1A5D3F9012B105863129DBD9E2"
|
|
||||||
|
|
||||||
plain = t2b("Everyone gets Friday off.")
|
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.rsa = RsaPrivate(h2b(self.key))
|
|
||||||
|
|
||||||
|
|
||||||
def test_raises(self):
|
|
||||||
# invalid key
|
|
||||||
self.assertRaises(WolfCryptError, RsaPrivate, 'key')
|
|
||||||
|
|
||||||
|
|
||||||
def test_output_size(self):
|
|
||||||
assert self.rsa.output_size == 1024 / 8
|
|
||||||
|
|
||||||
|
|
||||||
def test_encrypt_decrypt(self):
|
|
||||||
cipher = self.rsa.encrypt(self.plain)
|
|
||||||
result = self.rsa.decrypt(cipher)
|
|
||||||
|
|
||||||
assert len(cipher) == self.rsa.output_size == 1024 / 8
|
|
||||||
assert self.plain == result
|
|
||||||
|
|
||||||
|
|
||||||
def test_sign_verify(self):
|
|
||||||
signature = self.rsa.sign(self.plain)
|
|
||||||
result = self.rsa.verify(signature)
|
|
||||||
|
|
||||||
assert len(signature) == self.rsa.output_size == 1024 / 8
|
|
||||||
assert self.plain == result
|
|
||||||
|
|
||||||
|
|
||||||
class TestRsaPublic(unittest.TestCase):
|
|
||||||
prv = "3082025C02010002818100BC730EA849F374A2A9EF18A5DA559921F9C8ECB36D" \
|
|
||||||
+ "48E53535757737ECD161905F3ED9E4D5DF94CAC1A9D719DA86C9E84DC4613682" \
|
|
||||||
+ "FEABAD7E7725BB8D11A5BC623AA838CC39A20466B4F7F7F3AADA4D020EBB5E8D" \
|
|
||||||
+ "6948DC77C9280E22E96BA426BA4CE8C1FD4A6F2B1FEF8AAEF69062E5641EEB2B" \
|
|
||||||
+ "3C67C8DC2700F6916865A902030100010281801397EAE8387825A25C04CE0D40" \
|
|
||||||
+ "7C31E5C470CD9B823B5809863B665FDC3190F14FD5DB15DDDED73B9593311831" \
|
|
||||||
+ "0E5EA3D6A21A716E81481C4BCFDB8E7A866132DCFB55C1166D279224458BF1B8" \
|
|
||||||
+ "48B14B1DACDEDADD8E2FC291FBA5A96EF83A6AF1FD5018EF9FE7C3CA78EA56D3" \
|
|
||||||
+ "D3725B96DD4E064E3AC3D9BE72B66507074C01024100FA47D47A7C923C55EF81" \
|
|
||||||
+ "F041302DA3CF8F1CE6872705700DDF9835D6F18B382F24B5D084B6794F712994" \
|
|
||||||
+ "5AF0646AACE772C6ED4D59983E673AF3742CF9611769024100C0C1820D0CEBC6" \
|
|
||||||
+ "2FDC92F99D821A31E9E9F74BF282871CEE166AD11D188270F3C0B62FF6F3F71D" \
|
|
||||||
+ "F18623C84EEB8F568E8FF5BFF1F72BB5CC3DC657390C1B54410241009D7E05DE" \
|
|
||||||
+ "EDF4B7B2FBFC304B551DE32F0147966905CD0E2E2CBD8363B6AB7CB76DCA5B64" \
|
|
||||||
+ "A7CEBE86DF3B53DE61D21EEBA5F637EDACAB78D94CE755FBD71199C102401898" \
|
|
||||||
+ "1829E61E2739702168AC0A2FA172C121869538C65890A0579CBAE3A7B115C8DE" \
|
|
||||||
+ "F61BC2612376EFB09D1C44BE1343396717C89DCAFBF545648B38822CF2810240" \
|
|
||||||
+ "3989E59C195530BAB7488C48140EF49F7E779743E1B419353123759C3B44AD69" \
|
|
||||||
+ "1256EE0061641666D37C742B15B4A2FEBF086B1A5D3F9012B105863129DBD9E2"
|
|
||||||
|
|
||||||
pub = "30819F300D06092A864886F70D010101050003818D0030818902818100BC730E" \
|
|
||||||
+ "A849F374A2A9EF18A5DA559921F9C8ECB36D48E53535757737ECD161905F3ED9" \
|
|
||||||
+ "E4D5DF94CAC1A9D719DA86C9E84DC4613682FEABAD7E7725BB8D11A5BC623AA8" \
|
|
||||||
+ "38CC39A20466B4F7F7F3AADA4D020EBB5E8D6948DC77C9280E22E96BA426BA4C" \
|
|
||||||
+ "E8C1FD4A6F2B1FEF8AAEF69062E5641EEB2B3C67C8DC2700F6916865A90203010001"
|
|
||||||
|
|
||||||
plain = t2b("Everyone gets Friday off.")
|
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.private = RsaPrivate(h2b(self.prv))
|
|
||||||
self.public = RsaPublic(h2b(self.pub))
|
|
||||||
|
|
||||||
|
|
||||||
def test_raises(self):
|
|
||||||
# invalid key
|
|
||||||
self.assertRaises(WolfCryptError, RsaPublic, 'key')
|
|
||||||
|
|
||||||
|
|
||||||
def test_output_size(self):
|
|
||||||
assert self.public.output_size == 1024 / 8
|
|
||||||
|
|
||||||
|
|
||||||
def test_encrypt_decrypt(self):
|
|
||||||
cipher = self.public.encrypt(self.plain)
|
|
||||||
result = self.private.decrypt(cipher)
|
|
||||||
|
|
||||||
assert len(cipher) == self.public.output_size == 1024 / 8
|
|
||||||
assert self.plain == result
|
|
||||||
|
|
||||||
|
|
||||||
def test_sign_verify(self):
|
|
||||||
signature = self.private.sign(self.plain)
|
|
||||||
result = self.public.verify(signature)
|
|
||||||
|
|
||||||
assert len(signature) == self.public.output_size == 1024 / 8
|
|
||||||
assert self.plain == result
|
|
@ -1,151 +0,0 @@
|
|||||||
# test_hashes.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
import unittest
|
|
||||||
from wolfcrypt.hashes import *
|
|
||||||
from wolfcrypt.utils import t2b, h2b
|
|
||||||
|
|
||||||
|
|
||||||
class TestSha(unittest.TestCase):
|
|
||||||
_class = Sha
|
|
||||||
digest = t2b("1b6182d68ae91ce0853bd9c6b6edfedd4b6a510d")
|
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.hash = self._class()
|
|
||||||
|
|
||||||
|
|
||||||
def test_new(self):
|
|
||||||
# update inside constructor
|
|
||||||
assert self._class.new("wolfcrypt").hexdigest() == self.digest
|
|
||||||
|
|
||||||
|
|
||||||
def test_hash_update_001(self):
|
|
||||||
self.hash.update("wolfcrypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == self.digest
|
|
||||||
assert self.hash.digest() == h2b(self.digest)
|
|
||||||
|
|
||||||
|
|
||||||
def test_hash_update_002(self):
|
|
||||||
self.hash.update("wolf")
|
|
||||||
self.hash.update("crypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == self.digest
|
|
||||||
assert self.hash.digest() == h2b(self.digest)
|
|
||||||
|
|
||||||
|
|
||||||
def test_hash_copy(self):
|
|
||||||
copy = self.hash.copy()
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == copy.hexdigest()
|
|
||||||
|
|
||||||
self.hash.update("wolfcrypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() != copy.hexdigest()
|
|
||||||
|
|
||||||
copy.update("wolfcrypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == copy.hexdigest() == self.digest
|
|
||||||
|
|
||||||
|
|
||||||
class TestSha256(TestSha):
|
|
||||||
_class = Sha256
|
|
||||||
digest = t2b("96e02e7b1cbcd6f104fe1fdb4652027a" \
|
|
||||||
+ "5505b68652b70095c6318f9dce0d1844")
|
|
||||||
|
|
||||||
|
|
||||||
class TestSha384(TestSha):
|
|
||||||
_class = Sha384
|
|
||||||
digest = t2b("4c79d80531203a16f91bee325f18c6aada47f9382fe44fc1" \
|
|
||||||
+ "1f92917837e9b7902f5dccb7d3656f667a1dce3460bc884b")
|
|
||||||
|
|
||||||
|
|
||||||
class TestSha512(TestSha):
|
|
||||||
_class = Sha512
|
|
||||||
digest = t2b("88fcf67ffd8558d713f9cedcd852db47" \
|
|
||||||
+ "9e6573f0bd9955610a993f609637553c" \
|
|
||||||
+ "e8fff55e644ee8a106aae19c07f91b3f" \
|
|
||||||
+ "2a2a6d40dfa7302c0fa6a1a9a5bfa03f")
|
|
||||||
|
|
||||||
|
|
||||||
_HMAC_KEY = "python"
|
|
||||||
|
|
||||||
|
|
||||||
class TestHmacSha(unittest.TestCase):
|
|
||||||
_class = HmacSha
|
|
||||||
digest = t2b("5dfabcfb3a25540824867cd21f065f52f73491e0")
|
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.hash = self._class(_HMAC_KEY)
|
|
||||||
|
|
||||||
|
|
||||||
def test_new(self):
|
|
||||||
# update inside constructor
|
|
||||||
assert self._class.new(_HMAC_KEY,"wolfcrypt").hexdigest() == self.digest
|
|
||||||
|
|
||||||
|
|
||||||
def test_hash_update_001(self):
|
|
||||||
self.hash.update("wolfcrypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == self.digest
|
|
||||||
|
|
||||||
|
|
||||||
def test_hash_update_002(self):
|
|
||||||
self.hash.update("wolf")
|
|
||||||
self.hash.update("crypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == self.digest
|
|
||||||
|
|
||||||
|
|
||||||
def test_hash_copy(self):
|
|
||||||
copy = self.hash.copy()
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == copy.hexdigest()
|
|
||||||
|
|
||||||
self.hash.update("wolfcrypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() != copy.hexdigest()
|
|
||||||
|
|
||||||
copy.update("wolfcrypt")
|
|
||||||
|
|
||||||
assert self.hash.hexdigest() == copy.hexdigest() == self.digest
|
|
||||||
|
|
||||||
|
|
||||||
class TestHmacSha256(TestHmacSha):
|
|
||||||
_class = HmacSha256
|
|
||||||
digest = t2b("4b641d721493d80f019d9447830ebfee" \
|
|
||||||
+ "89234a7d594378b89f8bb73873576bf6")
|
|
||||||
|
|
||||||
|
|
||||||
class TestHmacSha384(TestHmacSha):
|
|
||||||
_class = HmacSha384
|
|
||||||
digest = t2b("e72c72070c9c5c78e3286593068a510c1740cdf9dc34b512" \
|
|
||||||
+ "ccec97320295db1fe673216b46fe72e81f399a9ec04780ab")
|
|
||||||
|
|
||||||
|
|
||||||
class TestHmacSha512(TestHmacSha):
|
|
||||||
_class = HmacSha512
|
|
||||||
digest = t2b("c7f48db79314fc2b5be9a93fd58601a1" \
|
|
||||||
+ "bf42f397ec7f66dba034d44503890e6b" \
|
|
||||||
+ "5708242dcd71a248a78162d815c685f6" \
|
|
||||||
+ "038a4ac8cb34b8bf18986dbd300c9b41")
|
|
@ -1,40 +0,0 @@
|
|||||||
# test_random.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
import unittest
|
|
||||||
from wolfcrypt.random import *
|
|
||||||
|
|
||||||
|
|
||||||
class TestRandom(unittest.TestCase):
|
|
||||||
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.random = Random()
|
|
||||||
|
|
||||||
|
|
||||||
def test_byte(self):
|
|
||||||
assert len(self.random.byte()) == 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_bytes(self):
|
|
||||||
assert len(self.random.bytes(1)) == 1
|
|
||||||
assert len(self.random.bytes(10)) == 10
|
|
||||||
assert len(self.random.bytes(100)) == 100
|
|
@ -1,7 +0,0 @@
|
|||||||
[tox]
|
|
||||||
envlist=py27,py34,py35
|
|
||||||
skip_missing_interpreters=true
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
deps=-rrequirements-testing.txt
|
|
||||||
commands=py.test test/
|
|
@ -1,47 +0,0 @@
|
|||||||
# __about__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
metadata = dict(
|
|
||||||
__name__ = "wolfcrypt",
|
|
||||||
__version__ = "0.1.9",
|
|
||||||
__license__ = "GPLv2 or Commercial License",
|
|
||||||
__author__ = "wolfSSL Inc.",
|
|
||||||
__author_email__ = "info@wolfssl.com",
|
|
||||||
__url__ = "https://wolfssl.github.io/wolfcrypt-py",
|
|
||||||
__description__ = \
|
|
||||||
u"A Python library that encapsulates wolfSSL's wolfCrypt API.",
|
|
||||||
__keywords__ = "security, cryptography, ssl, embedded, embedded ssl",
|
|
||||||
__classifiers__ = [
|
|
||||||
u"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
|
|
||||||
u"License :: Other/Proprietary License",
|
|
||||||
u"Operating System :: OS Independent",
|
|
||||||
u"Programming Language :: Python :: 2.7",
|
|
||||||
u"Programming Language :: Python :: 3.5",
|
|
||||||
u"Topic :: Security",
|
|
||||||
u"Topic :: Security :: Cryptography",
|
|
||||||
u"Topic :: Software Development"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
globals().update(metadata)
|
|
||||||
|
|
||||||
__all__ = list(metadata.keys())
|
|
@ -1,23 +0,0 @@
|
|||||||
# __init__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
from .__about__ import *
|
|
@ -1,129 +0,0 @@
|
|||||||
# build_ffi.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
import os
|
|
||||||
|
|
||||||
from cffi import FFI
|
|
||||||
|
|
||||||
ffi = FFI()
|
|
||||||
|
|
||||||
ffi.set_source("wolfcrypt._ffi",
|
|
||||||
"""
|
|
||||||
#include <wolfssl/options.h>
|
|
||||||
|
|
||||||
#include <wolfssl/wolfcrypt/sha.h>
|
|
||||||
#include <wolfssl/wolfcrypt/sha256.h>
|
|
||||||
#include <wolfssl/wolfcrypt/sha512.h>
|
|
||||||
|
|
||||||
#include <wolfssl/wolfcrypt/hmac.h>
|
|
||||||
|
|
||||||
#include <wolfssl/wolfcrypt/aes.h>
|
|
||||||
#include <wolfssl/wolfcrypt/des3.h>
|
|
||||||
#include <wolfssl/wolfcrypt/asn.h>
|
|
||||||
|
|
||||||
#include <wolfssl/wolfcrypt/random.h>
|
|
||||||
|
|
||||||
#include <wolfssl/wolfcrypt/rsa.h>
|
|
||||||
""",
|
|
||||||
include_dirs=["/usr/local/include"],
|
|
||||||
library_dirs=["/usr/local/lib"],
|
|
||||||
libraries=["wolfssl"],
|
|
||||||
)
|
|
||||||
|
|
||||||
ffi.cdef(
|
|
||||||
"""
|
|
||||||
|
|
||||||
typedef unsigned char byte;
|
|
||||||
typedef unsigned int word32;
|
|
||||||
|
|
||||||
typedef struct { ...; } Sha;
|
|
||||||
|
|
||||||
int wc_InitSha(Sha*);
|
|
||||||
int wc_ShaUpdate(Sha*, const byte*, word32);
|
|
||||||
int wc_ShaFinal(Sha*, byte*);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct { ...; } Sha256;
|
|
||||||
|
|
||||||
int wc_InitSha256(Sha256*);
|
|
||||||
int wc_Sha256Update(Sha256*, const byte*, word32);
|
|
||||||
int wc_Sha256Final(Sha256*, byte*);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct { ...; } Sha384;
|
|
||||||
|
|
||||||
int wc_InitSha384(Sha384*);
|
|
||||||
int wc_Sha384Update(Sha384*, const byte*, word32);
|
|
||||||
int wc_Sha384Final(Sha384*, byte*);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct { ...; } Sha512;
|
|
||||||
|
|
||||||
int wc_InitSha512(Sha512*);
|
|
||||||
int wc_Sha512Update(Sha512*, const byte*, word32);
|
|
||||||
int wc_Sha512Final(Sha512*, byte*);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct { ...; } Hmac;
|
|
||||||
|
|
||||||
int wc_HmacSetKey(Hmac*, int, const byte*, word32);
|
|
||||||
int wc_HmacUpdate(Hmac*, const byte*, word32);
|
|
||||||
int wc_HmacFinal(Hmac*, byte*);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct { ...; } Aes;
|
|
||||||
|
|
||||||
int wc_AesSetKey(Aes*, const byte*, word32, const byte*, int);
|
|
||||||
int wc_AesCbcEncrypt(Aes*, byte*, const byte*, word32);
|
|
||||||
int wc_AesCbcDecrypt(Aes*, byte*, const byte*, word32);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct { ...; } WC_RNG;
|
|
||||||
|
|
||||||
int wc_InitRng(WC_RNG*);
|
|
||||||
int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32);
|
|
||||||
int wc_RNG_GenerateByte(WC_RNG*, byte*);
|
|
||||||
int wc_FreeRng(WC_RNG*);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {...; } RsaKey;
|
|
||||||
|
|
||||||
int wc_InitRsaKey(RsaKey* key, void*);
|
|
||||||
int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
|
|
||||||
int wc_FreeRsaKey(RsaKey* key);
|
|
||||||
|
|
||||||
int wc_RsaPrivateKeyDecode(const byte*, word32*, RsaKey*, word32);
|
|
||||||
int wc_RsaPublicKeyDecode(const byte*, word32*, RsaKey*, word32);
|
|
||||||
int wc_RsaEncryptSize(RsaKey*);
|
|
||||||
|
|
||||||
int wc_RsaPrivateDecrypt(const byte*, word32, byte*, word32,
|
|
||||||
RsaKey* key);
|
|
||||||
int wc_RsaPublicEncrypt(const byte*, word32, byte*, word32,
|
|
||||||
RsaKey*, WC_RNG*);
|
|
||||||
|
|
||||||
int wc_RsaSSL_Sign(const byte*, word32, byte*, word32, RsaKey*, WC_RNG*);
|
|
||||||
int wc_RsaSSL_Verify(const byte*, word32, byte*, word32, RsaKey*);
|
|
||||||
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
ffi.compile(verbose=1)
|
|
@ -1,327 +0,0 @@
|
|||||||
# ciphers.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
from wolfcrypt._ffi import ffi as _ffi
|
|
||||||
from wolfcrypt._ffi import lib as _lib
|
|
||||||
from wolfcrypt.utils import t2b
|
|
||||||
from wolfcrypt.random import Random
|
|
||||||
|
|
||||||
from wolfcrypt.exceptions import *
|
|
||||||
|
|
||||||
|
|
||||||
# key direction flags
|
|
||||||
_ENCRYPTION = 0
|
|
||||||
_DECRYPTION = 1
|
|
||||||
|
|
||||||
|
|
||||||
# feedback modes
|
|
||||||
MODE_ECB = 1 # Electronic Code Book
|
|
||||||
MODE_CBC = 2 # Cipher Block Chaining
|
|
||||||
MODE_CFB = 3 # Cipher Feedback
|
|
||||||
MODE_OFB = 5 # Output Feedback
|
|
||||||
MODE_CTR = 6 # Counter
|
|
||||||
|
|
||||||
_FEEDBACK_MODES = [MODE_ECB, MODE_CBC, MODE_CFB, MODE_OFB, MODE_CTR]
|
|
||||||
|
|
||||||
|
|
||||||
class _Cipher(object):
|
|
||||||
"""
|
|
||||||
A **PEP 272: Block Encryption Algorithms** compliant
|
|
||||||
**Symmetric Key Cipher**.
|
|
||||||
"""
|
|
||||||
def __init__(self, key, mode, IV=None):
|
|
||||||
if mode not in _FEEDBACK_MODES:
|
|
||||||
raise ValueError("this mode is not supported")
|
|
||||||
|
|
||||||
if mode == MODE_CBC:
|
|
||||||
if IV is None:
|
|
||||||
raise ValueError("this mode requires an 'IV' string")
|
|
||||||
else:
|
|
||||||
raise ValueError("this mode is not supported by this cipher")
|
|
||||||
|
|
||||||
if self.key_size:
|
|
||||||
if self.key_size != len(key):
|
|
||||||
raise ValueError("key must be %d in length" % self.key_size)
|
|
||||||
elif self._key_sizes:
|
|
||||||
if len(key) not in self._key_sizes:
|
|
||||||
raise ValueError("key must be %s in length" % self._key_sizes)
|
|
||||||
else:
|
|
||||||
if not len(key):
|
|
||||||
raise ValueError("key must not be 0 in length")
|
|
||||||
|
|
||||||
if IV is not None and len(IV) != self.block_size:
|
|
||||||
raise ValueError("IV must be %d in length" % self.block_size)
|
|
||||||
|
|
||||||
self._native_object = _ffi.new(self._native_type)
|
|
||||||
self._enc = None
|
|
||||||
self._dec = None
|
|
||||||
self._key = t2b(key)
|
|
||||||
|
|
||||||
if IV:
|
|
||||||
self._IV = t2b(IV)
|
|
||||||
else:
|
|
||||||
self._IV = t2b("\0" * self.block_size)
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def new(cls, key, mode, IV=None, **kwargs):
|
|
||||||
"""
|
|
||||||
Returns a ciphering object, using the secret key contained in
|
|
||||||
the string **key**, and using the feedback mode **mode**, which
|
|
||||||
must be one of MODE_* defined in this module.
|
|
||||||
|
|
||||||
If **mode** is MODE_CBC or MODE_CFB, **IV** must be provided and
|
|
||||||
must be a string of the same length as the block size. Not
|
|
||||||
providing a value of **IV** will result in a ValueError exception
|
|
||||||
being raised.
|
|
||||||
"""
|
|
||||||
return cls(key, mode, IV)
|
|
||||||
|
|
||||||
|
|
||||||
def encrypt(self, string):
|
|
||||||
"""
|
|
||||||
Encrypts a non-empty string, using the key-dependent data in
|
|
||||||
the object, and with the appropriate feedback mode. The
|
|
||||||
string's length must be an exact multiple of the algorithm's
|
|
||||||
block size or, in CFB mode, of the segment size. Returns a
|
|
||||||
string containing the ciphertext.
|
|
||||||
"""
|
|
||||||
string = t2b(string)
|
|
||||||
|
|
||||||
if not string or len(string) % self.block_size:
|
|
||||||
raise ValueError(
|
|
||||||
"string must be a multiple of %d in length" % self.block_size)
|
|
||||||
|
|
||||||
if self._enc is None:
|
|
||||||
self._enc = _ffi.new(self._native_type)
|
|
||||||
ret = self._set_key(_ENCRYPTION)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % ret)
|
|
||||||
|
|
||||||
result = t2b("\0" * len(string))
|
|
||||||
ret = self._encrypt(result, string)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Encryption error (%d)" % ret)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def decrypt(self, string):
|
|
||||||
"""
|
|
||||||
Decrypts **string**, using the key-dependent data in the
|
|
||||||
object and with the appropriate feedback mode. The string's
|
|
||||||
length must be an exact multiple of the algorithm's block
|
|
||||||
size or, in CFB mode, of the segment size. Returns a string
|
|
||||||
containing the plaintext.
|
|
||||||
"""
|
|
||||||
string = t2b(string)
|
|
||||||
|
|
||||||
if not string or len(string) % self.block_size:
|
|
||||||
raise ValueError(
|
|
||||||
"string must be a multiple of %d in length" % self.block_size)
|
|
||||||
|
|
||||||
if self._dec is None:
|
|
||||||
self._dec = _ffi.new(self._native_type)
|
|
||||||
ret = self._set_key(_DECRYPTION)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % ret)
|
|
||||||
|
|
||||||
result = t2b("\0" * len(string))
|
|
||||||
ret = self._decrypt(result, string)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Decryption error (%d)" % ret)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class Aes(_Cipher):
|
|
||||||
"""
|
|
||||||
The **Advanced Encryption Standard** (AES), a.k.a. Rijndael, is
|
|
||||||
a symmetric-key cipher standardized by **NIST**.
|
|
||||||
"""
|
|
||||||
block_size = 16
|
|
||||||
key_size = None # 16, 24, 32
|
|
||||||
_key_sizes = [16, 24, 32]
|
|
||||||
_native_type = "Aes *"
|
|
||||||
|
|
||||||
|
|
||||||
def _set_key(self, direction):
|
|
||||||
if direction == _ENCRYPTION:
|
|
||||||
return _lib.wc_AesSetKey(
|
|
||||||
self._enc, self._key, len(self._key), self._IV, _ENCRYPTION)
|
|
||||||
else:
|
|
||||||
return _lib.wc_AesSetKey(
|
|
||||||
self._dec, self._key, len(self._key), self._IV, _DECRYPTION)
|
|
||||||
|
|
||||||
|
|
||||||
def _encrypt(self, destination, source):
|
|
||||||
return _lib.wc_AesCbcEncrypt(self._enc, destination, source,len(source))
|
|
||||||
|
|
||||||
|
|
||||||
def _decrypt(self, destination, source):
|
|
||||||
return _lib.wc_AesCbcDecrypt(self._dec, destination, source,len(source))
|
|
||||||
|
|
||||||
|
|
||||||
class _Rsa(object):
|
|
||||||
RSA_MIN_PAD_SIZE = 11
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.native_object = _ffi.new("RsaKey *")
|
|
||||||
ret = _lib.wc_InitRsaKey(self.native_object, _ffi.NULL)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % ret)
|
|
||||||
|
|
||||||
self._random = Random()
|
|
||||||
ret = _lib.wc_RsaSetRNG(self.native_object, self._random.native_object)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Key initialization error (%d)" % ret)
|
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self.native_object:
|
|
||||||
_lib.wc_FreeRsaKey(self.native_object)
|
|
||||||
|
|
||||||
|
|
||||||
class RsaPublic(_Rsa):
|
|
||||||
def __init__(self, key):
|
|
||||||
key = t2b(key)
|
|
||||||
|
|
||||||
_Rsa.__init__(self)
|
|
||||||
|
|
||||||
idx = _ffi.new("word32*")
|
|
||||||
idx[0] = 0
|
|
||||||
|
|
||||||
ret = _lib.wc_RsaPublicKeyDecode(key, idx, self.native_object, len(key))
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % ret)
|
|
||||||
|
|
||||||
self.output_size = _lib.wc_RsaEncryptSize(self.native_object)
|
|
||||||
if self.output_size <= 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % self.output_size)
|
|
||||||
|
|
||||||
|
|
||||||
def encrypt(self, plaintext):
|
|
||||||
"""
|
|
||||||
Encrypts **plaintext**, using the public key data in the
|
|
||||||
object. The plaintext's length must not be greater than:
|
|
||||||
|
|
||||||
**self.output_size - self.RSA_MIN_PAD_SIZE**
|
|
||||||
|
|
||||||
Returns a string containing the ciphertext.
|
|
||||||
"""
|
|
||||||
|
|
||||||
plaintext = t2b(plaintext)
|
|
||||||
ciphertext = t2b("\0" * self.output_size)
|
|
||||||
|
|
||||||
ret = _lib.wc_RsaPublicEncrypt(plaintext, len(plaintext),
|
|
||||||
ciphertext, len(ciphertext),
|
|
||||||
self.native_object,
|
|
||||||
self._random.native_object)
|
|
||||||
|
|
||||||
if ret != self.output_size:
|
|
||||||
raise WolfCryptError("Encryption error (%d)" % ret)
|
|
||||||
|
|
||||||
return ciphertext
|
|
||||||
|
|
||||||
|
|
||||||
def verify(self, signature):
|
|
||||||
"""
|
|
||||||
Verifies **signature**, using the public key data in the
|
|
||||||
object. The signature's length must be equal to:
|
|
||||||
|
|
||||||
**self.output_size**
|
|
||||||
|
|
||||||
Returns a string containing the plaintext.
|
|
||||||
"""
|
|
||||||
signature = t2b(signature)
|
|
||||||
plaintext = t2b("\0" * self.output_size)
|
|
||||||
|
|
||||||
ret = _lib.wc_RsaSSL_Verify(signature, len(signature),
|
|
||||||
plaintext, len(plaintext),
|
|
||||||
self.native_object)
|
|
||||||
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Verify error (%d)" % ret)
|
|
||||||
|
|
||||||
return plaintext[:ret]
|
|
||||||
|
|
||||||
|
|
||||||
class RsaPrivate(RsaPublic):
|
|
||||||
def __init__(self, key):
|
|
||||||
key = t2b(key)
|
|
||||||
|
|
||||||
_Rsa.__init__(self)
|
|
||||||
|
|
||||||
idx = _ffi.new("word32*")
|
|
||||||
idx[0] = 0
|
|
||||||
|
|
||||||
ret = _lib.wc_RsaPrivateKeyDecode(key, idx, self.native_object,len(key))
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % ret)
|
|
||||||
|
|
||||||
self.output_size = _lib.wc_RsaEncryptSize(self.native_object)
|
|
||||||
if self.output_size <= 0:
|
|
||||||
raise WolfCryptError("Invalid key error (%d)" % self.output_size)
|
|
||||||
|
|
||||||
|
|
||||||
def decrypt(self, ciphertext):
|
|
||||||
"""
|
|
||||||
Decrypts **ciphertext**, using the private key data in the
|
|
||||||
object. The ciphertext's length must be equal to:
|
|
||||||
|
|
||||||
**self.output_size**
|
|
||||||
|
|
||||||
Returns a string containing the plaintext.
|
|
||||||
"""
|
|
||||||
ciphertext = t2b(ciphertext)
|
|
||||||
plaintext = t2b("\0" * self.output_size)
|
|
||||||
|
|
||||||
ret = _lib.wc_RsaPrivateDecrypt(ciphertext, len(ciphertext),
|
|
||||||
plaintext, len(plaintext),
|
|
||||||
self.native_object)
|
|
||||||
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Decryption error (%d)" % ret)
|
|
||||||
|
|
||||||
return plaintext[:ret]
|
|
||||||
|
|
||||||
|
|
||||||
def sign(self, plaintext):
|
|
||||||
"""
|
|
||||||
Signs **plaintext**, using the private key data in the object.
|
|
||||||
The plaintext's length must not be greater than:
|
|
||||||
|
|
||||||
**self.output_size - self.RSA_MIN_PAD_SIZE**
|
|
||||||
|
|
||||||
Returns a string containing the signature.
|
|
||||||
"""
|
|
||||||
plaintext = t2b(plaintext)
|
|
||||||
signature = t2b("\0" * self.output_size)
|
|
||||||
|
|
||||||
ret = _lib.wc_RsaSSL_Sign(plaintext, len(plaintext),
|
|
||||||
signature, len(signature),
|
|
||||||
self.native_object,
|
|
||||||
self._random.native_object)
|
|
||||||
|
|
||||||
if ret != self.output_size:
|
|
||||||
raise WolfCryptError("Signature error (%d)" % ret)
|
|
||||||
|
|
||||||
return signature
|
|
@ -1,25 +0,0 @@
|
|||||||
# exceptions.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
|
|
||||||
class WolfCryptError(Exception):
|
|
||||||
pass
|
|
@ -1,304 +0,0 @@
|
|||||||
# hashes.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
from wolfcrypt._ffi import ffi as _ffi
|
|
||||||
from wolfcrypt._ffi import lib as _lib
|
|
||||||
from wolfcrypt.utils import t2b, b2h
|
|
||||||
|
|
||||||
from wolfcrypt.exceptions import *
|
|
||||||
|
|
||||||
class _Hash(object):
|
|
||||||
"""
|
|
||||||
A **PEP 247: Cryptographic Hash Functions** compliant
|
|
||||||
**Hash Function Interface**.
|
|
||||||
"""
|
|
||||||
def __init__(self, string=None):
|
|
||||||
self._native_object = _ffi.new(self._native_type)
|
|
||||||
ret = self._init()
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Hash init error (%d)" % ret)
|
|
||||||
|
|
||||||
if (string):
|
|
||||||
self.update(string)
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def new(cls, string=None):
|
|
||||||
"""
|
|
||||||
Creates a new hashing object and returns it. The optional
|
|
||||||
**string** parameter, if supplied, will be immediately
|
|
||||||
hashed into the object's starting state, as if
|
|
||||||
obj.update(string) was called.
|
|
||||||
"""
|
|
||||||
return cls(string)
|
|
||||||
|
|
||||||
|
|
||||||
def copy(self):
|
|
||||||
"""
|
|
||||||
Returns a separate copy of this hashing object. An update
|
|
||||||
to this copy won't affect the original object.
|
|
||||||
"""
|
|
||||||
copy = self.new("")
|
|
||||||
|
|
||||||
_ffi.memmove(copy._native_object,
|
|
||||||
self._native_object,
|
|
||||||
self._native_size)
|
|
||||||
|
|
||||||
return copy
|
|
||||||
|
|
||||||
|
|
||||||
def update(self, string):
|
|
||||||
"""
|
|
||||||
Hashes **string** into the current state of the hashing
|
|
||||||
object. update() can be called any number of times during
|
|
||||||
a hashing object's lifetime.
|
|
||||||
"""
|
|
||||||
string = t2b(string)
|
|
||||||
|
|
||||||
ret = self._update(string)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Hash update error (%d)" % ret)
|
|
||||||
|
|
||||||
|
|
||||||
def digest(self):
|
|
||||||
"""
|
|
||||||
Returns the hash value of this hashing object as a string
|
|
||||||
containing 8-bit data. The object is not altered in any
|
|
||||||
way by this function; you can continue updating the object
|
|
||||||
after calling this function.
|
|
||||||
"""
|
|
||||||
result = t2b("\0" * self.digest_size)
|
|
||||||
|
|
||||||
if self._native_object:
|
|
||||||
obj = _ffi.new(self._native_type)
|
|
||||||
|
|
||||||
_ffi.memmove(obj, self._native_object, self._native_size)
|
|
||||||
|
|
||||||
ret = self._final(obj, result)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Hash finalize error (%d)" % ret)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def hexdigest(self):
|
|
||||||
"""
|
|
||||||
Returns the hash value of this hashing object as a string
|
|
||||||
containing hexadecimal digits. Lowercase letters are used
|
|
||||||
for the digits 'a' through 'f'. Like the .digest() method,
|
|
||||||
this method doesn't alter the object.
|
|
||||||
"""
|
|
||||||
return b2h(self.digest())
|
|
||||||
|
|
||||||
|
|
||||||
class Sha(_Hash):
|
|
||||||
"""
|
|
||||||
**SHA-1** is a cryptographic hash function standardized by **NIST**.
|
|
||||||
|
|
||||||
It produces an [ **160-bit | 20 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
digest_size = 20
|
|
||||||
_native_type = "Sha *"
|
|
||||||
_native_size = _ffi.sizeof("Sha")
|
|
||||||
|
|
||||||
|
|
||||||
def _init(self):
|
|
||||||
return _lib.wc_InitSha(self._native_object)
|
|
||||||
|
|
||||||
|
|
||||||
def _update(self, data):
|
|
||||||
return _lib.wc_ShaUpdate(self._native_object, data, len(data))
|
|
||||||
|
|
||||||
|
|
||||||
def _final(self, obj, ret):
|
|
||||||
return _lib.wc_ShaFinal(obj, ret)
|
|
||||||
|
|
||||||
|
|
||||||
class Sha256(_Hash):
|
|
||||||
"""
|
|
||||||
**SHA-256** is a cryptographic hash function from the
|
|
||||||
**SHA-2 family** and is standardized by **NIST**.
|
|
||||||
|
|
||||||
It produces a [ **256-bit | 32 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
digest_size = 32
|
|
||||||
_native_type = "Sha256 *"
|
|
||||||
_native_size = _ffi.sizeof("Sha256")
|
|
||||||
|
|
||||||
|
|
||||||
def _init(self):
|
|
||||||
return _lib.wc_InitSha256(self._native_object)
|
|
||||||
|
|
||||||
|
|
||||||
def _update(self, data):
|
|
||||||
return _lib.wc_Sha256Update(self._native_object, data, len(data))
|
|
||||||
|
|
||||||
|
|
||||||
def _final(self, obj, ret):
|
|
||||||
return _lib.wc_Sha256Final(obj, ret)
|
|
||||||
|
|
||||||
|
|
||||||
class Sha384(_Hash):
|
|
||||||
"""
|
|
||||||
**SHA-384** is a cryptographic hash function from the
|
|
||||||
**SHA-2 family** and is standardized by **NIST**.
|
|
||||||
|
|
||||||
It produces a [ **384-bit | 48 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
digest_size = 48
|
|
||||||
_native_type = "Sha384 *"
|
|
||||||
_native_size = _ffi.sizeof("Sha384")
|
|
||||||
|
|
||||||
|
|
||||||
def _init(self):
|
|
||||||
return _lib.wc_InitSha384(self._native_object)
|
|
||||||
|
|
||||||
|
|
||||||
def _update(self, data):
|
|
||||||
return _lib.wc_Sha384Update(self._native_object, data, len(data))
|
|
||||||
|
|
||||||
|
|
||||||
def _final(self, obj, ret):
|
|
||||||
return _lib.wc_Sha384Final(obj, ret)
|
|
||||||
|
|
||||||
|
|
||||||
class Sha512(_Hash):
|
|
||||||
"""
|
|
||||||
**SHA-512** is a cryptographic hash function from the
|
|
||||||
**SHA-2 family** and is standardized by **NIST**.
|
|
||||||
|
|
||||||
It produces a [ **512-bit | 64 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
digest_size = 64
|
|
||||||
_native_type = "Sha512 *"
|
|
||||||
_native_size = _ffi.sizeof("Sha512")
|
|
||||||
|
|
||||||
|
|
||||||
def _init(self):
|
|
||||||
return _lib.wc_InitSha512(self._native_object)
|
|
||||||
|
|
||||||
|
|
||||||
def _update(self, data):
|
|
||||||
return _lib.wc_Sha512Update(self._native_object, data, len(data))
|
|
||||||
|
|
||||||
|
|
||||||
def _final(self, obj, ret):
|
|
||||||
return _lib.wc_Sha512Final(obj, ret)
|
|
||||||
|
|
||||||
|
|
||||||
# Hmac types
|
|
||||||
|
|
||||||
_TYPE_SHA = 1
|
|
||||||
_TYPE_SHA256 = 2
|
|
||||||
_TYPE_SHA384 = 5
|
|
||||||
_TYPE_SHA512 = 4
|
|
||||||
_HMAC_TYPES = [_TYPE_SHA, _TYPE_SHA256, _TYPE_SHA384, _TYPE_SHA512]
|
|
||||||
|
|
||||||
|
|
||||||
class _Hmac(_Hash):
|
|
||||||
"""
|
|
||||||
A **PEP 247: Cryptographic Hash Functions** compliant
|
|
||||||
**Keyed Hash Function Interface**.
|
|
||||||
"""
|
|
||||||
digest_size = None
|
|
||||||
_native_type = "Hmac *"
|
|
||||||
_native_size = _ffi.sizeof("Hmac")
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, key, string=None):
|
|
||||||
key = t2b(key)
|
|
||||||
|
|
||||||
self._native_object = _ffi.new(self._native_type)
|
|
||||||
ret = self._init(self._type, key)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("Hmac init error (%d)" % ret)
|
|
||||||
|
|
||||||
if (string):
|
|
||||||
self.update(string)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def new(cls, key, string=None):
|
|
||||||
"""
|
|
||||||
Creates a new hashing object and returns it. **key** is
|
|
||||||
a required parameter containing a string giving the key
|
|
||||||
to use. The optional **string** parameter, if supplied,
|
|
||||||
will be immediately hashed into the object's starting
|
|
||||||
state, as if obj.update(string) was called.
|
|
||||||
"""
|
|
||||||
return cls(key, string)
|
|
||||||
|
|
||||||
|
|
||||||
def _init(self, type, key):
|
|
||||||
return _lib.wc_HmacSetKey(self._native_object, type, key, len(key))
|
|
||||||
|
|
||||||
|
|
||||||
def _update(self, data):
|
|
||||||
return _lib.wc_HmacUpdate(self._native_object, data, len(data))
|
|
||||||
|
|
||||||
|
|
||||||
def _final(self, obj, ret):
|
|
||||||
return _lib.wc_HmacFinal(obj, ret)
|
|
||||||
|
|
||||||
|
|
||||||
class HmacSha(_Hmac):
|
|
||||||
"""
|
|
||||||
A HMAC function using **SHA-1** as it's cryptographic
|
|
||||||
hash function.
|
|
||||||
|
|
||||||
It produces a [ **512-bit | 64 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
_type = _TYPE_SHA
|
|
||||||
digest_size = Sha.digest_size
|
|
||||||
|
|
||||||
|
|
||||||
class HmacSha256(_Hmac):
|
|
||||||
"""
|
|
||||||
A HMAC function using **SHA-256** as it's cryptographic
|
|
||||||
hash function.
|
|
||||||
|
|
||||||
It produces a [ **512-bit | 64 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
_type = _TYPE_SHA256
|
|
||||||
digest_size = Sha256.digest_size
|
|
||||||
|
|
||||||
|
|
||||||
class HmacSha384(_Hmac):
|
|
||||||
"""
|
|
||||||
A HMAC function using **SHA-384** as it's cryptographic
|
|
||||||
hash function.
|
|
||||||
|
|
||||||
It produces a [ **512-bit | 64 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
_type = _TYPE_SHA384
|
|
||||||
digest_size = Sha384.digest_size
|
|
||||||
|
|
||||||
|
|
||||||
class HmacSha512(_Hmac):
|
|
||||||
"""
|
|
||||||
A HMAC function using **SHA-512** as it's cryptographic
|
|
||||||
hash function.
|
|
||||||
|
|
||||||
It produces a [ **512-bit | 64 bytes** ] message digest.
|
|
||||||
"""
|
|
||||||
_type = _TYPE_SHA512
|
|
||||||
digest_size = Sha512.digest_size
|
|
@ -1,74 +0,0 @@
|
|||||||
# random.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
from wolfcrypt._ffi import ffi as _ffi
|
|
||||||
from wolfcrypt._ffi import lib as _lib
|
|
||||||
from wolfcrypt.utils import t2b
|
|
||||||
|
|
||||||
from wolfcrypt.exceptions import *
|
|
||||||
|
|
||||||
|
|
||||||
class Random(object):
|
|
||||||
"""
|
|
||||||
A Cryptographically Secure Pseudo Random Number Generator - CSPRNG
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self.native_object = _ffi.new("WC_RNG *")
|
|
||||||
|
|
||||||
ret = _lib.wc_InitRng(self.native_object)
|
|
||||||
if ret < 0:
|
|
||||||
self.native_object = None
|
|
||||||
raise WolfCryptError("RNG init error (%d)" % ret)
|
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self.native_object:
|
|
||||||
try:
|
|
||||||
_lib.wc_FreeRng(self.native_object)
|
|
||||||
except AttributeError:
|
|
||||||
# Can occur during interpreter shutdown
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def byte(self):
|
|
||||||
"""
|
|
||||||
Generate and return a random byte.
|
|
||||||
"""
|
|
||||||
result = _ffi.new('byte[1]')
|
|
||||||
|
|
||||||
ret = _lib.wc_RNG_GenerateByte(self.native_object, result)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("RNG generate byte error (%d)" % ret)
|
|
||||||
|
|
||||||
return _ffi.buffer(result, 1)[:]
|
|
||||||
|
|
||||||
|
|
||||||
def bytes(self, length):
|
|
||||||
"""
|
|
||||||
Generate and return a random sequence of length bytes.
|
|
||||||
"""
|
|
||||||
result = _ffi.new('byte[%d]' % length)
|
|
||||||
|
|
||||||
ret = _lib.wc_RNG_GenerateBlock(self.native_object, result, length)
|
|
||||||
if ret < 0:
|
|
||||||
raise WolfCryptError("RNG generate block error (%d)" % ret)
|
|
||||||
|
|
||||||
return _ffi.buffer(result, length)[:]
|
|
@ -1,38 +0,0 @@
|
|||||||
# utils.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=unused-import, undefined-variable
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from binascii import hexlify as b2h, unhexlify as h2b
|
|
||||||
|
|
||||||
_PY3 = sys.version_info[0] == 3
|
|
||||||
_TEXT_TYPE = str if _PY3 else unicode
|
|
||||||
_BINARY_TYPE = bytes if _PY3 else str
|
|
||||||
|
|
||||||
def t2b(string):
|
|
||||||
"""
|
|
||||||
Converts text to bynary.
|
|
||||||
"""
|
|
||||||
if isinstance(string, _BINARY_TYPE):
|
|
||||||
return string
|
|
||||||
return _TEXT_TYPE(string).encode("utf-8")
|
|
@ -1,40 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
[ "$(whoami)" != "root" ] && echo "Sorry, you are not root." && exit 1
|
|
||||||
|
|
||||||
rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
|
||||||
|
|
||||||
yum install -y \
|
|
||||||
git autoconf libtool libffi-devel python-devel python34-devel python2-pip
|
|
||||||
|
|
||||||
pip install -U pip setuptools
|
|
||||||
|
|
||||||
git clone --depth 1 https://github.com/wolfssl/wolfssl.git
|
|
||||||
[ $? -ne 0 ] && echo "\n\nCouldn't download wolfssl.\n\n" && exit 1
|
|
||||||
|
|
||||||
pushd wolfssl
|
|
||||||
|
|
||||||
./autogen.sh
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
echo /usr/local/lib > wolfssl.conf
|
|
||||||
mv wolfssl.conf /etc/ld.so.conf
|
|
||||||
ldconfig
|
|
||||||
|
|
||||||
popd
|
|
||||||
|
|
||||||
rm -rf wolfssl
|
|
||||||
|
|
||||||
pushd /vagrant
|
|
||||||
|
|
||||||
pip install -r requirements-testing.txt
|
|
||||||
|
|
||||||
make clean
|
|
||||||
|
|
||||||
tox -epy27,py34 -- -v
|
|
||||||
|
|
||||||
popd
|
|
||||||
|
|
||||||
# pip install wolfssl
|
|
||||||
# [ $? -ne 0 ] && echo "\n\nCouldn't install wolfssl.\n\n" && exit 1
|
|
21
wrapper/python/wolfssl/.gitignore
vendored
21
wrapper/python/wolfssl/.gitignore
vendored
@ -1,21 +0,0 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
|
|
||||||
# Distribution
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
.eggs/
|
|
||||||
*.egg-info/
|
|
||||||
|
|
||||||
# Unit test
|
|
||||||
.tox/
|
|
||||||
htmlcov/
|
|
||||||
.coverage
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# Certificates
|
|
||||||
certs/
|
|
@ -1,38 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
[ "$(whoami)" != "root" ] && echo "Sorry, you are not root." && exit 1
|
|
||||||
|
|
||||||
apt-get update
|
|
||||||
|
|
||||||
apt-get install -y \
|
|
||||||
git autoconf libtool python-dev python3-dev python-pip libffi-dev
|
|
||||||
|
|
||||||
pip install -U pip setuptools
|
|
||||||
|
|
||||||
git clone --depth 1 https://github.com/wolfssl/wolfssl.git
|
|
||||||
[ $? -ne 0 ] && echo "\n\nCouldn't download wolfssl.\n\n" && exit 1
|
|
||||||
|
|
||||||
pushd wolfssl
|
|
||||||
|
|
||||||
./autogen.sh
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
ldconfig
|
|
||||||
|
|
||||||
popd
|
|
||||||
|
|
||||||
rm -rf wolfssl
|
|
||||||
|
|
||||||
pushd /vagrant
|
|
||||||
|
|
||||||
pip install -r requirements-testing.txt
|
|
||||||
|
|
||||||
make clean
|
|
||||||
|
|
||||||
tox -epy27,py34 -- -v
|
|
||||||
|
|
||||||
popd
|
|
||||||
|
|
||||||
# pip install wolfssl
|
|
||||||
# [ $? -ne 0 ] && echo -e "\n\nCouldn't install wolfssl.\n\n" && exit 1
|
|
@ -1,23 +0,0 @@
|
|||||||
Licensing
|
|
||||||
=========
|
|
||||||
|
|
||||||
wolfSSL’s software is available under two distinct licensing models:
|
|
||||||
open source and standard commercial licensing. Please see the relevant
|
|
||||||
section below for information on each type of license.
|
|
||||||
|
|
||||||
Open Source
|
|
||||||
-----------
|
|
||||||
|
|
||||||
wolfCrypt and wolfSSL software are free software downloads and may be modified
|
|
||||||
to the needs of the user as long as the user adheres to version two of the GPL
|
|
||||||
License. The GPLv2 license can be found on the `gnu.org website
|
|
||||||
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>`_.
|
|
||||||
|
|
||||||
Commercial Licensing
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Businesses and enterprises who wish to incorporate wolfSSL products into
|
|
||||||
proprietary appliances or other commercial software products for
|
|
||||||
re-distribution must license commercial versions. Licenses are generally
|
|
||||||
issued for one product and include unlimited royalty-free distribution.
|
|
||||||
Custom licensing terms are also available at licensing@wolfssl.com.
|
|
@ -1,2 +0,0 @@
|
|||||||
include LICENSING.rst
|
|
||||||
recursive-include certs *.pem
|
|
@ -1,60 +0,0 @@
|
|||||||
# Makefile
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
.PHONY : all clean clean-test clean-build clean-pyc install test check upload
|
|
||||||
|
|
||||||
# builds the module
|
|
||||||
all :
|
|
||||||
python ./setup.py build
|
|
||||||
|
|
||||||
#builds and installs the module
|
|
||||||
install : all
|
|
||||||
python ./setup.py install
|
|
||||||
|
|
||||||
## removes all build, test, coverage and Python artifacts
|
|
||||||
clean : clean-test clean-build clean-pyc
|
|
||||||
|
|
||||||
## removes test and coverage artifacts
|
|
||||||
clean-test :
|
|
||||||
rm -rf .coverage .tox/ htmlcov/
|
|
||||||
|
|
||||||
## removes build artifacts
|
|
||||||
clean-build :
|
|
||||||
rm -rf build/ dist/ .eggs/
|
|
||||||
find . -name '*.egg-info' -exec rm -rf {} +
|
|
||||||
find . -name '*.egg' -exec rm -v {} +
|
|
||||||
|
|
||||||
## removes Python file artifacts
|
|
||||||
clean-pyc :
|
|
||||||
find src test -name '__pycache__' -exec rm -rf {} +
|
|
||||||
find src test -name '*.pyc' -exec rm -f {} +
|
|
||||||
find src test -name '*.pyo' -exec rm -f {} +
|
|
||||||
|
|
||||||
# runs unit tests
|
|
||||||
check : test
|
|
||||||
|
|
||||||
test : clean-pyc
|
|
||||||
tox
|
|
||||||
|
|
||||||
# publishes module at pypi
|
|
||||||
upload : test
|
|
||||||
python ./setup.py sdist upload
|
|
@ -1,96 +0,0 @@
|
|||||||
Welcome
|
|
||||||
=======
|
|
||||||
|
|
||||||
``wolfssl Python`` is a Python module that encapsulates ``wolfssl C``, a `lightweight C-language-based SSL/TLS library <https://wolfssl.com/wolfSSL/Products-wolfssl.html>`_ targeted for embedded, RTOS, or
|
|
||||||
resource-constrained environments primarily because of its small size, speed,
|
|
||||||
and portability.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
In order to use ``wolfssl Python``, you'll also need to install ``wolfssl C``.
|
|
||||||
|
|
||||||
Mac OSX
|
|
||||||
-------
|
|
||||||
|
|
||||||
Installing from ``homebrew`` and ``pip`` package managers:
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
# wolfssl C installation
|
|
||||||
brew install wolfssl
|
|
||||||
|
|
||||||
# wolfssl Python installation
|
|
||||||
sudo -H pip install wolfssl
|
|
||||||
|
|
||||||
Installing from ``source code``:
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
# wolfssl C installation
|
|
||||||
git clone https://github.com/wolfssl/wolfssl.git
|
|
||||||
cd wolfssl/
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-sha512
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
# wolfssl Python installation
|
|
||||||
cd wrapper/python/wolfssl
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
|
|
||||||
Linux
|
|
||||||
-----
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
# dependencies installation
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y git autoconf libtool
|
|
||||||
sudo apt-get install -y python-dev python3-dev python-pip libffi-dev
|
|
||||||
|
|
||||||
# wolfssl C installation
|
|
||||||
git clone https://github.com/wolfssl/wolfssl.git
|
|
||||||
cd wolfssl/
|
|
||||||
./autogen.sh
|
|
||||||
./configure --enable-sha512
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
sudo ldconfig
|
|
||||||
|
|
||||||
# wolfssl Python installation
|
|
||||||
sudo -H pip install wolfssl
|
|
||||||
|
|
||||||
|
|
||||||
Testing
|
|
||||||
=======
|
|
||||||
|
|
||||||
To run the tox tests in the source code, you'll need ``tox`` and a few other
|
|
||||||
requirements. The source code relies at **WOLFSSL_DIR/wrapper/python/wolfssl**
|
|
||||||
where **WOLFSSL_DIR** is the path of ``wolfssl C``'s source code.
|
|
||||||
|
|
||||||
1. Make sure that the testing requirements are installed:
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
sudo -H pip install -r requirements-testing.txt
|
|
||||||
|
|
||||||
|
|
||||||
2. Run ``make check``:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ make check
|
|
||||||
...
|
|
||||||
_________________________________ summary _________________________________
|
|
||||||
py27: commands succeeded
|
|
||||||
SKIPPED: py34: InterpreterNotFound: python3.4
|
|
||||||
py35: commands succeeded
|
|
||||||
py36: commands succeeded
|
|
||||||
congratulations :)
|
|
||||||
|
|
||||||
Note: the test is performed using multiple versions of python. If you are
|
|
||||||
missing a version the test will be skipped with an **InterpreterNotFound
|
|
||||||
error**.
|
|
17
wrapper/python/wolfssl/Vagrantfile
vendored
17
wrapper/python/wolfssl/Vagrantfile
vendored
@ -1,17 +0,0 @@
|
|||||||
# -*- mode: ruby -*-
|
|
||||||
# vi: set ft=ruby :
|
|
||||||
VAGRANTFILE_API_VERSION = "2"
|
|
||||||
|
|
||||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
||||||
|
|
||||||
config.vm.define "default" do |default|
|
|
||||||
default.vm.box = "ubuntu/trusty64"
|
|
||||||
default.vm.provision "shell", path: ".ubuntu-provisioner.sh"
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.define "centos", autostart: false do |centos|
|
|
||||||
centos.vm.box = "moisesguimaraes/centos72-64"
|
|
||||||
centos.vm.provision "shell", path: ".centos-provisioner.sh"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,61 +0,0 @@
|
|||||||
# Makefile
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
.PHONY : all clean html pdf man
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
PAPER = a4
|
|
||||||
BUILDDIR = _build
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
|
|
||||||
all:
|
|
||||||
@echo "Please use \`make <target>' where <target> is one of"
|
|
||||||
@echo " html to make a single large HTML file"
|
|
||||||
@echo " pdf to make LaTeX files and run them through pdflatex"
|
|
||||||
@echo " man to make manual pages"
|
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(BUILDDIR)/*
|
|
||||||
|
|
||||||
html:
|
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
|
||||||
|
|
||||||
pdf:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
man:
|
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
|
@ -1,21 +0,0 @@
|
|||||||
API Documentation
|
|
||||||
=================
|
|
||||||
|
|
||||||
.. module:: wolfssl
|
|
||||||
|
|
||||||
wrap_socket
|
|
||||||
-----------
|
|
||||||
|
|
||||||
.. autofunction:: wrap_socket
|
|
||||||
|
|
||||||
SSL/TLS Context
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. autoclass:: SSLContext
|
|
||||||
:members:
|
|
||||||
|
|
||||||
SSL/TLS Socket
|
|
||||||
--------------
|
|
||||||
|
|
||||||
.. autoclass:: SSLSocket
|
|
||||||
:members:
|
|
@ -1,300 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# wolfcrypt documentation build configuration file, created by
|
|
||||||
# sphinx-quickstart on Fri Apr 29 16:47:53 2016.
|
|
||||||
#
|
|
||||||
# This file is execfile()d with the current directory set to its
|
|
||||||
# containing dir.
|
|
||||||
#
|
|
||||||
# Note that not all possible configuration values are present in this
|
|
||||||
# autogenerated file.
|
|
||||||
#
|
|
||||||
# All configuration values have a default; values that are commented out
|
|
||||||
# serve to show the default.
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name, redefined-builtin, exec-used
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sphinx_rtd_theme
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
|
||||||
#needs_sphinx = '1.0'
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = [
|
|
||||||
'sphinx.ext.autodoc',
|
|
||||||
'sphinx.ext.doctest',
|
|
||||||
'sphinx.ext.coverage',
|
|
||||||
'sphinx.ext.viewcode',
|
|
||||||
'sphinx.ext.githubpages',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
|
||||||
|
|
||||||
# The suffix(es) of source filenames.
|
|
||||||
# You can specify multiple suffix as a list of string:
|
|
||||||
# source_suffix = ['.rst', '.md']
|
|
||||||
source_suffix = '.rst'
|
|
||||||
|
|
||||||
# The encoding of source files.
|
|
||||||
#source_encoding = 'utf-8-sig'
|
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = u'wolfssl Python'
|
|
||||||
copyright = u'2017, wolfSSL Inc. All rights reserved'
|
|
||||||
author = u'wolfSSL'
|
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
|
||||||
# |version| and |release|, also used in various other places throughout the
|
|
||||||
# built documents.
|
|
||||||
#
|
|
||||||
|
|
||||||
base_dir = os.path.join(os.path.dirname(__file__), os.pardir, "src")
|
|
||||||
about = {}
|
|
||||||
with open(os.path.join(base_dir, "wolfssl", "__about__.py")) as f:
|
|
||||||
exec(f.read(), about)
|
|
||||||
|
|
||||||
version = release = about["__version__"]
|
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
||||||
# for a list of supported languages.
|
|
||||||
#
|
|
||||||
# This is also used if you do content translation via gettext catalogs.
|
|
||||||
# Usually you set "language" from the command line for these cases.
|
|
||||||
language = None
|
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
|
||||||
# non-false value, then it is used:
|
|
||||||
#today = ''
|
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
|
||||||
#today_fmt = '%B %d, %Y'
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
# This patterns also effect to html_static_path and html_extra_path
|
|
||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all
|
|
||||||
# documents.
|
|
||||||
#default_role = None
|
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
|
||||||
#add_function_parentheses = True
|
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description
|
|
||||||
# unit titles (such as .. function::).
|
|
||||||
#add_module_names = True
|
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
|
||||||
# output. They are ignored by default.
|
|
||||||
#show_authors = False
|
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
|
||||||
#modindex_common_prefix = []
|
|
||||||
|
|
||||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
|
||||||
#keep_warnings = False
|
|
||||||
|
|
||||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
|
||||||
todo_include_todos = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ----------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
|
||||||
# further. For a list of options available for each theme, see the
|
|
||||||
# documentation.
|
|
||||||
#html_theme_options = {}
|
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
|
||||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
|
||||||
|
|
||||||
# The name for this set of Sphinx documents.
|
|
||||||
# "<project> v<release> documentation" by default.
|
|
||||||
#html_title = u'%s v%s' % (project, release)
|
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
||||||
#html_short_title = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
|
||||||
# of the sidebar.
|
|
||||||
#html_logo = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to use as a favicon of
|
|
||||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
|
||||||
# pixels large.
|
|
||||||
#html_favicon = None
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
|
||||||
# directly to the root of the documentation.
|
|
||||||
#html_extra_path = []
|
|
||||||
|
|
||||||
# If not None, a 'Last updated on:' timestamp is inserted at every page
|
|
||||||
# bottom, using the given strftime format.
|
|
||||||
# The empty string is equivalent to '%b %d, %Y'.
|
|
||||||
#html_last_updated_fmt = None
|
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
||||||
# typographically correct entities.
|
|
||||||
#html_use_smartypants = True
|
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
#html_sidebars = {}
|
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
|
||||||
# template names.
|
|
||||||
#html_additional_pages = {}
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#html_domain_indices = True
|
|
||||||
|
|
||||||
# If false, no index is generated.
|
|
||||||
#html_use_index = True
|
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter.
|
|
||||||
#html_split_index = False
|
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages.
|
|
||||||
#html_show_sourcelink = True
|
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_sphinx = True
|
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_copyright = True
|
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will
|
|
||||||
# contain a <link> tag referring to it. The value of this option must be the
|
|
||||||
# base URL from which the finished HTML is served.
|
|
||||||
#html_use_opensearch = ''
|
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
|
||||||
#html_file_suffix = None
|
|
||||||
|
|
||||||
# Language to be used for generating the HTML full-text search index.
|
|
||||||
# Sphinx supports the following languages:
|
|
||||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
|
||||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
|
|
||||||
#html_search_language = 'en'
|
|
||||||
|
|
||||||
# A dictionary with options for the search language support, empty by default.
|
|
||||||
# 'ja' uses this config value.
|
|
||||||
# 'zh' user can custom change `jieba` dictionary path.
|
|
||||||
#html_search_options = {'type': 'default'}
|
|
||||||
|
|
||||||
# The name of a javascript file (relative to the configuration directory) that
|
|
||||||
# implements a search results scorer. If empty, the default will be used.
|
|
||||||
#html_search_scorer = 'scorer.js'
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
htmlhelp_basename = 'wolfssl-pydoc'
|
|
||||||
|
|
||||||
# -- Options for LaTeX output ---------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
|
||||||
#'papersize': 'letterpaper',
|
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
|
||||||
#'pointsize': '10pt',
|
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
|
||||||
#'preamble': '',
|
|
||||||
|
|
||||||
# Latex figure (float) alignment
|
|
||||||
#'figure_align': 'htbp',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title,
|
|
||||||
# author, documentclass [howto, manual, or own class]).
|
|
||||||
latex_documents = [
|
|
||||||
(master_doc, 'wolfssl.tex', u'wolfssl Python Documentation',
|
|
||||||
u'wolfSSL', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
|
||||||
# the title page.
|
|
||||||
#latex_logo = None
|
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
||||||
# not chapters.
|
|
||||||
#latex_use_parts = False
|
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
|
||||||
#latex_show_pagerefs = False
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#latex_show_urls = False
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#latex_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#latex_domain_indices = True
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output ---------------------------------------
|
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
|
||||||
# (source start file, name, description, authors, manual section).
|
|
||||||
man_pages = [
|
|
||||||
(master_doc, 'wolfssl', u'wolfssl Python Documentation',
|
|
||||||
[author], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#man_show_urls = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output -------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree into Texinfo files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# dir menu entry, description, category)
|
|
||||||
texinfo_documents = [
|
|
||||||
(master_doc, 'wolfssl', u'wolfssl Python Documentation',
|
|
||||||
author, 'wolfssl', 'One line description of project.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#texinfo_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#texinfo_domain_indices = True
|
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
|
||||||
#texinfo_show_urls = 'footnote'
|
|
||||||
|
|
||||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
|
||||||
#texinfo_no_detailmenu = False
|
|
||||||
|
|
||||||
# Preserves the order of the members, doesn't sorts them alphabetically.
|
|
||||||
autodoc_member_order = 'bysource'
|
|
@ -1,95 +0,0 @@
|
|||||||
Client and Server Examples
|
|
||||||
==========================
|
|
||||||
|
|
||||||
SSL/TLS Client Example
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import wolfssl
|
|
||||||
|
|
||||||
CA_DATA = \
|
|
||||||
"""
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
|
|
||||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
|
||||||
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
|
||||||
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
|
|
||||||
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
|
|
||||||
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
|
|
||||||
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
|
|
||||||
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
|
|
||||||
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
|
|
||||||
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
|
|
||||||
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
|
|
||||||
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
|
|
||||||
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
|
|
||||||
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
|
|
||||||
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
|
|
||||||
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
|
|
||||||
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
|
|
||||||
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
|
|
||||||
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
|
|
||||||
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
|
|
||||||
+OkuE6N36B9K
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
"""
|
|
||||||
|
|
||||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
|
|
||||||
context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2)
|
|
||||||
|
|
||||||
context.verify_mode = wolfssl.CERT_REQUIRED
|
|
||||||
context.load_verify_locations(cadata=CA_DATA)
|
|
||||||
|
|
||||||
secure_socket = context.wrap_socket(bind_socket)
|
|
||||||
|
|
||||||
secure_socket.connect(("www.python.org", 443))
|
|
||||||
|
|
||||||
secure_socket.write(b"GET / HTTP/1.1\n\n")
|
|
||||||
|
|
||||||
print(secure_socket.read())
|
|
||||||
|
|
||||||
secure_socket.close()
|
|
||||||
|
|
||||||
|
|
||||||
SSL/TLS Server Example
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import wolfssl
|
|
||||||
|
|
||||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
|
|
||||||
bind_socket.bind(("", 4433))
|
|
||||||
bind_socket.listen(5)
|
|
||||||
|
|
||||||
context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2, server_side=True)
|
|
||||||
|
|
||||||
context.load_cert_chain("certs/server-cert.pem", "certs/server-key.pem")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
secure_socket = None
|
|
||||||
|
|
||||||
new_socket, from_addr = bind_socket.accept()
|
|
||||||
|
|
||||||
secure_socket = context.wrap_socket(new_socket)
|
|
||||||
|
|
||||||
print("Connection received from", from_addr)
|
|
||||||
|
|
||||||
print("\n", secure_socket.read(), "\n")
|
|
||||||
secure_socket.write(b"I hear you fa shizzle!")
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print()
|
|
||||||
break
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if secure_socket:
|
|
||||||
secure_socket.close()
|
|
||||||
|
|
||||||
bind_socket.close()
|
|
@ -1,8 +0,0 @@
|
|||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
installation
|
|
||||||
usage
|
|
||||||
api
|
|
||||||
examples
|
|
||||||
licensing
|
|
@ -1 +0,0 @@
|
|||||||
.. include:: ../README.rst
|
|
@ -1 +0,0 @@
|
|||||||
.. include:: ../LICENSING.rst
|
|
@ -1,2 +0,0 @@
|
|||||||
Sphinx
|
|
||||||
sphinx_rtd_theme
|
|
@ -1,87 +0,0 @@
|
|||||||
Basic Usage
|
|
||||||
===========
|
|
||||||
|
|
||||||
The SSL/TLS protocol works securing an underlying TCP connection, this module
|
|
||||||
adds the secure layer around the Python standard library
|
|
||||||
`socket <https://docs.python.org/3.6/library/socket.html>`_ module.
|
|
||||||
|
|
||||||
There are three different paths to secure a socket in this module:
|
|
||||||
|
|
||||||
* Using the top level function wolfssl.wrap_socket();
|
|
||||||
* Using the method wrap_socket() from a SSLContext instance;
|
|
||||||
* Creating an SSLSocket object from the scratch.
|
|
||||||
|
|
||||||
Note 1:
|
|
||||||
It is possible to use the same SSLContext for multiple SSLSockets to save
|
|
||||||
time and resources.
|
|
||||||
|
|
||||||
Note 2:
|
|
||||||
Each path provides its own options for fine-tuning the securint parameters.
|
|
||||||
Check them out in the API documentation.
|
|
||||||
|
|
||||||
|
|
||||||
Using the top level function wolfssl.wrap_socket()
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
>>> import socket
|
|
||||||
>>> import wolfssl
|
|
||||||
>>>
|
|
||||||
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
>>>
|
|
||||||
>>> secure_socket = wolfssl.wrap_socket(sock)
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.connect(("www.python.org", 443))
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.write(b"GET / HTTP/1.1\n\n")
|
|
||||||
>>>
|
|
||||||
>>> print(secure_socket.read())
|
|
||||||
b'HTTP/1.1 500 Domain Not Found\r\nServer: Varnish\r\nRetry-After: 0\r\ncontent-type: text/html\r\nCache-Control: private, no-cache\r\nconnection: keep-alive\r\nContent-Length: 179\r\nAccept-Ranges: bytes\r\nDate: Sun, 05 Feb 2017 21:26:48 GMT\r\nVia: 1.1 varnish\r\nConnection: keep-alive\r\n\r\n\n<html>\n<head>\n<title>Fastly error: unknown domain </title>\n</head>\n<body>\nFastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>'
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.close()
|
|
||||||
|
|
||||||
|
|
||||||
Using the method wrap_socket() from a SSLContext instance
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
>>> import socket
|
|
||||||
>>> import wolfssl
|
|
||||||
>>>
|
|
||||||
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
>>>
|
|
||||||
>>> context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2)
|
|
||||||
>>>
|
|
||||||
>>> secure_socket = context.wrap_socket(sock)
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.connect(("www.python.org", 443))
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.write(b"GET / HTTP/1.1\n\n")
|
|
||||||
>>>
|
|
||||||
>>> print(secure_socket.read())
|
|
||||||
b'HTTP/1.1 500 Domain Not Found\r\nServer: Varnish\r\nRetry-After: 0\r\ncontent-type: text/html\r\nCache-Control: private, no-cache\r\nconnection: keep-alive\r\nContent-Length: 179\r\nAccept-Ranges: bytes\r\nDate: Sun, 05 Feb 2017 21:26:48 GMT\r\nVia: 1.1 varnish\r\nConnection: keep-alive\r\n\r\n\n<html>\n<head>\n<title>Fastly error: unknown domain </title>\n</head>\n<body>\nFastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>'
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.close()
|
|
||||||
|
|
||||||
Creating an SSLSocket object from the scratch
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
>>> import socket
|
|
||||||
>>> import wolfssl
|
|
||||||
>>>
|
|
||||||
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
>>>
|
|
||||||
>>> secure_socket = wolfssl.SSLSocket(sock)
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.connect(("www.python.org", 443))
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.write(b"GET / HTTP/1.1\n\n")
|
|
||||||
>>>
|
|
||||||
>>> print(secure_socket.read())
|
|
||||||
b'HTTP/1.1 500 Domain Not Found\r\nServer: Varnish\r\nRetry-After: 0\r\ncontent-type: text/html\r\nCache-Control: private, no-cache\r\nconnection: keep-alive\r\nContent-Length: 179\r\nAccept-Ranges: bytes\r\nDate: Sun, 05 Feb 2017 21:26:48 GMT\r\nVia: 1.1 varnish\r\nConnection: keep-alive\r\n\r\n\n<html>\n<head>\n<title>Fastly error: unknown domain </title>\n</head>\n<body>\nFastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>'
|
|
||||||
>>>
|
|
||||||
>>> secure_socket.close()
|
|
@ -1,142 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# client.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, invalid-name, import-error
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import socket
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
try:
|
|
||||||
import wolfssl
|
|
||||||
except ImportError:
|
|
||||||
print("You must run 'python setup.py install' to use the examples")
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
def build_arg_parser():
|
|
||||||
parser = argparse.ArgumentParser(add_help=False)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-?", "--help", action="help",
|
|
||||||
help="show this help message and exit"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-h", metavar="host", default="127.0.0.1",
|
|
||||||
help="Host to connect to, default 127.0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-p", metavar="port", type=int, default=11111,
|
|
||||||
help="Port to connect on, not 0, default 11111"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-v", metavar="version", type=int, choices=[0, 1, 2, 3], default=3,
|
|
||||||
help="SSL version [0-3], SSLv3(0) - TLS1.2(3)), default 3"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-l", metavar="ciphers", type=str, default="",
|
|
||||||
help="Cipher suite list (: delimited)"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-c", metavar="certificate", default="./certs/client-cert.pem",
|
|
||||||
help="Certificate file, default ./certs/client-cert.pem"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-k", metavar="key", default="./certs/client-key.pem",
|
|
||||||
help="Key file, default ./certs/client-key.pem"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-A", metavar="ca_file", default="./certs/ca-cert.pem",
|
|
||||||
help="Certificate Authority file, default ./certs/ca-cert.pem"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-d", action="store_true",
|
|
||||||
help="Disable client cert check"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-g", action="store_true",
|
|
||||||
help="Send server HTTP GET"
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def get_method(index):
|
|
||||||
return (
|
|
||||||
wolfssl.PROTOCOL_SSLv3,
|
|
||||||
wolfssl.PROTOCOL_TLSv1,
|
|
||||||
wolfssl.PROTOCOL_TLSv1_1,
|
|
||||||
wolfssl.PROTOCOL_TLSv1_2
|
|
||||||
)[index]
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = build_arg_parser().parse_args()
|
|
||||||
|
|
||||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
|
|
||||||
context = wolfssl.SSLContext(get_method(args.v))
|
|
||||||
|
|
||||||
context.load_cert_chain(args.c, args.k)
|
|
||||||
|
|
||||||
if args.d:
|
|
||||||
context.verify_mode = wolfssl.CERT_NONE
|
|
||||||
else:
|
|
||||||
context.verify_mode = wolfssl.CERT_REQUIRED
|
|
||||||
context.load_verify_locations(args.A)
|
|
||||||
|
|
||||||
if args.l:
|
|
||||||
context.set_ciphers(args.l)
|
|
||||||
|
|
||||||
try:
|
|
||||||
secure_socket = context.wrap_socket(bind_socket)
|
|
||||||
|
|
||||||
secure_socket.connect((args.h, args.p))
|
|
||||||
|
|
||||||
if args.g:
|
|
||||||
secure_socket.write(b"GET / HTTP/1.1\n\n")
|
|
||||||
else:
|
|
||||||
secure_socket.write(b"hello wolfssl")
|
|
||||||
|
|
||||||
print("\n", secure_socket.read(), "\n")
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print()
|
|
||||||
|
|
||||||
finally:
|
|
||||||
secure_socket.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,154 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# server.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, invalid-name, import-error
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import socket
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
try:
|
|
||||||
import wolfssl
|
|
||||||
except ImportError:
|
|
||||||
print("You must run 'python setup.py install' to use the examples")
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
def build_arg_parser():
|
|
||||||
parser = argparse.ArgumentParser(add_help=False)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-?", "--help", action="help",
|
|
||||||
help="show this help message and exit"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-p", metavar="port", type=int, default=11111,
|
|
||||||
help="Port to listen on, not 0, default 11111"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-v", metavar="version", type=int, choices=[0, 1, 2, 3], default=3,
|
|
||||||
help="SSL version [0-3], SSLv3(0) - TLS1.2(3)), default 3"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-l", metavar="ciphers", type=str, default="",
|
|
||||||
help="Cipher suite list (: delimited)"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-c", metavar="certificate", default="./certs/server-cert.pem",
|
|
||||||
help="Certificate file, default ./certs/server-cert.pem"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-k", metavar="key", default="./certs/server-key.pem",
|
|
||||||
help="Key file, default ./certs/server-key.pem"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-A", metavar="ca_file", default="./certs/client-cert.pem",
|
|
||||||
help="Certificate Authority file, default ./certs/client-cert.pem"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-d", action="store_true",
|
|
||||||
help="Disable client cert check"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-b", action="store_true",
|
|
||||||
help="Bind to any interface instead of localhost only"
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-i", action="store_true",
|
|
||||||
help="Loop indefinitely (allow repeated connections)"
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def get_method(index):
|
|
||||||
return (
|
|
||||||
wolfssl.PROTOCOL_SSLv3,
|
|
||||||
wolfssl.PROTOCOL_TLSv1,
|
|
||||||
wolfssl.PROTOCOL_TLSv1_1,
|
|
||||||
wolfssl.PROTOCOL_TLSv1_2
|
|
||||||
)[index]
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = build_arg_parser().parse_args()
|
|
||||||
|
|
||||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
|
||||||
bind_socket.bind(("" if args.b else "localhost", args.p))
|
|
||||||
bind_socket.listen(5)
|
|
||||||
|
|
||||||
print("Server listening on port", bind_socket.getsockname()[1])
|
|
||||||
|
|
||||||
context = wolfssl.SSLContext(get_method(args.v), server_side=True)
|
|
||||||
|
|
||||||
context.load_cert_chain(args.c, args.k)
|
|
||||||
|
|
||||||
if args.d:
|
|
||||||
context.verify_mode = wolfssl.CERT_NONE
|
|
||||||
else:
|
|
||||||
context.verify_mode = wolfssl.CERT_REQUIRED
|
|
||||||
context.load_verify_locations(args.A)
|
|
||||||
|
|
||||||
if args.l:
|
|
||||||
context.set_ciphers(args.l)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
secure_socket = None
|
|
||||||
|
|
||||||
new_socket, from_addr = bind_socket.accept()
|
|
||||||
|
|
||||||
secure_socket = context.wrap_socket(new_socket)
|
|
||||||
|
|
||||||
print("Connection received from", from_addr)
|
|
||||||
|
|
||||||
print("\n", secure_socket.read(), "\n")
|
|
||||||
secure_socket.write(b"I hear you fa shizzle!")
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print()
|
|
||||||
break
|
|
||||||
|
|
||||||
finally:
|
|
||||||
if secure_socket:
|
|
||||||
secure_socket.close()
|
|
||||||
|
|
||||||
if not args.i:
|
|
||||||
break
|
|
||||||
|
|
||||||
bind_socket.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,38 +0,0 @@
|
|||||||
# vim:ft=automake
|
|
||||||
# included from Top Level Makefile.am
|
|
||||||
# All paths should be given relative to the root
|
|
||||||
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/.gitignore
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/api.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/conf.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/examples.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/index.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/installation.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/Makefile
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/licensing.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/requirements.txt
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/docs/usage.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/examples/client.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/examples/server.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/test/conftest.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/test/test_client.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/test/test_context.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/test/test_methods.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/__about__.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/__init__.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/build_ffi.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/_memory.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/_methods.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/exceptions.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/src/wolfssl/utils.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/LICENSING.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/Makefile
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/MANIFEST.in
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/README.rst
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/requirements-testing.txt
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/setup.py
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/tox.ini
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/Vagrantfile
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/.centos-provisioner.sh
|
|
||||||
EXTRA_DIST+= wrapper/python/wolfssl/.ubuntu-provisioner.sh
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
pytest
|
|
||||||
cffi
|
|
||||||
tox
|
|
@ -1,89 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# setup.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# Python 2.7 Standard Library
|
|
||||||
|
|
||||||
# pylint: disable=import-error, wrong-import-position
|
|
||||||
|
|
||||||
from __future__ import absolute_import
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import shutil
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
sys.path.insert(0, 'src')
|
|
||||||
from wolfssl.__about__ import METADATA
|
|
||||||
|
|
||||||
os.chdir(os.path.dirname(sys.argv[0]) or ".")
|
|
||||||
|
|
||||||
LONG_DESCRIPTION = open("README.rst", "rt").read().replace(
|
|
||||||
".. include:: LICENSING.rst\n",
|
|
||||||
open("LICENSING.rst", "rt").read()
|
|
||||||
)
|
|
||||||
|
|
||||||
INFO = dict(
|
|
||||||
metadata={k[2:-2]: METADATA[k] for k in METADATA},
|
|
||||||
contents={
|
|
||||||
"long_description" : LONG_DESCRIPTION,
|
|
||||||
"package_data" : {"": ["*.txt"]},
|
|
||||||
"packages" : find_packages("src"),
|
|
||||||
"package_dir" : {"": "src"},
|
|
||||||
"cffi_modules" : ["./src/wolfssl/build_ffi.py:ffi"],
|
|
||||||
},
|
|
||||||
requirements={
|
|
||||||
"setup_requires" : ["cffi>=1.6.0"],
|
|
||||||
"install_requires" : ["cffi>=1.6.0"],
|
|
||||||
},
|
|
||||||
scripts={},
|
|
||||||
plugins={},
|
|
||||||
tests={},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def update_certs():
|
|
||||||
c_certs_dir = "../../../certs"
|
|
||||||
py_certs_dir = "certs"
|
|
||||||
certs = [
|
|
||||||
"ca-cert.pem",
|
|
||||||
"client-cert.pem",
|
|
||||||
"client-key.pem",
|
|
||||||
"server-cert.pem",
|
|
||||||
"server-key.pem",
|
|
||||||
"external/ca-digicert-ev.pem"
|
|
||||||
]
|
|
||||||
|
|
||||||
if os.path.isdir(c_certs_dir):
|
|
||||||
if not os.path.isdir(py_certs_dir):
|
|
||||||
os.makedirs(py_certs_dir)
|
|
||||||
|
|
||||||
for cert in certs:
|
|
||||||
shutil.copy(os.path.join(c_certs_dir, cert), py_certs_dir)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
update_certs()
|
|
||||||
|
|
||||||
KWARGS = {k:v for dct in INFO.values() for (k, v) in dct.items()}
|
|
||||||
setup(**KWARGS)
|
|
@ -1,51 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# __about__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring
|
|
||||||
|
|
||||||
METADATA = dict(
|
|
||||||
__name__="wolfssl",
|
|
||||||
__version__="0.1.0",
|
|
||||||
__license__="GPLv2 or Commercial License",
|
|
||||||
__author__="wolfSSL Inc.",
|
|
||||||
__author_email__="info@wolfssl.com",
|
|
||||||
__url__="https://wolfssl.github.io/wolfssl-py",
|
|
||||||
__description__= \
|
|
||||||
u"A Python module that encapsulates wolfSSL's C SSL/TLS library.",
|
|
||||||
__keywords__="security, cryptography, ssl, embedded, embedded ssl",
|
|
||||||
__classifiers__=[
|
|
||||||
u"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
|
|
||||||
u"License :: Other/Proprietary License",
|
|
||||||
u"Operating System :: OS Independent",
|
|
||||||
u"Programming Language :: Python :: 2.7",
|
|
||||||
u"Programming Language :: Python :: 3.5",
|
|
||||||
u"Topic :: Security",
|
|
||||||
u"Topic :: Security :: Cryptography",
|
|
||||||
u"Topic :: Software Development"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
globals().update(METADATA)
|
|
||||||
|
|
||||||
__all__ = list(METADATA.keys())
|
|
@ -1,679 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# __init__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import errno
|
|
||||||
from socket import (
|
|
||||||
socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_TYPE, error as socket_error
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
from wolfssl._ffi import ffi as _ffi
|
|
||||||
from wolfssl._ffi import lib as _lib
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
from wolfssl.utils import t2b
|
|
||||||
|
|
||||||
from wolfssl.exceptions import (
|
|
||||||
CertificateError, SSLError, SSLEOFError, SSLSyscallError,
|
|
||||||
SSLWantReadError, SSLWantWriteError, SSLZeroReturnError
|
|
||||||
)
|
|
||||||
|
|
||||||
from wolfssl._methods import (
|
|
||||||
PROTOCOL_SSLv23, PROTOCOL_SSLv3, PROTOCOL_TLSv1,
|
|
||||||
PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2, PROTOCOL_TLS,
|
|
||||||
WolfSSLMethod as _WolfSSLMethod
|
|
||||||
)
|
|
||||||
|
|
||||||
from wolfssl.__about__ import (
|
|
||||||
__all__, METADATA
|
|
||||||
)
|
|
||||||
|
|
||||||
globals().update(METADATA)
|
|
||||||
|
|
||||||
CERT_NONE = 0
|
|
||||||
CERT_REQUIRED = 1
|
|
||||||
|
|
||||||
_VERIFY_MODE_LIST = [CERT_NONE, CERT_REQUIRED]
|
|
||||||
|
|
||||||
_SSL_SUCCESS = 1
|
|
||||||
_SSL_FILETYPE_PEM = 1
|
|
||||||
_SSL_ERROR_WANT_READ = 2
|
|
||||||
|
|
||||||
_WOLFSSL_ECC_SECP160K1 = 15
|
|
||||||
_WOLFSSL_ECC_SECP160R1 = 16
|
|
||||||
_WOLFSSL_ECC_SECP160R2 = 17
|
|
||||||
_WOLFSSL_ECC_SECP192K1 = 18
|
|
||||||
_WOLFSSL_ECC_SECP192R1 = 19
|
|
||||||
_WOLFSSL_ECC_SECP224K1 = 20
|
|
||||||
_WOLFSSL_ECC_SECP224R1 = 21
|
|
||||||
_WOLFSSL_ECC_SECP256K1 = 22
|
|
||||||
_WOLFSSL_ECC_SECP256R1 = 23
|
|
||||||
_WOLFSSL_ECC_SECP384R1 = 24
|
|
||||||
_WOLFSSL_ECC_SECP521R1 = 25
|
|
||||||
_WOLFSSL_ECC_BRAINPOOLP256R1 = 26
|
|
||||||
_WOLFSSL_ECC_BRAINPOOLP384R1 = 27
|
|
||||||
_WOLFSSL_ECC_BRAINPOOLP512R1 = 28
|
|
||||||
|
|
||||||
_SUPPORTED_CURVES = [
|
|
||||||
_WOLFSSL_ECC_SECP160K1, _WOLFSSL_ECC_SECP160R1, _WOLFSSL_ECC_SECP160R2,
|
|
||||||
_WOLFSSL_ECC_SECP192K1, _WOLFSSL_ECC_SECP192R1, _WOLFSSL_ECC_SECP224K1,
|
|
||||||
_WOLFSSL_ECC_SECP224R1, _WOLFSSL_ECC_SECP256K1, _WOLFSSL_ECC_SECP256R1,
|
|
||||||
_WOLFSSL_ECC_SECP384R1, _WOLFSSL_ECC_SECP521R1,
|
|
||||||
_WOLFSSL_ECC_BRAINPOOLP256R1, _WOLFSSL_ECC_BRAINPOOLP384R1,
|
|
||||||
_WOLFSSL_ECC_BRAINPOOLP512R1
|
|
||||||
]
|
|
||||||
|
|
||||||
_PY3 = sys.version_info[0] == 3
|
|
||||||
|
|
||||||
class SSLContext(object):
|
|
||||||
"""
|
|
||||||
An SSLContext holds various SSL-related configuration options and
|
|
||||||
data, such as certificates and possibly a private key.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, protocol, server_side=False):
|
|
||||||
method = _WolfSSLMethod(protocol, server_side)
|
|
||||||
|
|
||||||
self.protocol = protocol
|
|
||||||
self._side = server_side
|
|
||||||
self._verify_mode = None
|
|
||||||
self.native_object = _lib.wolfSSL_CTX_new(method.native_object)
|
|
||||||
|
|
||||||
# wolfSSL_CTX_new() takes ownership of the method.
|
|
||||||
# the method is freed later inside wolfSSL_CTX_free()
|
|
||||||
# or if wolfSSL_CTX_new() failed to allocate the context object.
|
|
||||||
method.native_object = _ffi.NULL
|
|
||||||
|
|
||||||
if self.native_object == _ffi.NULL:
|
|
||||||
raise MemoryError("Unnable to allocate context object")
|
|
||||||
|
|
||||||
# verify_mode initialization needs a valid native_object.
|
|
||||||
self.verify_mode = CERT_NONE
|
|
||||||
|
|
||||||
if not server_side:
|
|
||||||
for curve in _SUPPORTED_CURVES:
|
|
||||||
ret = _lib.wolfSSL_CTX_UseSupportedCurve(self.native_object,
|
|
||||||
curve)
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("unnable to set curve (%d)" % curve)
|
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if getattr(self, 'native_object', _ffi.NULL) != _ffi.NULL:
|
|
||||||
_lib.wolfSSL_CTX_free(self.native_object)
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def verify_mode(self):
|
|
||||||
"""
|
|
||||||
Whether to try to verify other peers’ certificates and how to behave
|
|
||||||
if verification fails. This attribute must be one of CERT_NONE,
|
|
||||||
CERT_OPTIONAL or CERT_REQUIRED.
|
|
||||||
"""
|
|
||||||
return self._verify_mode
|
|
||||||
|
|
||||||
|
|
||||||
@verify_mode.setter
|
|
||||||
def verify_mode(self, value):
|
|
||||||
if value not in _VERIFY_MODE_LIST:
|
|
||||||
raise ValueError("verify_mode must be one of CERT_NONE, "
|
|
||||||
"CERT_OPTIONAL or CERT_REQUIRED")
|
|
||||||
|
|
||||||
if value != self._verify_mode:
|
|
||||||
self._verify_mode = value
|
|
||||||
_lib.wolfSSL_CTX_set_verify(self.native_object,
|
|
||||||
self._verify_mode,
|
|
||||||
_ffi.NULL)
|
|
||||||
|
|
||||||
|
|
||||||
def wrap_socket(self, sock, server_side=False,
|
|
||||||
do_handshake_on_connect=True,
|
|
||||||
suppress_ragged_eofs=True):
|
|
||||||
"""
|
|
||||||
Wrap an existing Python socket sock and return an SSLSocket object.
|
|
||||||
sock must be a SOCK_STREAM socket; other socket types are unsupported.
|
|
||||||
|
|
||||||
The returned SSL socket is tied to the context, its settings and
|
|
||||||
certificates. The parameters server_side, do_handshake_on_connect and
|
|
||||||
suppress_ragged_eofs have the same meaning as in the top-level
|
|
||||||
wrap_socket() function.
|
|
||||||
"""
|
|
||||||
return SSLSocket(sock=sock, server_side=server_side,
|
|
||||||
do_handshake_on_connect=do_handshake_on_connect,
|
|
||||||
suppress_ragged_eofs=suppress_ragged_eofs,
|
|
||||||
_context=self)
|
|
||||||
|
|
||||||
|
|
||||||
def set_ciphers(self, ciphers):
|
|
||||||
"""
|
|
||||||
Set the available ciphers for sockets created with this context. It
|
|
||||||
should be a string in the wolfSSL cipher list format. If no cipher can
|
|
||||||
be selected (because compile-time options or other configuration forbids
|
|
||||||
use of all the specified ciphers), an SSLError will be raised.
|
|
||||||
"""
|
|
||||||
ret = _lib.wolfSSL_CTX_set_cipher_list(self.native_object, t2b(ciphers))
|
|
||||||
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("Unnable to set cipher list")
|
|
||||||
|
|
||||||
|
|
||||||
def load_cert_chain(self, certfile, keyfile=None, password=None):
|
|
||||||
"""
|
|
||||||
Load a private key and the corresponding certificate. The certfile
|
|
||||||
string must be the path to a single file in PEM format containing
|
|
||||||
the certificate as well as any number of CA certificates needed to
|
|
||||||
establish the certificate's authenticity.
|
|
||||||
|
|
||||||
The keyfile string, if present, must point to a file containing the
|
|
||||||
private key in.
|
|
||||||
|
|
||||||
The password parameter is not supported yet.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if password is not None:
|
|
||||||
raise NotImplementedError("password callback support not "
|
|
||||||
"implemented yet")
|
|
||||||
|
|
||||||
if certfile is not None:
|
|
||||||
ret = _lib.wolfSSL_CTX_use_certificate_chain_file(
|
|
||||||
self.native_object, t2b(certfile))
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("Unnable to load certificate chain. Err %d"% ret)
|
|
||||||
else:
|
|
||||||
raise TypeError("certfile should be a valid filesystem path")
|
|
||||||
|
|
||||||
if keyfile is not None:
|
|
||||||
ret = _lib.wolfSSL_CTX_use_PrivateKey_file(
|
|
||||||
self.native_object, t2b(keyfile), _SSL_FILETYPE_PEM)
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("Unnable to load private key. Err %d" % ret)
|
|
||||||
|
|
||||||
|
|
||||||
def load_verify_locations(self, cafile=None, capath=None, cadata=None):
|
|
||||||
"""
|
|
||||||
Load a set of "certification authority" (CA) certificates used to
|
|
||||||
validate other peers' certificates when verify_mode is other than
|
|
||||||
CERT_NONE. At least one of cafile or capath must be specified.
|
|
||||||
|
|
||||||
The cafile string, if present, is the path to a file of concatenated
|
|
||||||
CA certificates in PEM format.
|
|
||||||
|
|
||||||
The capath string, if present, is the path to a directory containing
|
|
||||||
several CA certificates in PEM format.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if cafile is None and capath is None and cadata is None:
|
|
||||||
raise TypeError("cafile, capath and cadata cannot be all omitted")
|
|
||||||
|
|
||||||
if cafile is not None or capath is not None:
|
|
||||||
ret = _lib.wolfSSL_CTX_load_verify_locations(
|
|
||||||
self.native_object,
|
|
||||||
t2b(cafile) if cafile else _ffi.NULL,
|
|
||||||
t2b(capath) if capath else _ffi.NULL)
|
|
||||||
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("Unnable to load verify locations. Err %d" % ret)
|
|
||||||
|
|
||||||
if cadata is not None:
|
|
||||||
ret = _lib.wolfSSL_CTX_load_verify_buffer(
|
|
||||||
self.native_object, t2b(cadata), len(cadata), _SSL_FILETYPE_PEM)
|
|
||||||
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("Unnable to load verify locations. Err %d" % ret)
|
|
||||||
|
|
||||||
|
|
||||||
class SSLSocket(socket):
|
|
||||||
"""
|
|
||||||
This class implements a subtype of socket.socket that wraps the
|
|
||||||
underlying OS socket in an SSL/TLS connection, providing secure
|
|
||||||
read and write methods over that channel.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, sock=None, keyfile=None, certfile=None,
|
|
||||||
server_side=False, cert_reqs=CERT_NONE,
|
|
||||||
ssl_version=PROTOCOL_TLS, ca_certs=None,
|
|
||||||
do_handshake_on_connect=True, family=AF_INET,
|
|
||||||
sock_type=SOCK_STREAM, proto=0, fileno=None,
|
|
||||||
suppress_ragged_eofs=True, ciphers=None,
|
|
||||||
_context=None):
|
|
||||||
|
|
||||||
# set options
|
|
||||||
self.do_handshake_on_connect = do_handshake_on_connect
|
|
||||||
self.suppress_ragged_eofs = suppress_ragged_eofs
|
|
||||||
self.server_side = server_side
|
|
||||||
|
|
||||||
# set context
|
|
||||||
if _context:
|
|
||||||
self._context = _context
|
|
||||||
else:
|
|
||||||
if server_side and not certfile:
|
|
||||||
raise ValueError("certfile must be specified for server-side "
|
|
||||||
"operations")
|
|
||||||
|
|
||||||
if keyfile and not certfile:
|
|
||||||
raise ValueError("certfile must be specified")
|
|
||||||
|
|
||||||
if certfile and not keyfile:
|
|
||||||
keyfile = certfile
|
|
||||||
|
|
||||||
self._context = SSLContext(ssl_version, server_side)
|
|
||||||
self._context.verify_mode = cert_reqs
|
|
||||||
if ca_certs:
|
|
||||||
self._context.load_verify_locations(ca_certs)
|
|
||||||
if certfile:
|
|
||||||
self._context.load_cert_chain(certfile, keyfile)
|
|
||||||
if ciphers:
|
|
||||||
self._context.set_ciphers(ciphers)
|
|
||||||
|
|
||||||
self.keyfile = keyfile
|
|
||||||
self.certfile = certfile
|
|
||||||
self.cert_reqs = cert_reqs
|
|
||||||
self.ssl_version = ssl_version
|
|
||||||
self.ca_certs = ca_certs
|
|
||||||
self.ciphers = ciphers
|
|
||||||
|
|
||||||
# preparing socket
|
|
||||||
if sock is not None:
|
|
||||||
# Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
|
|
||||||
# mixed in.
|
|
||||||
if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
|
|
||||||
raise NotImplementedError("only stream sockets are supported")
|
|
||||||
|
|
||||||
if _PY3:
|
|
||||||
socket.__init__(self,
|
|
||||||
family=sock.family,
|
|
||||||
type=sock.type,
|
|
||||||
proto=sock.proto,
|
|
||||||
fileno=sock.fileno())
|
|
||||||
else:
|
|
||||||
socket.__init__(self, _sock=sock._sock)
|
|
||||||
|
|
||||||
self.settimeout(sock.gettimeout())
|
|
||||||
|
|
||||||
if _PY3:
|
|
||||||
sock.detach()
|
|
||||||
|
|
||||||
elif fileno is not None:
|
|
||||||
socket.__init__(self, fileno=fileno)
|
|
||||||
|
|
||||||
else:
|
|
||||||
socket.__init__(self, family=family, type=sock_type,
|
|
||||||
proto=proto)
|
|
||||||
|
|
||||||
# see if we are connected
|
|
||||||
try:
|
|
||||||
self.getpeername()
|
|
||||||
except socket_error as exception:
|
|
||||||
if exception.errno != errno.ENOTCONN:
|
|
||||||
raise
|
|
||||||
connected = False
|
|
||||||
else:
|
|
||||||
connected = True
|
|
||||||
|
|
||||||
self._closed = False
|
|
||||||
self._connected = connected
|
|
||||||
|
|
||||||
# create the SSL object
|
|
||||||
self.native_object = _lib.wolfSSL_new(self.context.native_object)
|
|
||||||
if self.native_object == _ffi.NULL:
|
|
||||||
raise MemoryError("Unnable to allocate ssl object")
|
|
||||||
|
|
||||||
ret = _lib.wolfSSL_set_fd(self.native_object, self.fileno())
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
self._release_native_object()
|
|
||||||
raise ValueError("Unnable to set fd to ssl object")
|
|
||||||
|
|
||||||
if connected:
|
|
||||||
try:
|
|
||||||
if do_handshake_on_connect:
|
|
||||||
self.do_handshake()
|
|
||||||
except:
|
|
||||||
self._release_native_object()
|
|
||||||
self.close()
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
self._release_native_object()
|
|
||||||
|
|
||||||
|
|
||||||
def _release_native_object(self):
|
|
||||||
if getattr(self, 'native_object', _ffi.NULL) != _ffi.NULL:
|
|
||||||
_lib.wolfSSL_CTX_free(self.native_object)
|
|
||||||
self.native_object = _ffi.NULL
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def context(self):
|
|
||||||
"""
|
|
||||||
Returns the context used by this object.
|
|
||||||
"""
|
|
||||||
return self._context
|
|
||||||
|
|
||||||
|
|
||||||
def dup(self):
|
|
||||||
raise NotImplementedError("Can't dup() %s instances" %
|
|
||||||
self.__class__.__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def _check_closed(self, call=None):
|
|
||||||
if self.native_object == _ffi.NULL:
|
|
||||||
raise ValueError("%s on closed or unwrapped secure channel" % call)
|
|
||||||
|
|
||||||
def _check_connected(self):
|
|
||||||
if not self._connected:
|
|
||||||
# getpeername() will raise ENOTCONN if the socket is really
|
|
||||||
# not connected; note that we can be connected even without
|
|
||||||
# _connected being set, e.g. if connect() first returned
|
|
||||||
# EAGAIN.
|
|
||||||
self.getpeername()
|
|
||||||
|
|
||||||
|
|
||||||
def write(self, data):
|
|
||||||
"""
|
|
||||||
Write DATA to the underlying secure channel.
|
|
||||||
Returns number of bytes of DATA actually transmitted.
|
|
||||||
"""
|
|
||||||
self._check_closed("write")
|
|
||||||
self._check_connected()
|
|
||||||
|
|
||||||
data = t2b(data)
|
|
||||||
|
|
||||||
return _lib.wolfSSL_write(self.native_object, data, len(data))
|
|
||||||
|
|
||||||
|
|
||||||
def send(self, data, flags=0):
|
|
||||||
if flags != 0:
|
|
||||||
raise NotImplementedError("non-zero flags not allowed in calls to "
|
|
||||||
"send() on %s" % self.__class__)
|
|
||||||
|
|
||||||
return self.write(data)
|
|
||||||
|
|
||||||
|
|
||||||
def sendall(self, data, flags=0):
|
|
||||||
if flags != 0:
|
|
||||||
raise NotImplementedError("non-zero flags not allowed in calls to "
|
|
||||||
"sendall() on %s" % self.__class__)
|
|
||||||
|
|
||||||
length = len(data)
|
|
||||||
sent = 0
|
|
||||||
|
|
||||||
while sent < length:
|
|
||||||
sent += self.write(data[sent:])
|
|
||||||
|
|
||||||
return sent
|
|
||||||
|
|
||||||
|
|
||||||
def sendto(self, data, flags_or_addr, addr=None):
|
|
||||||
# Ensure programs don't send unencrypted data trying to use this method
|
|
||||||
raise NotImplementedError("sendto not allowed on instances "
|
|
||||||
"of %s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def sendmsg(self, *args, **kwargs):
|
|
||||||
# Ensure programs don't send unencrypted data trying to use this method
|
|
||||||
raise NotImplementedError("sendmsg not allowed on instances "
|
|
||||||
"of %s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def sendfile(self, file, offset=0, count=None):
|
|
||||||
# Ensure programs don't send unencrypted files trying to use this method
|
|
||||||
raise NotImplementedError("sendfile not allowed on instances "
|
|
||||||
"of %s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def read(self, length=1024, buffer=None):
|
|
||||||
"""
|
|
||||||
Read up to LENGTH bytes and return them.
|
|
||||||
Return zero-length string on EOF.
|
|
||||||
"""
|
|
||||||
self._check_closed("read")
|
|
||||||
self._check_connected()
|
|
||||||
|
|
||||||
if buffer is not None:
|
|
||||||
raise ValueError("buffer not allowed in calls to "
|
|
||||||
"read() on %s" % self.__class__)
|
|
||||||
|
|
||||||
data = _ffi.new('byte[%d]' % length)
|
|
||||||
length = _lib.wolfSSL_read(self.native_object, data, length)
|
|
||||||
|
|
||||||
if length < 0:
|
|
||||||
err = _lib.wolfSSL_get_error(self.native_object, 0)
|
|
||||||
if err == _SSL_ERROR_WANT_READ:
|
|
||||||
raise SSLWantReadError()
|
|
||||||
else:
|
|
||||||
raise SSLError("wolfSSL_read error (%d)" % err)
|
|
||||||
|
|
||||||
return _ffi.buffer(data, length)[:] if length > 0 else b''
|
|
||||||
|
|
||||||
|
|
||||||
def recv(self, length=1024, flags=0):
|
|
||||||
if flags != 0:
|
|
||||||
raise NotImplementedError("non-zero flags not allowed in calls to "
|
|
||||||
"recv() on %s" % self.__class__)
|
|
||||||
|
|
||||||
return self.read(self, length)
|
|
||||||
|
|
||||||
|
|
||||||
def recv_into(self, buffer, nbytes=None, flags=0):
|
|
||||||
raise NotImplementedError("recv_into not allowed on instances "
|
|
||||||
"of %s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def recvfrom(self, length=1024, flags=0):
|
|
||||||
# Ensure programs don't receive encrypted data trying to use this method
|
|
||||||
raise NotImplementedError("recvfrom not allowed on instances "
|
|
||||||
"of %s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def recvfrom_into(self, buffer, nbytes=None, flags=0):
|
|
||||||
# Ensure programs don't receive encrypted data trying to use this method
|
|
||||||
raise NotImplementedError("recvfrom_into not allowed on instances "
|
|
||||||
"of %s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def recvmsg(self, *args, **kwargs):
|
|
||||||
raise NotImplementedError("recvmsg not allowed on instances of %s" %
|
|
||||||
self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def recvmsg_into(self, *args, **kwargs):
|
|
||||||
raise NotImplementedError("recvmsg_into not allowed on instances of "
|
|
||||||
"%s" % self.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
def shutdown(self, how):
|
|
||||||
if self.native_object != _ffi.NULL:
|
|
||||||
_lib.wolfSSL_shutdown(self.native_object)
|
|
||||||
self._release_native_object()
|
|
||||||
socket.shutdown(self, how)
|
|
||||||
|
|
||||||
|
|
||||||
def unwrap(self):
|
|
||||||
"""
|
|
||||||
Unwraps the underlying OS socket from the SSL/TLS connection.
|
|
||||||
Returns the wrapped OS socket.
|
|
||||||
"""
|
|
||||||
if self.native_object != _ffi.NULL:
|
|
||||||
_lib.wolfSSL_set_fd(self.native_object, -1)
|
|
||||||
|
|
||||||
sock = socket(family=self.family,
|
|
||||||
sock_type=self.type,
|
|
||||||
proto=self.proto,
|
|
||||||
fileno=self.fileno())
|
|
||||||
sock.settimeout(self.gettimeout())
|
|
||||||
self.detach()
|
|
||||||
|
|
||||||
return sock
|
|
||||||
|
|
||||||
|
|
||||||
def do_handshake(self, block=False):
|
|
||||||
"""
|
|
||||||
Perform a TLS/SSL handshake.
|
|
||||||
"""
|
|
||||||
self._check_closed("do_handshake")
|
|
||||||
self._check_connected()
|
|
||||||
|
|
||||||
ret = _lib.wolfSSL_negotiate(self.native_object)
|
|
||||||
if ret != _SSL_SUCCESS:
|
|
||||||
raise SSLError("do_handshake failed with error %d" % ret)
|
|
||||||
|
|
||||||
|
|
||||||
def _real_connect(self, addr, connect_ex):
|
|
||||||
if self.server_side:
|
|
||||||
raise ValueError("can't connect in server-side mode")
|
|
||||||
|
|
||||||
# Here we assume that the socket is client-side, and not
|
|
||||||
# connected at the time of the call. We connect it, then wrap it.
|
|
||||||
if self._connected:
|
|
||||||
raise ValueError("attempt to connect already-connected SSLSocket!")
|
|
||||||
|
|
||||||
if connect_ex:
|
|
||||||
err = socket.connect_ex(self, addr)
|
|
||||||
else:
|
|
||||||
err = 0
|
|
||||||
socket.connect(self, addr)
|
|
||||||
|
|
||||||
if err == 0:
|
|
||||||
self._connected = True
|
|
||||||
if self.do_handshake_on_connect:
|
|
||||||
self.do_handshake()
|
|
||||||
|
|
||||||
return err
|
|
||||||
|
|
||||||
|
|
||||||
def connect(self, addr):
|
|
||||||
"""
|
|
||||||
Connects to remote ADDR, and then wraps the connection in a secure
|
|
||||||
channel.
|
|
||||||
"""
|
|
||||||
self._real_connect(addr, False)
|
|
||||||
|
|
||||||
|
|
||||||
def connect_ex(self, addr):
|
|
||||||
"""
|
|
||||||
Connects to remote ADDR, and then wraps the connection in a secure
|
|
||||||
channel.
|
|
||||||
"""
|
|
||||||
return self._real_connect(addr, True)
|
|
||||||
|
|
||||||
|
|
||||||
def accept(self):
|
|
||||||
"""
|
|
||||||
Accepts a new connection from a remote client, and returns a tuple
|
|
||||||
containing that new connection wrapped with a server-side secure
|
|
||||||
channel, and the address of the remote client.
|
|
||||||
"""
|
|
||||||
if not self.server_side:
|
|
||||||
raise ValueError("can't accept in client-side mode")
|
|
||||||
|
|
||||||
newsock, addr = socket.accept(self)
|
|
||||||
newsock = self.context.wrap_socket(
|
|
||||||
newsock,
|
|
||||||
do_handshake_on_connect=self.do_handshake_on_connect,
|
|
||||||
suppress_ragged_eofs=self.suppress_ragged_eofs,
|
|
||||||
server_side=True)
|
|
||||||
|
|
||||||
return newsock, addr
|
|
||||||
|
|
||||||
|
|
||||||
def wrap_socket(sock, keyfile=None, certfile=None, server_side=False,
|
|
||||||
cert_reqs=CERT_NONE, ssl_version=PROTOCOL_TLS, ca_certs=None,
|
|
||||||
do_handshake_on_connect=True, suppress_ragged_eofs=True,
|
|
||||||
ciphers=None):
|
|
||||||
"""
|
|
||||||
Takes an instance sock of socket.socket, and returns an instance of
|
|
||||||
wolfssl.SSLSocket, wrapping the underlying socket in an SSL context.
|
|
||||||
|
|
||||||
The sock parameter must be a SOCK_STREAM socket; other socket types are
|
|
||||||
unsupported.
|
|
||||||
|
|
||||||
The keyfile and certfile parameters specify optional files with proper
|
|
||||||
key and the certificates used to identify the local side of the connection.
|
|
||||||
|
|
||||||
The parameter server_side is a boolean which identifies whether server-side
|
|
||||||
or client-side behavior is desired from this socket.
|
|
||||||
|
|
||||||
The parameter cert_reqs specifies whether a certificate is required from the
|
|
||||||
other side of the connection, and whether it will be validated if provided.
|
|
||||||
It must be one of the three values:
|
|
||||||
|
|
||||||
* CERT_NONE (certificates ignored)
|
|
||||||
* CERT_OPTIONAL (not required, but validated if provided)
|
|
||||||
* CERT_REQUIRED (required and validated)
|
|
||||||
|
|
||||||
If the value of this parameter is not CERT_NONE, then the ca_certs parameter
|
|
||||||
must point to a file of CA certificates.
|
|
||||||
|
|
||||||
The ca_certs file contains a set of concatenated “certification authority”
|
|
||||||
certificates, which are used to validate certificates passed from the other
|
|
||||||
end of the connection.
|
|
||||||
|
|
||||||
The parameter ssl_version specifies which version of the SSL protocol to
|
|
||||||
use. Typically, the server chooses a particular protocol version, and the
|
|
||||||
client must adapt to the server’s choice. Most of the versions are not
|
|
||||||
interoperable with the other versions. If not specified, the default is
|
|
||||||
PROTOCOL_TLS; it provides the most compatibility with other versions.
|
|
||||||
|
|
||||||
Here’s a table showing which versions in a client (down the side) can
|
|
||||||
connect to which versions in a server (along the top):
|
|
||||||
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
| client \\ server | SSLv3 | TLS | TLSv1 | TLSv1.1 | TLSv1.2 |
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
| SSLv3 | yes | yes | no | no | no |
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
| TLS (SSLv23) | yes | yes | yes | yes | yes |
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
| TLSv1 | no | yes | yes | no | no |
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
| TLSv1.1 | no | yes | no | yes | no |
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
| TLSv1.2 | no | yes | no | no | yes |
|
|
||||||
+------------------+-------+-----+-------+---------+---------+
|
|
||||||
|
|
||||||
Note:
|
|
||||||
Which connections succeed will vary depending on the versions of the ssl
|
|
||||||
providers on both sides of the communication.
|
|
||||||
|
|
||||||
The ciphers parameter sets the available ciphers for this SSL object. It
|
|
||||||
should be a string in the wolfSSL cipher list format.
|
|
||||||
|
|
||||||
The parameter do_handshake_on_connect specifies whether to do the SSL
|
|
||||||
handshake automatically after doing a socket.connect(), or whether the
|
|
||||||
application program will call it explicitly, by invoking the
|
|
||||||
SSLSocket.do_handshake() method. Calling SSLSocket.do_handshake() explicitly
|
|
||||||
gives the program control over the blocking behavior of the socket I/O
|
|
||||||
involved in the handshake.
|
|
||||||
|
|
||||||
The parameter suppress_ragged_eofs is not supported yet.
|
|
||||||
"""
|
|
||||||
return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
|
|
||||||
server_side=server_side, cert_reqs=cert_reqs,
|
|
||||||
ssl_version=ssl_version, ca_certs=ca_certs,
|
|
||||||
do_handshake_on_connect=do_handshake_on_connect,
|
|
||||||
suppress_ragged_eofs=suppress_ragged_eofs,
|
|
||||||
ciphers=ciphers)
|
|
@ -1,36 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# _memory.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring
|
|
||||||
|
|
||||||
try:
|
|
||||||
from wolfssl._ffi import ffi as _ffi
|
|
||||||
from wolfssl._ffi import lib as _lib
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
_DYNAMIC_TYPE_METHOD = 11
|
|
||||||
|
|
||||||
def _native_free(native_object, dynamic_type):
|
|
||||||
_lib.wolfSSL_Free(native_object, _ffi.NULL, dynamic_type)
|
|
@ -1,84 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# _methods.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, invalid-name
|
|
||||||
|
|
||||||
try:
|
|
||||||
from wolfssl._ffi import ffi as _ffi
|
|
||||||
from wolfssl._ffi import lib as _lib
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
from wolfssl._memory import (
|
|
||||||
_native_free, _DYNAMIC_TYPE_METHOD
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
PROTOCOL_SSLv23 = 1
|
|
||||||
PROTOCOL_SSLv3 = 2
|
|
||||||
PROTOCOL_TLS = 1
|
|
||||||
PROTOCOL_TLSv1 = 3
|
|
||||||
PROTOCOL_TLSv1_1 = 4
|
|
||||||
PROTOCOL_TLSv1_2 = 5
|
|
||||||
|
|
||||||
_PROTOCOL_LIST = [PROTOCOL_SSLv23, PROTOCOL_SSLv3, PROTOCOL_TLS,
|
|
||||||
PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2]
|
|
||||||
|
|
||||||
|
|
||||||
class WolfSSLMethod(object):
|
|
||||||
"""
|
|
||||||
An SSLMethod holds SSL-related configuration options such as
|
|
||||||
protocol version and communication side.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, protocol, server_side):
|
|
||||||
if protocol not in _PROTOCOL_LIST:
|
|
||||||
raise ValueError("this protocol is not supported")
|
|
||||||
|
|
||||||
elif protocol == PROTOCOL_SSLv3:
|
|
||||||
raise ValueError("this protocol is not supported")
|
|
||||||
|
|
||||||
elif protocol == PROTOCOL_TLSv1:
|
|
||||||
raise ValueError("this protocol is not supported")
|
|
||||||
|
|
||||||
elif protocol == PROTOCOL_TLSv1_1:
|
|
||||||
raise ValueError("this protocol is not supported")
|
|
||||||
|
|
||||||
elif protocol == PROTOCOL_TLSv1_2:
|
|
||||||
self.native_object = \
|
|
||||||
_lib.wolfTLSv1_2_server_method() if server_side else \
|
|
||||||
_lib.wolfTLSv1_2_client_method()
|
|
||||||
|
|
||||||
elif protocol in [PROTOCOL_SSLv23, PROTOCOL_TLS]:
|
|
||||||
self.native_object = \
|
|
||||||
_lib.wolfSSLv23_server_method() if server_side else \
|
|
||||||
_lib.wolfSSLv23_client_method()
|
|
||||||
|
|
||||||
if self.native_object == _ffi.NULL:
|
|
||||||
raise MemoryError("Unnable to allocate method object")
|
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if getattr(self, 'native_object', _ffi.NULL) != _ffi.NULL:
|
|
||||||
_native_free(self.native_object, _DYNAMIC_TYPE_METHOD)
|
|
@ -1,81 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# build_ffi.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, invalid-name
|
|
||||||
|
|
||||||
from cffi import FFI
|
|
||||||
|
|
||||||
ffi = FFI()
|
|
||||||
|
|
||||||
ffi.set_source(
|
|
||||||
"wolfssl._ffi",
|
|
||||||
"""
|
|
||||||
#include <wolfssl/options.h>
|
|
||||||
#include <wolfssl/ssl.h>
|
|
||||||
|
|
||||||
void wolfSSL_Free(void *ptr, void* heap, int type);
|
|
||||||
""",
|
|
||||||
include_dirs=["/usr/local/include"],
|
|
||||||
library_dirs=["/usr/local/lib"],
|
|
||||||
libraries=["wolfssl"],
|
|
||||||
)
|
|
||||||
|
|
||||||
ffi.cdef(
|
|
||||||
"""
|
|
||||||
typedef unsigned char byte;
|
|
||||||
typedef unsigned int word32;
|
|
||||||
|
|
||||||
void wolfSSL_Free(void*, void*, int);
|
|
||||||
|
|
||||||
void* wolfSSLv23_server_method(void);
|
|
||||||
void* wolfSSLv23_client_method(void);
|
|
||||||
void* wolfTLSv1_2_server_method(void);
|
|
||||||
void* wolfTLSv1_2_client_method(void);
|
|
||||||
|
|
||||||
void* wolfSSL_CTX_new(void*);
|
|
||||||
void wolfSSL_CTX_free(void*);
|
|
||||||
|
|
||||||
void wolfSSL_CTX_set_verify(void*, int, void*);
|
|
||||||
int wolfSSL_CTX_set_cipher_list(void*, const char*);
|
|
||||||
int wolfSSL_CTX_use_PrivateKey_file(void*, const char*, int);
|
|
||||||
int wolfSSL_CTX_load_verify_locations(void*, const char*, const char*);
|
|
||||||
int wolfSSL_CTX_load_verify_buffer(void*, const unsigned char*, long, int);
|
|
||||||
int wolfSSL_CTX_use_certificate_chain_file(void*, const char *);
|
|
||||||
int wolfSSL_CTX_UseSupportedCurve(void*, short);
|
|
||||||
|
|
||||||
|
|
||||||
void* wolfSSL_new(void*);
|
|
||||||
void wolfSSL_free(void*);
|
|
||||||
|
|
||||||
int wolfSSL_set_fd(void*, int);
|
|
||||||
int wolfSSL_get_error(void*, int);
|
|
||||||
int wolfSSL_negotiate(void*);
|
|
||||||
int wolfSSL_write(void*, const void*, int);
|
|
||||||
int wolfSSL_read(void*, void*, int);
|
|
||||||
int wolfSSL_shutdown(void*);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
ffi.compile(verbose=1)
|
|
@ -1,90 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# exceptions.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring
|
|
||||||
|
|
||||||
from socket import error as socket_error
|
|
||||||
|
|
||||||
|
|
||||||
class SSLError(socket_error):
|
|
||||||
"""
|
|
||||||
Raised to signal an error from the wolfSSL's SSL/TLS library. This signifies
|
|
||||||
some problem in the higher-level encryption and authentication layer that's
|
|
||||||
superimposed on the underlying network connection. This error is a subtype
|
|
||||||
of socket.error, which in turn is a subtype of IOError. The error code and
|
|
||||||
message of SSLError instances are provided by the wolfSSL library.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SSLZeroReturnError(SSLError):
|
|
||||||
"""
|
|
||||||
A subclass of SSLError raised when trying to read or write and the SSL
|
|
||||||
connection has been closed cleanly. Note that this doesn't mean that the
|
|
||||||
underlying transport (read TCP) has been closed.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SSLWantReadError(SSLError):
|
|
||||||
"""
|
|
||||||
A subclass of SSLError raised by a non-blocking SSL socket when trying to
|
|
||||||
read or write data, but more data needs to be received on the underlying TCP
|
|
||||||
transport before the request can be fulfilled.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SSLWantWriteError(SSLError):
|
|
||||||
"""
|
|
||||||
A subclass of SSLError raised by a non-blocking SSL socket when trying to
|
|
||||||
read or write data, but more data needs to be sent on the underlying TCP
|
|
||||||
transport before the request can be fulfilled.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SSLSyscallError(SSLError):
|
|
||||||
"""
|
|
||||||
A subclass of SSLError raised when a system error was encountered while
|
|
||||||
trying to fulfill an operation on a SSL socket. Unfortunately, there is no
|
|
||||||
easy way to inspect the original errno number.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SSLEOFError(SSLError):
|
|
||||||
"""
|
|
||||||
A subclass of SSLError raised when the SSL connection has been terminated
|
|
||||||
abruptly. Generally, you shouldn't try to reuse the underlying transport
|
|
||||||
when this error is encountered.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class CertificateError(ValueError):
|
|
||||||
"""
|
|
||||||
Raised to signal an error with a certificate (such as mismatching hostname).
|
|
||||||
Certificate errors detected by wolfSSL, though, raise an SSLError.
|
|
||||||
"""
|
|
||||||
pass
|
|
@ -1,40 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# utils.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, unused-import, undefined-variable
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from binascii import hexlify as b2h, unhexlify as h2b
|
|
||||||
|
|
||||||
_PY3 = sys.version_info[0] == 3
|
|
||||||
_TEXT_TYPE = str if _PY3 else unicode
|
|
||||||
_BINARY_TYPE = bytes if _PY3 else str
|
|
||||||
|
|
||||||
def t2b(string):
|
|
||||||
"""
|
|
||||||
Converts text to bynary.
|
|
||||||
"""
|
|
||||||
if isinstance(string, _BINARY_TYPE):
|
|
||||||
return string
|
|
||||||
return _TEXT_TYPE(string).encode("utf-8")
|
|
@ -1,48 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# conftest.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, redefined-outer-name
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import ssl
|
|
||||||
import wolfssl
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def tcp_socket():
|
|
||||||
import socket
|
|
||||||
from contextlib import closing
|
|
||||||
|
|
||||||
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
|
||||||
yield sock
|
|
||||||
|
|
||||||
@pytest.fixture(
|
|
||||||
params=[ssl, wolfssl] if sys.version_info.major == 3 else [wolfssl],
|
|
||||||
ids=["ssl", "wolfssl"] if sys.version_info.major == 3 else ["wolfssl"])
|
|
||||||
def ssl_provider(request):
|
|
||||||
return request.param
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def ssl_context(ssl_provider):
|
|
||||||
return ssl_provider.SSLContext(ssl_provider.PROTOCOL_SSLv23)
|
|
@ -1,67 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# test_client.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, invalid-name, import-error
|
|
||||||
# pylint: disable=redefined-outer-name
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
HOST = "www.python.org"
|
|
||||||
PORT = 443
|
|
||||||
CA_CERTS = "certs/ca-digicert-ev.pem"
|
|
||||||
|
|
||||||
@pytest.fixture(
|
|
||||||
params=["wrap_socket", "wrap_socket_with_ca",
|
|
||||||
"wrap_socket_from_context", "ssl_socket"])
|
|
||||||
def secure_socket(request, ssl_provider, tcp_socket):
|
|
||||||
sock = None
|
|
||||||
|
|
||||||
if request.param == "wrap_socket":
|
|
||||||
sock = ssl_provider.wrap_socket(tcp_socket)
|
|
||||||
|
|
||||||
elif request.param == "wrap_socket_with_ca":
|
|
||||||
sock = ssl_provider.wrap_socket(
|
|
||||||
tcp_socket, cert_reqs=ssl_provider.CERT_REQUIRED, ca_certs=CA_CERTS)
|
|
||||||
|
|
||||||
elif request.param == "wrap_socket_from_context":
|
|
||||||
ctx = ssl_provider.SSLContext(ssl_provider.PROTOCOL_TLSv1_2)
|
|
||||||
|
|
||||||
ctx.verify_mode = ssl_provider.CERT_REQUIRED
|
|
||||||
ctx.load_verify_locations(CA_CERTS)
|
|
||||||
|
|
||||||
sock = ctx.wrap_socket(tcp_socket)
|
|
||||||
|
|
||||||
elif request.param == "ssl_socket":
|
|
||||||
sock = ssl_provider.SSLSocket(
|
|
||||||
tcp_socket, cert_reqs=ssl_provider.CERT_REQUIRED, ca_certs=CA_CERTS)
|
|
||||||
|
|
||||||
if sock:
|
|
||||||
yield sock
|
|
||||||
sock.close()
|
|
||||||
|
|
||||||
def test_secure_connection(secure_socket):
|
|
||||||
secure_socket.connect((HOST, PORT))
|
|
||||||
|
|
||||||
secure_socket.write(b"GET / HTTP/1.1\n\n")
|
|
||||||
assert secure_socket.read(4) == b"HTTP"
|
|
@ -1,67 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# test_context.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, invalid-name, import-error
|
|
||||||
# pylint: disable=redefined-outer-name
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
with open("certs/ca-cert.pem") as ca:
|
|
||||||
_CADATA = ca.read()
|
|
||||||
|
|
||||||
def test_context_creation(ssl_context):
|
|
||||||
assert ssl_context != None
|
|
||||||
|
|
||||||
def test_verify_mode(ssl_provider, ssl_context):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
ssl_context.verify_mode = -1
|
|
||||||
|
|
||||||
assert ssl_context.verify_mode == ssl_provider.CERT_NONE
|
|
||||||
|
|
||||||
ssl_context.verify_mode = ssl_provider.CERT_REQUIRED
|
|
||||||
assert ssl_context.verify_mode == ssl_provider.CERT_REQUIRED
|
|
||||||
|
|
||||||
def test_set_ciphers(ssl_context):
|
|
||||||
ssl_context.set_ciphers("DHE-RSA-AES256-SHA256")
|
|
||||||
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
ssl_context.set_ciphers("foo")
|
|
||||||
|
|
||||||
def test_load_cert_chain_raises(ssl_context):
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
ssl_context.load_cert_chain(None)
|
|
||||||
|
|
||||||
def test_load_cert_chain(ssl_context):
|
|
||||||
ssl_context.load_cert_chain("certs/client-cert.pem",
|
|
||||||
"certs/client-key.pem")
|
|
||||||
|
|
||||||
def test_load_verify_locations_raises(ssl_context):
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
ssl_context.load_verify_locations(None)
|
|
||||||
|
|
||||||
def test_load_verify_locations_with_cafile(ssl_context):
|
|
||||||
ssl_context.load_verify_locations(cafile="certs/ca-cert.pem")
|
|
||||||
|
|
||||||
def test_load_verify_locations_with_cadata(ssl_provider, ssl_context):
|
|
||||||
ssl_context.load_verify_locations(cadata=_CADATA)
|
|
@ -1,60 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# test_methods.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006-2021 wolfSSL Inc.
|
|
||||||
#
|
|
||||||
# This file is part of wolfSSL.
|
|
||||||
#
|
|
||||||
# wolfSSL 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wolfSSL 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-1335, USA
|
|
||||||
#/
|
|
||||||
#/
|
|
||||||
|
|
||||||
# pylint: disable=missing-docstring, redefined-outer-name, import-error
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from wolfssl._methods import (WolfSSLMethod, PROTOCOL_SSLv3, PROTOCOL_SSLv23,
|
|
||||||
PROTOCOL_TLS, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1,
|
|
||||||
PROTOCOL_TLSv1_2)
|
|
||||||
from wolfssl._ffi import ffi as _ffi
|
|
||||||
|
|
||||||
@pytest.fixture(
|
|
||||||
params=[-1, PROTOCOL_SSLv3, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1],
|
|
||||||
ids=["invalid", "SSLv3", "TLSv1", "TLSv1_1"])
|
|
||||||
def unsupported_method(request):
|
|
||||||
yield request.param
|
|
||||||
|
|
||||||
@pytest.fixture(
|
|
||||||
params=[PROTOCOL_SSLv23, PROTOCOL_TLS, PROTOCOL_TLSv1_2],
|
|
||||||
ids=["SSLv23", "TLS", "TLSv1_2"])
|
|
||||||
def supported_method(request):
|
|
||||||
yield request.param
|
|
||||||
|
|
||||||
|
|
||||||
def test_unsupported_method(unsupported_method):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
WolfSSLMethod(unsupported_method, False)
|
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
WolfSSLMethod(unsupported_method, True)
|
|
||||||
|
|
||||||
def test_supported_method(supported_method):
|
|
||||||
client = WolfSSLMethod(supported_method, False)
|
|
||||||
server = WolfSSLMethod(supported_method, True)
|
|
||||||
|
|
||||||
assert isinstance(client, WolfSSLMethod)
|
|
||||||
assert isinstance(server, WolfSSLMethod)
|
|
||||||
assert client.native_object != _ffi.NULL
|
|
||||||
assert server.native_object != _ffi.NULL
|
|
@ -1,7 +0,0 @@
|
|||||||
[tox]
|
|
||||||
envlist=py27,py34,py35,py36
|
|
||||||
skip_missing_interpreters=true
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
deps=-rrequirements-testing.txt
|
|
||||||
commands=py.test test/ {posargs}
|
|
Reference in New Issue
Block a user