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
|
||||
# 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
|
||||
|
||||
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