mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 03:07:29 +02:00
Remove the Python wrappers from wolfSSL source
The wolfCrypt and wolfSSL Python wrappers are maintained in the wolfCrypt-py and wolfSSL-py trees respectively. The duplicates in this tree are stale. The content has been checked and any important changes have been ported over to their respective trees.
This commit is contained in:
@ -2,6 +2,4 @@
|
||||
# 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
|
||||
|
@ -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